Compare commits

...

37 Commits

Author SHA1 Message Date
Ben V. Brown
0e7e304f4e Patch to handle UTF slightly better.
Not perfect but working for now
2017-09-17 12:21:25 +10:00
Ben V. Brown
0aae546dc9 Update strings to be more uniform
closes #89
Also includes the new Italian translation
closes #88
2017-09-17 11:50:44 +10:00
Maelremrem
2bf06caa09 Added french language (#84)
* Added french language

Add the french translation for all the strings <maelremrem>
2017-09-09 23:13:21 +10:00
thanks4opensource
c1ab76260f Python version of Logo Editor/TS100 Logo Editor (#78) 2017-08-29 20:06:00 +10:00
Ben V. Brown
6cc2dfe238 Fix jumping into cooldown accidentally
Final commit for 1.17
2017-08-26 16:54:09 +10:00
Ben V. Brown
0ae32506e9 Fix the blinking display on cooling screen 2017-08-23 13:15:01 +10:00
Ben V. Brown
bb174c7639 Fix #62 2017-08-13 22:47:01 +10:00
Ben V. Brown
1d602bd9a1 Add display inversion for cooling 2017-08-13 12:48:16 +10:00
Ben V. Brown
a9da6d511b Add German #60 2017-08-13 12:39:04 +10:00
Ben V. Brown
4f0e3560b9 Fix #62 2017-08-13 12:36:00 +10:00
Ben V. Brown
8b112e7f7d Add little C and F logos & arrow for boost 2017-08-11 17:04:09 +10:00
Ben V. Brown
37f36b960c Merge branch 'master' of https://github.com/Ralim/ts100 2017-08-11 16:31:10 +10:00
Ben V. Brown
c5c1171112 Fix font erroring char. Add accel lockout for autostart.
Helps for the following issues:
#51
#38
2017-08-11 16:31:04 +10:00
Ben V. Brown
109b3436e6 Update README.md 2017-08-11 14:51:51 +10:00
Ben V. Brown
088b98c131 Update README.md 2017-08-11 14:25:04 +10:00
Ben V. Brown
ea1b0e2ae3 Link in latin extended font 2017-08-11 14:20:41 +10:00
Ben V. Brown
92ee55ebd5 Annotate font table 2017-08-11 14:06:26 +10:00
Ben V. Brown
f0e1498e92 Fix screen blink
Fixes #56
2017-08-10 17:34:01 +10:00
Ángel González
6c56f98928 Translated strings to es_ES (#55)
Thanks to @Aglezabad
2017-08-09 19:52:01 +10:00
Ben V. Brown
d2efa0dc05 Add early exit to settings menu
Adds pressing both buttons to exit settings menu. #53
2017-08-09 15:14:06 +10:00
Ben V. Brown
f3c1fafccc Documentation cleanup 2017-08-09 10:34:24 +10:00
Ben V. Brown
220775ed1f Merge branch 'master' of https://github.com/Ralim/ts100 2017-08-09 10:28:54 +10:00
Ben V. Brown
c3d672c0dd Adding in lower sleep times
#46
Adding in smaller times for sleep
2017-08-09 10:28:51 +10:00
Alex Wigen
57c0bf4dc1 Fix typo in Linux flasher script (#49) 2017-08-09 10:13:18 +10:00
Ben V. Brown
9969c66520 Add ability to start into sleep 2017-08-09 10:07:34 +10:00
Ben V. Brown
8cc7d452ce Adjust key timings & patch flashing
Patch to help improve #52
Fixes #50
2017-08-09 10:01:38 +10:00
Ben V. Brown
c0f2a4991a Add blinking temp
Adds blinking temp
#39
2017-08-08 21:00:41 +10:00
Ben V. Brown
1822cece90 Massively better font
Moved to a newer font.
First stage of improving screen
2017-08-08 18:09:07 +10:00
Ben V. Brown
42e6818114 Convert IMU to IRQ for rotation
This moves the rotation detection to use the IRQ2 line. Fixes #44
2017-08-08 16:38:21 +10:00
Ben V. Brown
a10947cdac Moving more text into strings.c/.h 2017-08-08 10:49:15 +10:00
Ben V. Brown
48040acbcc Add autostart
Adds autostart option.
Only works on first power up, so if the settings wrong you can still easily change it 😄
Fixes #43
2017-08-06 22:21:57 +10:00
Ben V. Brown
f1aa331168 Converted menu over to strings.h mostly 2017-08-06 20:41:34 +10:00
Ben V. Brown
de0059bd08 Moving strings (more) 2017-08-05 22:51:54 +10:00
Alex Wigen
f8f20bee5c Add flash script for Linux (#40)
* Add flash script for Linux

* Add credit and link to github
2017-08-05 20:34:43 +10:00
Ben V. Brown
90599a8ae6 Retune PID, improve response rate slightly. (But slightly more oscillation) 2017-08-02 21:38:42 +10:00
Ben V. Brown
b0264be3c5 Better button auto-repeat 2017-07-30 21:25:27 +10:00
Ben V. Brown
4fb7a70e3c More explicit left handed checks 2017-07-30 20:02:58 +10:00
23 changed files with 1506 additions and 508 deletions

79
History.md Normal file
View File

@@ -0,0 +1,79 @@
# Version Changes
V1.17
* Added blinking cooldown display
* Allowed smaller sleep timeout values
* New font!
* Automatic startup option
V1.16
* Added automatic rotation support
* Added power display graph
V1.15
* Added support for a custom bootup logo to be programmed via the DFU bootloader.
V1.14
* Changed input voltage cutoff to be based on cell count rather than voltage.
V1.13
* Swapped buttons for menu to prevent accidentally changing first menu item
* Added auto key repeat.
V1.12
* Increases sensitivity options to be 1*9 with 0 off state
* Fixes issue where going from COOL *> soldering can leave screen off.
V1.11
* Boost mode
* Change sensitivity options to be 1*8
V1.10
* Adds help text to settings
* Improves settings for the display update rate
V1.09
* Adds display modes, for slowing down or simplifying the display
V1.08
* Fix settings menu not showing flip display
V1.07
* Adds shutdown time to automatically shutdown the iron after inactivity
V1.06
* Changes H and C when the iron is heating to the minidso chevron like images
V1.05
* Adds ability to calibrate the input voltage measurement
V1.04
* Increased accuracy of the temperature control
* Improved PID response slightly
* Allows temperature offset calibration
* Nicer idle screen
V1.03
* Improved Button handling
* Ability to set motion sensitivity
* DC voltmeter page shows input voltage
V1.02
* Adds hold both buttons on IDLE to access the therometer mode.
* Changes the exit soldering mode to be holding both buttons (Like original firmware).

View File

@@ -28,8 +28,9 @@ Please calibrate your irons voltage reading when you are using a lithium battery
# Upgrading your ts100 iron
This is completely safe, if it goes wrong just put the .hex file from the official website onto the unit and your back to the old firmware. Downloads for the hex files to flash are available on the [releases page.](https://github.com/Ralim/ts100/releases)
Officially the bootloader on the iron only works under windows. However, users have reported that it does work under Mac, and can be made to work under Linux *sometimes*. Details over on the [wiki page](https://github.com/Ralim/ts100/wiki/Upgrading*Firmware).
This is completely safe, if it goes wrong just put the .hex file from the official website onto the unit and your back to the old firmware. Downloads for the hex files to flash are available on the [releases page.](https://github.com/Ralim/ts100/releases) The file you want is called *ts100.hex* unless you want the translations, they are ts100_*language short name*.hex.
Officially the bootloader on the iron only works under windows. However, users have reported that it does work under Mac, and can be made to work under Linux *sometimes*. Details over on the [wiki page](https://github.com/Ralim/ts100/wiki/Upgrading-Firmware).
1. Hold the button closest to the tip, and plug in the USB to the computer.
2. The unit will appear as a USB drive.
@@ -47,19 +48,7 @@ There is a complete device flash backup included in this repository. (Note this
This firmware uses a different method of updating the bootup image.
This removes the need for emulating a USB drive on the iron just to allow for a bootup image to be setup.
At this point in time you will need a windows machine to make the required .hex file for you image.
*If you know what your doing, this program will run fine through mono on other systems*
1. On the [releases page](https://github.com/Ralim/ts100/releases) you will need to download the latest copy of the GUI Tool (*TS100.Logo.Editor.exe*).
2. Launch the TS100 Logo Editor, you will need to have .NET 4.0 installed on your machine
3. On the tool open the source image that you would like to use as your bootup screen. A resolution of 96x16 is ideal, but you can fill or stretch your logo to fit
4. Colour images are okay, the software will convert them to B&W for you.
5. You can also invert colours if you would prefer.
6. Save the created file as a *.hex* file somewhere.
7. Connect your iron to your computer in DFU mode (same as you would to upgrade firmware).
8. Drag the created .hex file for the logo onto the iron to update it with the file.
9. You should be good to go.
10. The image will stay through future updates, but if it ever wont I will put a warning in the update download on the releases page.
There are further instructions on the [wiki](https://github.com/Ralim/ts100/wiki/Logo-Editor). Instructions are kept on the wiki so that users can update the information if they find extra helpful information.
## New Menu System
@@ -152,77 +141,6 @@ The boost temperature is set in the settings menu.
This software is provided as-is, so I cannot provide any commercial support for the firmware. However you are more than welcome to distribute links to the firmware, or provide irons with this software on them.
Please do not re-host the files, but rather link to this page, so that there are not old versions of the firmware hanging around. If this firmware does make you money, it would be nice to recieve a donation, however I dont enforce this.
## Version Changes
V1.16
* Added automatic rotation support
* Added power display graph
V1.15
* Added support for a custom bootup logo to be programmed via the DFU bootloader.
V1.14
* Changed input voltage cutoff to be based on cell count rather than voltage.
V1.13
* Swapped buttons for menu to prevent accidentally changing first menu item
* Added auto key repeat.
V1.12
* Increases sensitivity options to be 1*9 with 0 off state
* Fixes issue where going from COOL *> soldering can leave screen off.
V1.11
* Boost mode
* Change sensitivity options to be 1*8
V1.10
* Adds help text to settings
* Improves settings for the display update rate
V1.09
* Adds display modes, for slowing down or simplifying the display
V1.08
* Fix settings menu not showing flip display
V1.07
* Adds shutdown time to automatically shutdown the iron after inactivity
V1.06
* Changes H and C when the iron is heating to the minidso chevron like images
V1.05
* Adds ability to calibrate the input voltage measurement
V1.04
* Increased accuracy of the temperature control
* Improved PID response slightly
* Allows temperature offset calibration
* Nicer idle screen
V1.03
* Improved Button handling
* Ability to set motion sensitivity
* DC voltmeter page shows input voltage
V1.02
* Adds hold both buttons on IDLE to access the therometer mode.
* Changes the exit soldering mode to be holding both buttons (Like original firmware).
## Thanks
If you love this firmware and want to continue my caffine addiction, you can do so here (or email me for other options) : https://paypal.me/RalimTek

130
flash/flash_ts100_linux.sh Executable file
View File

@@ -0,0 +1,130 @@
#!/bin/bash
# TS100 Flasher for Linux by Alex Wigen (https://github.com/awigen)
DIR_TMP="/tmp/ts100"
function usage() {
echo
echo "#################"
echo "# TS100 Flasher #"
echo "#################"
echo
echo " Usage: $0 <HEXFILE>"
echo
echo "This script has been tested to work on Fedora."
echo "If you experience any issues please open a ticket at:"
echo "https://github.com/Ralim/ts100/issues/new"
echo
}
GAUTOMOUNT=0
function disable_gautomount {
GSETTINGS=`which gsettings`
if [ $? -ne 0 ]; then
return 1
fi
gsettings get org.gnome.desktop.media-handling automount | grep true > /dev/null
if [ $? -eq 0 ]; then
GAUTOMOUNT=1
gsettings set org.gnome.desktop.media-handling automount false
fi
}
function enable_gautomount {
if [ "$GAUTOMOUNT" -ne 0 ]; then
gsettings set org.gnome.desktop.media-handling automount true
fi
}
function is_attached {
output=`lsblk -b --raw --output NAME,MODEL | grep 'DFU\\\\x20Disk'`
if [ $? -ne 0 ]; then
return 1
fi
DEVICE=`echo $output | awk '{print "/dev/"$1}'`
}
instructions="not printed"
function wait_for_ts100 {
is_attached
while [ $? -ne 0 ]; do
if [ "$instructions" = "not printed" ]; then
echo
echo "#####################################################"
echo "# Waiting for TS100 config disk device to appear #"
echo "# #"
echo "# Connect the soldering iron with a USB cable while #"
echo "# holding the button closest to the tip pressed #"
echo "#####################################################"
echo
instructions="printed"
fi
sleep 0.1
is_attached
done
}
function mount_ts100 {
mkdir -p "$DIR_TMP"
sudo mount -t msdos -o uid=$UID "$DEVICE" "$DIR_TMP"
if [ $? -ne 0 ]; then
echo "Failed to mount $DEVICE on $DIR_TMP"
exit 1
fi
}
function umount_ts100 {
mountpoint "$DIR_TMP" > /dev/null && sudo umount "$DIR_TMP"
if [ $? -ne 0 ]; then
echo "Failed to unmount $DIR_TMP"
exit 1
fi
rmdir "$DIR_TMP"
}
function cleanup {
enable_gautomount
if [ -d "$DIR_TMP" ]; then
umount_ts100
fi
}
trap cleanup EXIT
if [ "$#" -ne 1 ]; then
echo "Please provide a HEX file to flash"
usage
exit 1
fi
if [ ! -f "$1" ]; then
echo "'$1' is not a regular file, please provide a HEX file to flash"
usage
exit 1
fi
if [ `head -c1 "$1"` != ":" ] || [ `tail -n1 "$1" | head -c1` != ":" ]; then
echo "'$1' doesn't look like a valid HEX file. Please provide a HEX file to flash"
usage
exit 1
fi
disable_gautomount
wait_for_ts100
echo "Found TS100 config disk device on $DEVICE"
mount_ts100
echo "Mounted config disk drive, flashing..."
cp -v "$1" "$DIR_TMP/ts100.hex"
sync
echo "Waiting for TS100 to flash"
sleep 5
echo "Remounting config disk drive"
umount_ts100
wait_for_ts100
mount_ts100
echo "Flash result: "
ls "$DIR_TMP"/ts100*

View File

@@ -0,0 +1,251 @@
#!/usr/bin/env python
VERSION_STRING = '0.01'
import os
import sys
try:
import PIL, PIL.Image, PIL.ImageOps
except ImportError,error:
raise ImportError, "%s: %s requres Python Imaging Library (PIL). " \
"Install with `pip` or OS-specific package " \
"management tool." \
% (error, sys.argv[0])
LCD_WIDTH = 96
LCD_HEIGHT = 16
LCD_NUM_BYTES = LCD_WIDTH * LCD_HEIGHT / 8
LCD_PADDED_SIZE = 1024
INTELHEX_DATA_RECORD = 0x00
INTELHEX_END_OF_FILE_RECORD = 0x01
INTELHEX_EXTENDED_LINEAR_ADDRESS_RECORD = 0x04
INTELHEX_BYTES_PER_LINE = 16
INTELHEX_MINIMUM_SIZE = 4096
def split16(word):
'''return high and low byte of 16-bit word value as tuple'''
return ((word >> 8) & 0xff, word & 0xff)
def intel_hex_line(file, record_type, offset, data):
'''write a line of data in Intel hex format'''
# length, address offset, record type
record_length = len(data)
file.write(':%02X%04X%02X' % (record_length, offset, record_type))
# data
map(lambda byte: file.write("%02X" % byte), data)
# compute and write checksum (with DOS line ending for compatibility/safety)
file.write( "%02X\r\n"
% ( ( ( sum(data, # sum data ...
record_length # ... and other ...
+ sum(split16(offset)) # ... fields ...
+ record_type) # ... on line
& 0xff) # low 8 bits
^ 0xff) # two's ...
+ 1)) # ... complement
def intel_hex(file, bytes, start_address = 0x0):
'''write block of data in Intel hex format'''
if len(bytes) % INTELHEX_BYTES_PER_LINE != 0:
raise ValueError, \
"Program error: Size of LCD data is not evenly divisible by %s" \
% INTELHEX_BYTES_PER_LINE
address_lo = start_address & 0xffff
address_hi = (start_address >> 16) & 0xffff
intel_hex_line(file,
INTELHEX_EXTENDED_LINEAR_ADDRESS_RECORD,
0,
split16(address_hi))
size_written = 0
while size_written < INTELHEX_MINIMUM_SIZE:
offset = address_lo
for line_start in range(0, len(bytes), INTELHEX_BYTES_PER_LINE):
intel_hex_line(file,
INTELHEX_DATA_RECORD,
offset,
bytes[line_start:line_start+INTELHEX_BYTES_PER_LINE])
size_written += INTELHEX_BYTES_PER_LINE
if size_written >= INTELHEX_MINIMUM_SIZE:
break
offset += INTELHEX_BYTES_PER_LINE
intel_hex_line(file, INTELHEX_END_OF_FILE_RECORD, 0, ())
def img2hex(input_filename,
output_file,
preview_filename=None,
threshold=128,
dither=False,
negative=False):
'''
Convert 'input_filename' image file into Intel hex format with data
formatted for display on TS100 LCD and file object.
Input image is converted from color or grayscale to black-and-white,
and resized to fit TS100 LCD screen as necessary.
Optionally write resized/thresholded/black-and-white preview image
to file specified by name.
Optional `threshold' argument 8 bit value; grayscale pixels greater than
this become 1 (white) in output, less than become 0 (black).
Unless optional `dither', in which case PIL grayscale-to-black/white
dithering algorithm used.
Optional `negative' inverts black/white regardless of input image type
or other options.
'''
try:
image = PIL.Image.open(input_filename)
except BaseException,error:
raise IOError, \
"error reading image file \"%s\": %s" % (input_filename, error)
# convert to luminance
# do even if already black/white because PIL can't invert 1-bit so
# can't just pass thru in case --negative flag
# also resizing works better in luminance than black/white
# also no information loss converting black/white to grayscale
if image.mode != 'L':
image = image.convert('L')
if image.size != (LCD_WIDTH, LCD_HEIGHT):
image = image.resize((LCD_WIDTH, LCD_HEIGHT), PIL.Image.BICUBIC)
if negative:
image = PIL.ImageOps.invert(image)
threshold = 255 - threshold # have to invert threshold
if dither:
image = image.convert('1')
else:
image = image.point(lambda pixel: 0 if pixel < threshold else 1, '1')
if preview_filename: image.save(preview_filename)
''' DEBUG
for row in range(LCD_HEIGHT):
for column in range(LCD_WIDTH):
if image.getpixel((column, row)): sys.stderr.write('1')
else: sys.stderr.write('0')
sys.stderr.write('\n')
'''
# pad to this size (also will be repeated in output Intel hex file)
data = [0] * LCD_PADDED_SIZE
# magic/undocumented/required header in endian-reverse byte order
data[0] = 0x55
data[1] = 0xAA
data[2] = 0x0D
data[3] = 0xF0
# convert to TS100 LCD format
for ndx in range(LCD_WIDTH * 16 / 8):
bottom_half_offset = 0 if ndx < LCD_WIDTH else 8
byte = 0
for y in range(8):
if image.getpixel((ndx % LCD_WIDTH, y + bottom_half_offset)):
byte |= 1 << y
# store in endian-reversed byte order
data[4 + ndx + (1 if ndx % 2 == 0 else -1)] = byte
intel_hex(output_file, data, 0x0800B800)
def parse_commandline():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
description="Convert image file for display on TS100 LCD "
"at startup")
def zero_to_255(text):
try:
value = int(text)
assert(value >= 0 and value <= 255)
except:
raise argparse.ArgumentTypeError("must be integer from 0 to 255 ")
return value
parser.add_argument('input_filename',
help="input image file")
parser.add_argument('output_filename',
help="output Intel hex file")
parser.add_argument('-p', '--preview',
help="filename of image preview (same data as "
"Intel hex file, as will appear on TS100 LCD)")
parser.add_argument('-n', '--negative',
action='store_true',
help="photo negative: exchange black and white "
"in output")
parser.add_argument('-t', '--threshold',
type=zero_to_255,
default=128,
help="0 to 255: gray (or color converted to gray) "
"above this becomes white, below becomes black; "
"ignored if using --dither")
parser.add_argument('-d', '--dither',
action='store_true',
help="use dithering (speckling) to convert gray or "
"color to black and white")
parser.add_argument('-f', '--force',
action='store_true',
help="force overwriting of existing files")
parser.add_argument('-v', '--version',
action='version',
version="%(prog)s version " + VERSION_STRING,
help="print version info")
return parser.parse_args()
if __name__ == "__main__":
import argparse
args = parse_commandline()
if os.path.exists(args.output_filename) and not args.force:
sys.stderr.write( "Won't overwrite existing file \"%s\" (use --force "
"option to override)\n"
% args.output_filename)
sys.exit(1)
if args.preview and os.path.exists(args.preview) and not args.force:
sys.stderr.write( "Won't overwrite existing file \"%s\" (use --force "
"option to override)\n"
% args.preview)
sys.exit(1)
try:
with open(args.output_filename, 'w') as output_file:
img2hex(args.input_filename,
output_file,
args.preview,
args.threshold,
args.dither,
args.negative)
except BaseException,error:
sys.stderr.write("Error converting file: %s\n" % error)
sys.exit(1)

View File

@@ -51,7 +51,7 @@
<option id="gnu.c.compiler.option.warnings.nowarn.1227270879" name="Inhibit all warnings (-w)" superClass="gnu.c.compiler.option.warnings.nowarn" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.fdata.1556802580" name="Place the data in their own section (-fdata-sections)" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.fdata" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="gnu.c.compiler.option.warnings.extrawarn.826041739" name="Extra warnings (-Wextra)" superClass="gnu.c.compiler.option.warnings.extrawarn" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="fr.ac6.managedbuid.gnu.c.compiler.option.misc.other.1256666959" superClass="fr.ac6.managedbuid.gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-fmessage-length=0 -fno-common" valueType="string"/>
<option id="fr.ac6.managedbuid.gnu.c.compiler.option.misc.other.1256666959" name="Other flags" superClass="fr.ac6.managedbuid.gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-fmessage-length=0 -fno-common" valueType="string"/>
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.c.1635097739" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.c"/>
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.s.211510996" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.s"/>
</tool>

View File

@@ -14,92 +14,260 @@
*/
#define FONT_WIDTH 12 /*How many pixels wide the font is*/
const uint8_t FONT[]={
0x00,0xF0,0xFC,0x0E,0x82,0xC2,0x62,0x1E,0xFC,0xF0,0x00,0x00,
0x00,0x03,0x0F,0x1F,0x11,0x10,0x10,0x1C,0x0F,0x03,0x00,0x00,/*0*/
0x00,0x08,0x04,0x02,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10,0x00,0x00,0x00,/*1*/
0x00,0x04,0x02,0x02,0x02,0xC6,0xFC,0x78,0x00,0x00,0x00,0x00,
0x00,0x18,0x1C,0x16,0x13,0x11,0x10,0x10,0x10,0x00,0x00,0x00,/*2*/
0x00,0x02,0x02,0x42,0x42,0x66,0xFE,0x9C,0x00,0x00,0x00,0x00,
0x00,0x10,0x10,0x10,0x10,0x10,0x08,0x0F,0x07,0x00,0x00,0x00,/*3*/
0x00,0x00,0x80,0xE0,0x30,0x1C,0x06,0xFE,0xFE,0x00,0x00,0x00,
0x00,0x03,0x03,0x02,0x02,0x02,0x02,0x1F,0x1F,0x02,0x02,0x00,/*4*/
0x00,0x7E,0x7E,0x42,0x42,0x42,0xC2,0x82,0x00,0x00,0x00,0x00,
0x00,0x10,0x10,0x10,0x10,0x10,0x08,0x0F,0x07,0x00,0x00,0x00,/*5*/
0x00,0xE0,0xF8,0x8C,0x44,0x42,0x42,0xC2,0x82,0x80,0x00,0x00,
0x00,0x07,0x0F,0x18,0x10,0x10,0x10,0x18,0x0F,0x07,0x00,0x00,/*6*/
0x00,0x02,0x02,0x02,0x02,0xC2,0xF2,0x1E,0x06,0x00,0x00,0x00,
0x00,0x00,0x10,0x1C,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,/*7*/
0x00,0x38,0x7C,0x66,0xC2,0x82,0xC2,0x66,0x7C,0x3C,0x00,0x00,
0x00,0x0E,0x0F,0x19,0x10,0x10,0x10,0x19,0x0F,0x0E,0x00,0x00,/*8*/
0x00,0x78,0x7C,0xC6,0x82,0x82,0x82,0x46,0xFC,0xF8,0x00,0x00,
0x00,0x00,0x10,0x10,0x10,0x10,0x08,0x0C,0x07,0x03,0x00,0x00,/*9*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//blank
0x00,0x00,0x00,0x00,0x7C,0xFF,0xFF,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x33,0x00,0x00,0x00,0x00,0x00,//!
0x00,0x00,0x00,0x3C,0x3C,0x00,0x00,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//"
0x00,0x00,0x10,0x90,0xF0,0x7E,0x1E,0x90,0xF0,0x7E,0x1E,0x10,0x00,0x02,0x1E,0x1F,0x03,0x02,0x1E,0x1F,0x03,0x02,0x00,0x00,//#
0x00,0x00,0x78,0xFC,0xCC,0xFF,0xFF,0xCC,0xCC,0x88,0x00,0x00,0x00,0x00,0x04,0x0C,0x0C,0x3F,0x3F,0x0C,0x0F,0x07,0x00,0x00,//$
0x00,0x00,0x38,0x38,0x38,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x00,0x30,0x38,0x1C,0x0E,0x07,0x03,0x01,0x38,0x38,0x38,0x00,//%
0x00,0x00,0x00,0xB8,0xFC,0xC6,0xE2,0x3E,0x1C,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0x31,0x21,0x37,0x1E,0x1C,0x36,0x22,0x00,//&
0x00,0x00,0x00,0x00,0x27,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//'
0x00,0x00,0x00,0xF0,0xFC,0xFE,0x07,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0F,0x1F,0x38,0x20,0x20,0x00,0x00,0x00,//(
0x00,0x00,0x00,0x01,0x01,0x07,0xFE,0xFC,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x38,0x1F,0x0F,0x03,0x00,0x00,0x00,//)
0x00,0x00,0x98,0xB8,0xE0,0xF8,0xF8,0xE0,0xB8,0x98,0x00,0x00,0x00,0x00,0x0C,0x0E,0x03,0x0F,0x0F,0x03,0x0E,0x0C,0x00,0x00,// *
0x00,0x00,0x80,0x80,0x80,0xF0,0xF0,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x0F,0x0F,0x01,0x01,0x01,0x00,0x00,//+
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB8,0xF8,0x78,0x00,0x00,0x00,0x00,0x00,//,
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,//-
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00,//.
0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x00,0x18,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,// /
0x00,0x00,0x80,0xF0,0x1E,0x02,0x1E,0xF0,0x80,0x00,0x00,0x00,
0x00,0x1C,0x0F,0x03,0x02,0x02,0x02,0x03,0x0F,0x1C,0x00,0x00,/*A*/
0x00,0xFE,0xFE,0x42,0x42,0x42,0xE6,0xBE,0x9C,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x10,0x10,0x10,0x18,0x0F,0x07,0x00,0x00,0x00,/*B*/
0x00,0xF0,0xF8,0x0C,0x06,0x02,0x02,0x02,0x04,0x00,0x00,0x00,
0x00,0x03,0x0F,0x0C,0x18,0x10,0x10,0x10,0x08,0x00,0x00,0x00,/*C*/
0x00,0xFE,0xFE,0x02,0x02,0x02,0x06,0x0C,0xFC,0xF0,0x00,0x00,
0x00,0x1F,0x1F,0x10,0x10,0x10,0x18,0x0C,0x07,0x03,0x00,0x00,/*D*/
0x00,0xFE,0xFE,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,/*E*/
0x00,0xFE,0xFE,0x82,0x82,0x82,0x82,0x82,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*F*/
0x00,0xF0,0xF8,0x0C,0x06,0x02,0x82,0x82,0x82,0x84,0x00,0x00,
0x00,0x03,0x0F,0x0C,0x18,0x10,0x10,0x10,0x1F,0x1F,0x00,0x00,/*G*/
0x00,0xFE,0xFE,0x40,0x40,0x40,0x40,0xFE,0xFE,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,/*H*/
0x00,0x02,0x02,0x02,0xFE,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,
0x00,0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10,0x00,0x00,0x00,/*I*/
0x00,0x02,0x02,0x02,0x02,0x02,0xFE,0xFE,0x00,0x00,0x00,0x00,
0x00,0x08,0x10,0x10,0x10,0x18,0x0F,0x07,0x00,0x00,0x00,0x00,/*J*/
0x00,0xFE,0xFE,0xC0,0xE0,0x30,0x18,0x0C,0x06,0x02,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x01,0x03,0x06,0x0C,0x18,0x10,0x00,0x00,/*K*/
0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,/*L*/
0x00,0x00,0xFE,0x06,0x3C,0xC0,0xC0,0x3C,0x06,0xFE,0x00,0x00,
0x00,0x10,0x1F,0x00,0x00,0x01,0x01,0x00,0x00,0x1F,0x18,0x00,/*M*/
0x00,0xFE,0xFE,0x1E,0x70,0x80,0x00,0xFE,0xFE,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x00,0x03,0x1C,0x1F,0x1F,0x00,0x00,0x00,/*N*/
0x00,0xF0,0xFC,0x0C,0x02,0x02,0x02,0x0E,0xFC,0xF0,0x00,0x00,
0x00,0x03,0x0F,0x1C,0x10,0x10,0x10,0x0C,0x0F,0x03,0x00,0x00,/*O*/
0x00,0xFE,0xFE,0x02,0x02,0x02,0x86,0xFC,0x78,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,/*P*/
0x00,0xF0,0xF8,0x0C,0x02,0x02,0x02,0x02,0x0C,0xFC,0xF0,0x00,
0x00,0x03,0x0F,0x1C,0x10,0x30,0x70,0xD8,0x8C,0x8F,0x83,0x40,/*Q*/
0x00,0xFE,0xFE,0x42,0x42,0xC2,0xE6,0x3C,0x1C,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x00,0x00,0x01,0x0F,0x1C,0x10,0x00,0x00,/*R*/
0x00,0x38,0x7C,0x66,0xC2,0xC2,0x82,0x84,0x00,0x00,0x00,0x00,
0x00,0x08,0x10,0x10,0x10,0x10,0x19,0x0F,0x07,0x00,0x00,0x00,/*S*/
0x00,0x02,0x02,0x02,0x02,0xFE,0xFE,0x02,0x02,0x02,0x02,0x00,
0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,/*T*/
0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,
0x00,0x07,0x0F,0x18,0x10,0x10,0x10,0x18,0x0F,0x07,0x00,0x00,/*U*/
0x00,0x0E,0x7E,0xE0,0x00,0x00,0x00,0xE0,0x7C,0x0E,0x00,0x00,
0x00,0x00,0x00,0x03,0x1F,0x18,0x1F,0x03,0x00,0x00,0x00,0x00,/*V*/
0x00,0x7E,0xFE,0x00,0x00,0xE0,0xE0,0x00,0x00,0xFE,0x7E,0x00,
0x00,0x00,0x1F,0x18,0x0F,0x01,0x01,0x0F,0x18,0x1F,0x00,0x00,/*W*/
0x00,0x02,0x06,0x1C,0x38,0xE0,0xE0,0x38,0x1C,0x06,0x02,0x00,
0x00,0x10,0x18,0x0E,0x07,0x01,0x01,0x07,0x0E,0x18,0x10,0x00,/*X*/
0x00,0x02,0x0E,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0E,0x02,0x00,
0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,/*Y*/
0x00,0x02,0x02,0x02,0xC2,0xE2,0x3A,0x0E,0x02,0x00,0x00,0x00,
0x00,0x10,0x1C,0x17,0x11,0x10,0x10,0x10,0x10,0x00,0x00,0x00,/*Z*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/* */
0x00,0xF8,0xFE,0x06,0x03,0x83,0xC3,0x63,0x33,0x1E,0xFE,0xF8,0x00,0x07,0x1F,0x1E,0x33,0x31,0x30,0x30,0x30,0x18,0x1F,0x07,//0
0x00,0x00,0x00,0x0C,0x0C,0x0E,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x3F,0x3F,0x30,0x30,0x30,0x00,//1
0x00,0x1C,0x1E,0x07,0x03,0x03,0x83,0xC3,0xE3,0x77,0x3E,0x1C,0x00,0x30,0x38,0x3C,0x3E,0x37,0x33,0x31,0x30,0x30,0x30,0x30,//2
0x00,0x0C,0x0E,0x07,0xC3,0xC3,0xC3,0xC3,0xC3,0xE7,0x7E,0x3C,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0E,//3
0x00,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x07,0xFF,0xFF,0x00,0x00,0x00,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x3F,0x3F,0x03,0x03,//4
0x00,0x3F,0x7F,0x63,0x63,0x63,0x63,0x63,0x63,0xE3,0xC3,0x83,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,//5
0x00,0xC0,0xF0,0xF8,0xDC,0xCE,0xC7,0xC3,0xC3,0xC3,0x80,0x00,0x00,0x0F,0x1F,0x39,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,//6
0x00,0x03,0x03,0x03,0x03,0x03,0x03,0xC3,0xF3,0x3F,0x0F,0x03,0x00,0x00,0x00,0x00,0x30,0x3C,0x0F,0x03,0x00,0x00,0x00,0x00,//7
0x00,0x00,0xBC,0xFE,0xE7,0xC3,0xC3,0xC3,0xE7,0xFE,0xBC,0x00,0x00,0x0F,0x1F,0x39,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,//8
0x00,0x3C,0x7E,0xE7,0xC3,0xC3,0xC3,0xC3,0xC3,0xE7,0xFE,0xFC,0x00,0x00,0x00,0x30,0x30,0x30,0x38,0x1C,0x0E,0x07,0x03,0x00,//9
0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00,//:
0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9C,0xFC,0x7C,0x00,0x00,0x00,0x00,0x00,//;
0x00,0x00,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,0x00,//<
0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x00,//=
0x00,0x00,0x03,0x07,0x0E,0x1C,0x38,0xF0,0xE0,0xC0,0x00,0x00,0x00,0x00,0x30,0x38,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,//>
0x00,0x1C,0x1E,0x07,0x03,0x83,0xC3,0xE3,0x77,0x3E,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x37,0x00,0x00,0x00,0x00,0x00,//?
0x00,0x60,0xF0,0x98,0x0C,0x06,0x02,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x01,0x03,0x06,0x04,0x00,0x00,0x00,0x00,0x00,/*<*/
0x00,0x02,0x06,0x0C,0x98,0xF0,0x60,0x00,0x00,0x00,0x00,0x00,
0x00,0x04,0x06,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*>*/
0x00,0xF8,0xFE,0x07,0xF3,0xFB,0x1B,0xFB,0xFB,0x07,0xFE,0xF8,0x00,0x0F,0x1F,0x18,0x33,0x37,0x36,0x37,0x37,0x36,0x03,0x01,//@
0x00,0x00,0x00,0xE0,0xFC,0x1F,0x1F,0xFC,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,//A
0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xE7,0xFE,0xBC,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,//B
0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x0E,0x0C,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,//C
0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,//D
0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,//E
0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//F
0x00,0xF0,0xFC,0x0E,0x07,0x03,0xC3,0xC3,0xC3,0xC7,0xC6,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x30,0x3F,0x3F,0x00,//G
0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//H
0x00,0x00,0x00,0x03,0x03,0xFF,0xFF,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//I
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x0E,0x1E,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,//J
0x00,0xFF,0xFF,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,//K
0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,//L
0x00,0xFF,0xFF,0x1E,0x78,0xE0,0xE0,0x78,0x1E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x01,0x01,0x00,0x00,0x3F,0x3F,0x00,//M
0x00,0xFF,0xFF,0x0E,0x38,0xF0,0xC0,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x03,0x07,0x1C,0x3F,0x3F,0x00,//N
0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,//O
0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,//P
0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x36,0x3E,0x1C,0x3F,0x33,0x00,//Q
0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x03,0x07,0x0F,0x1D,0x38,0x30,0x00,//R
0x00,0x3C,0x7E,0xE7,0xC3,0xC3,0xC3,0xC3,0xC7,0x8E,0x0C,0x00,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,//S
0x00,0x00,0x03,0x03,0x03,0xFF,0xFF,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,//T
0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,//U
0x00,0x07,0x3F,0xF8,0xC0,0x00,0x00,0xC0,0xF8,0x3F,0x07,0x00,0x00,0x00,0x00,0x01,0x0F,0x3E,0x3E,0x0F,0x01,0x00,0x00,0x00,//V
0x00,0xFF,0xFF,0x00,0x00,0x80,0x80,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x06,0x03,0x03,0x06,0x1C,0x3F,0x3F,0x00,//W
0x00,0x03,0x0F,0x1C,0x30,0xE0,0xE0,0x30,0x1C,0x0F,0x03,0x00,0x00,0x30,0x3C,0x0E,0x03,0x01,0x01,0x03,0x0E,0x3C,0x30,0x00,//X
0x00,0x03,0x0F,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,//Y
0x00,0x03,0x03,0x03,0x03,0xC3,0xE3,0x33,0x1F,0x0F,0x03,0x00,0x00,0x30,0x3C,0x3E,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x00,//Z
0x00,0x00,0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x00,0x00,0x00,// [
0x00,0x0E,0x1C,0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x18,// backslash
0x00,0x00,0x00,0x03,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x3F,0x3F,0x00,0x00,0x00,// ]
0x00,0x60,0x70,0x38,0x1C,0x0E,0x07,0x0E,0x1C,0x38,0x70,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,//_
0x00,0x00,0x00,0x00,0x00,0x3E,0x7E,0x4E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//`
0x00,0x00,0x40,0x60,0x60,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,//a
0x00,0xFF,0xFF,0xC0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//b
0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x18,0x08,0x00,//c
0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0xE0,0xC0,0xFF,0xFF,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x3F,0x3F,0x00,//d
0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x01,0x00,//e
0x00,0xC0,0xC0,0xFC,0xFE,0xC7,0xC3,0xC3,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//f
0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xE0,0xE0,0x00,0x00,0x03,0xC7,0xCE,0xCC,0xCC,0xCC,0xCC,0xE6,0x7F,0x3F,0x00,//g
0x00,0xFF,0xFF,0xC0,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,//h
0x00,0x00,0x00,0x00,0x60,0xEC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//i
0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xEC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xE0,0xC0,0xC0,0xFF,0x7F,0x00,0x00,0x00,//j
0x00,0x00,0xFF,0xFF,0x00,0x80,0xC0,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x03,0x07,0x0F,0x1C,0x38,0x30,0x00,0x00,//k
0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//l
0x00,0xE0,0xC0,0xE0,0xE0,0xC0,0xC0,0xE0,0xE0,0xC0,0x80,0x00,0x00,0x3F,0x3F,0x00,0x00,0x3F,0x3F,0x00,0x00,0x3F,0x3F,0x00,//m
0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//n
0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//o
0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0xFF,0xFF,0x0C,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,//p
0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xE0,0xE0,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x0C,0xFF,0xFF,0x00,//q
0x00,0x00,0xE0,0xE0,0xC0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//r
0x00,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0x40,0x00,0x00,0x00,0x00,0x11,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,//s
0x00,0x60,0x60,0xFE,0xFE,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0x30,0x30,0x30,0x30,0x00,0x00,0x00,//t
0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,//u
0x00,0x60,0xE0,0x80,0x00,0x00,0x00,0x00,0x80,0xE0,0x60,0x00,0x00,0x00,0x01,0x07,0x1E,0x38,0x38,0x1E,0x07,0x01,0x00,0x00,//v
0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x07,0x1F,0x38,0x1C,0x0F,0x0F,0x1C,0x38,0x1F,0x07,0x00,//w
0x00,0x60,0xE0,0xC0,0x80,0x00,0x80,0xC0,0xE0,0x60,0x00,0x00,0x00,0x30,0x38,0x1D,0x0F,0x07,0x0F,0x1D,0x38,0x30,0x00,0x00,//x
0x00,0x00,0x60,0xE0,0x80,0x00,0x00,0x80,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x81,0xE7,0x7E,0x1E,0x07,0x01,0x00,0x00,0x00,//y
0x00,0x60,0x60,0x60,0x60,0x60,0xE0,0xE0,0x60,0x20,0x00,0x00,0x00,0x30,0x38,0x3C,0x36,0x33,0x31,0x30,0x30,0x30,0x00,0x00,//z
0x00,0x00,0x80,0xC0,0xFC,0x7E,0x07,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x1F,0x3F,0x70,0x60,0x60,0x60,0x00,0x00,//{
0x00,0x00,0x00,0x00,0x00,0xBF,0xBF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,//|
0x00,0x00,0x03,0x03,0x03,0x07,0x7E,0xFC,0xC0,0x80,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x70,0x3F,0x1F,0x01,0x00,0x00,0x00,//}
0x00,0x10,0x18,0x0C,0x04,0x0C,0x18,0x10,0x18,0x0C,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~
0x00,0x00,0x80,0xC0,0x60,0x30,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0F,0x0F,0x00,//Up triangle
};
/*Start extended range*/
const uint8_t FontLatin2[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//A0 (blank)
0x00,0x00,0x00,0x00,0x80,0xF3,0xF3,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x3F,0x3F,0x0F,0x00,0x00,0x00,0x00,//A1//161
0x00,0x00,0xE0,0xF0,0x38,0xFE,0xFE,0x18,0x38,0x30,0x00,0x00,0x00,0x00,0x03,0x07,0x0E,0x3F,0x3F,0x0C,0x0E,0x06,0x00,0x00,//A2//162
0x00,0x00,0x00,0x80,0xF8,0xFC,0x8C,0x8C,0x1C,0x18,0x00,0x00,0x00,0x00,0x18,0x1C,0x1F,0x0B,0x18,0x18,0x18,0x18,0x08,0x00,//A3//163
0x00,0xF6,0xFE,0x18,0x0C,0x0C,0x0C,0x0C,0x18,0xFE,0xF6,0x00,0x00,0x1B,0x1F,0x06,0x0C,0x0C,0x0C,0x0C,0x06,0x1F,0x1B,0x00,//A4//164
0x00,0x03,0x0F,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0F,0x03,0x00,0x00,0x00,0x0A,0x0A,0x0A,0x3F,0x3F,0x0A,0x0A,0x0A,0x00,0x00,//A5//165
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//A6 (blank)
0x00,0x00,0xDC,0xFE,0x22,0x22,0x22,0x22,0xE6,0xC4,0x00,0x00,0x00,0x00,0x08,0x19,0x11,0x11,0x11,0x11,0x1F,0x0E,0x00,0x00,//A7//167
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//A8 (blank)
0x00,0xF0,0xF8,0x1C,0xCC,0xEC,0x2C,0x6C,0x4C,0x1C,0xF8,0xF0,0x00,0x07,0x0F,0x1C,0x19,0x1B,0x1A,0x1B,0x19,0x1C,0x0F,0x07,//A9//169
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//AA (blank)
0x00,0x80,0xC0,0x60,0x20,0x00,0x80,0xC0,0x60,0x20,0x00,0x00,0x00,0x00,0x01,0x03,0x02,0x00,0x00,0x01,0x03,0x02,0x00,0x00,//AB//171
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x00,//AC//172
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//AD (blank)
0x00,0xF0,0xF8,0x1C,0xEC,0xEC,0xAC,0xEC,0x4C,0x1C,0xF8,0xF0,0x00,0x07,0x0F,0x1C,0x1B,0x1B,0x18,0x1B,0x1B,0x1C,0x0F,0x07,//AE//174
0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//AF//175
0x00,0x00,0x00,0x1E,0x3F,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//B0//176
0x00,0x00,0x00,0xC0,0xC0,0xF0,0xF0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x1B,0x1B,0x18,0x18,0x00,0x00,0x00,//B1//177
0x00,0x00,0x19,0x1D,0x15,0x17,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//B2//178
0x00,0x00,0x11,0x15,0x15,0x1F,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//B3//179
0x00,0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//B4//180
0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0xFF,0xFF,0x0E,0x0C,0x0C,0x0C,0x06,0x0F,0x0F,0x00,0x00,//B5//181
0x00,0x38,0x7C,0xC6,0x82,0xFE,0xFE,0x02,0xFE,0xFE,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x3F,0x3F,0x00,0x00,//B6//182
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//B7 (blank)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//B8 (blank)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//B9 (blank)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//BA (blank)
0x00,0x20,0x60,0xC0,0x80,0x00,0x20,0x60,0xC0,0x80,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x00,0x02,0x03,0x01,0x00,0x00,0x00,//BB//187
0x00,0x48,0x7C,0x7C,0x40,0x80,0xC0,0x60,0x30,0x10,0x00,0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x06,0x07,0x04,0x1F,0x1F,0x00,//BC//188
0x00,0x48,0x7C,0x7C,0x40,0x80,0xC0,0x60,0x30,0x10,0x00,0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x00,0x19,0x1D,0x17,0x12,0x00,//BD//189
0x00,0x44,0x54,0x7C,0x28,0x80,0xC0,0x60,0x30,0x10,0x00,0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x06,0x07,0x04,0x1F,0x1F,0x00,//BE//190
0x00,0x00,0x00,0x80,0xC0,0xFB,0x7B,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x1F,0x3B,0x31,0x30,0x30,0x30,0x38,0x1E,0x0E,0x00,//BF//191
0x00,0x00,0x00,0x80,0xE1,0x7B,0x7E,0xE4,0x80,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,//C0//192
0x00,0x00,0x00,0x80,0xE4,0x7E,0x7B,0xE1,0x80,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,//C1//193
0x00,0x00,0x00,0x84,0xE6,0x7B,0x7B,0xE6,0x84,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,//C2//194
0x00,0x00,0x00,0x82,0xE3,0x79,0x7B,0xE2,0x83,0x01,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,//C3//195
0x00,0x00,0x00,0x83,0xE3,0x78,0x78,0xE3,0x83,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,//C4//196
0x00,0x00,0x00,0x80,0xE2,0x75,0x75,0xE2,0x80,0x00,0x00,0x00,0x00,0x38,0x3E,0x0F,0x0D,0x0C,0x0C,0x0D,0x0F,0x3E,0x38,0x00,//C5//197
0x00,0x00,0x80,0xF0,0x7C,0x1F,0xFF,0xFF,0xC3,0xC3,0x03,0x00,0x00,0x3C,0x3F,0x07,0x06,0x06,0x3F,0x3F,0x30,0x30,0x30,0x00,//C6//198
0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x1E,0x1C,0x00,0x00,0x01,0x07,0xCE,0xDC,0xF8,0xF8,0x18,0x1C,0x0E,0x06,0x00,//C7//199
0x00,0xF8,0xF8,0x99,0x9B,0x9E,0x9C,0x98,0x98,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,//C8//200
0x00,0xF8,0xF8,0x98,0x98,0x9C,0x9E,0x9B,0x99,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,//C9//201
0x00,0xF8,0xF8,0x9C,0x9E,0x9B,0x9B,0x9E,0x9C,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,//CA//202
0x00,0xF8,0xF8,0x9B,0x9B,0x98,0x98,0x9B,0x9B,0x18,0x18,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,//CB//203
0x00,0x00,0x00,0x19,0x1B,0xFE,0xFC,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//CC//204
0x00,0x00,0x00,0x18,0x18,0xFC,0xFE,0x1B,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//CD//205
0x00,0x00,0x00,0x1C,0x1E,0xFB,0xFB,0x1E,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//CE//206
0x00,0x00,0x00,0x1B,0x1B,0xF8,0xF8,0x1B,0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//CF//207
0x00,0xC0,0xFF,0xFF,0xC3,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,//D0//208
0x00,0xF8,0xF8,0x72,0xE3,0xC1,0x83,0x02,0x03,0xF9,0xF8,0x00,0x00,0x3F,0x3F,0x00,0x00,0x01,0x03,0x07,0x0E,0x3F,0x3F,0x00,//D1//209
0x00,0xE0,0xF0,0x39,0x1B,0x1E,0x1C,0x18,0x38,0xF0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//D2//210
0x00,0xE0,0xF0,0x38,0x18,0x1C,0x1E,0x1B,0x39,0xF0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//D3//211
0x00,0xE0,0xF0,0x3C,0x1E,0x1B,0x1B,0x1E,0x3C,0xF0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//D4//212
0x00,0xE0,0xF0,0x3A,0x1B,0x19,0x1B,0x1A,0x3B,0xF1,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//D5//213
0x00,0xE0,0xF0,0x3B,0x1B,0x18,0x18,0x1B,0x3B,0xF0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//D6//214
0x00,0x00,0x10,0x30,0x60,0xC0,0xC0,0x60,0x30,0x10,0x00,0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x01,0x03,0x06,0x04,0x00,0x00,//D7//215
0x00,0xF0,0xF8,0x1C,0x0C,0x8C,0xEC,0x7C,0x18,0xFC,0xF4,0x00,0x00,0x2F,0x3F,0x18,0x3E,0x37,0x31,0x30,0x38,0x1F,0x0F,0x00,//D8//216
0x00,0xF8,0xF8,0x01,0x03,0x06,0x04,0x00,0x00,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,//D9//217
0x00,0xF8,0xF8,0x00,0x00,0x04,0x06,0x03,0x01,0xF8,0xF8,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,//DA//218
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//DB (blank)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//DC (blank)
0x00,0x08,0x18,0x30,0x60,0xC4,0xC6,0x63,0x31,0x18,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,//DD//221
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//DE (blank)
0x00,0x00,0xC0,0xE0,0x30,0x10,0x10,0x30,0xE0,0xC0,0x00,0x00,0x00,0x00,0xFF,0xFF,0x21,0x21,0x21,0x33,0x3F,0x1E,0x00,0x00,//DF//223
0x00,0x00,0x40,0x60,0x62,0x66,0x6C,0x68,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,//E0//224
0x00,0x00,0x40,0x60,0x68,0x6C,0x66,0x62,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,//E1//225
0x00,0x00,0x40,0x68,0x6C,0x66,0x66,0x6C,0x68,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,//E2//226
0x00,0x00,0x40,0x68,0x6C,0x64,0x6C,0x68,0x6C,0xE4,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,//E3//227
0x00,0x00,0x40,0x6C,0x6C,0x60,0x60,0x6C,0x6C,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,//E4//228
0x00,0x00,0x40,0x60,0x64,0x6A,0x6A,0x64,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,//E5//229
0x00,0x80,0xC0,0x40,0x40,0xC0,0x80,0x40,0x40,0xC0,0x80,0x00,0x00,0x1C,0x3E,0x22,0x22,0x1F,0x3F,0x22,0x22,0x33,0x11,0x00,//E6//230
0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0xB8,0xB0,0xF0,0xF0,0x30,0x38,0x18,0x08,0x00,//E7//231
0x00,0x80,0xC0,0xE0,0x62,0x66,0x6C,0x68,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x33,0x33,0x33,0x33,0x33,0x33,0x13,0x03,0x00,//E8//232
0x00,0x80,0xC0,0xE0,0x60,0x68,0x6C,0x66,0x62,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x03,0x00,//E9//233
0x00,0x80,0xC0,0xE8,0x6C,0x66,0x66,0x6C,0x68,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x33,0x33,0x33,0x33,0x33,0x33,0x13,0x03,0x00,//EA//234
0x00,0x80,0xC0,0xEC,0x6C,0x60,0x60,0x6C,0x6C,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x33,0x33,0x33,0x33,0x33,0x33,0x13,0x03,0x00,//EB//235
0x00,0x00,0x00,0x00,0x62,0xE6,0xEC,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//EC//236
0x00,0x00,0x00,0x00,0x68,0xEC,0xE6,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//ED//237
0x00,0x00,0x00,0x08,0x6C,0xE6,0xE6,0x0C,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//EE//238
0x00,0x00,0x00,0x0C,0x6C,0xE0,0xEC,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//EF//239
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//F0 (blank)
0x00,0x00,0xE0,0xE8,0x6C,0x64,0x6C,0x68,0xEC,0xC4,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//F1//241
0x00,0x80,0xC0,0xE0,0x62,0x66,0x6C,0x68,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//F2//242
0x00,0x80,0xC0,0xE0,0x68,0x6C,0x66,0x62,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//F3//243
0x00,0x80,0xC0,0xE8,0x6C,0x66,0x66,0x6C,0xE8,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//F4//244
0x00,0x80,0xC8,0xEC,0x64,0x6C,0x68,0x6C,0xE4,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//F5//245
0x00,0x80,0xC0,0xEC,0x6C,0x60,0x60,0x6C,0xEC,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//F6//246
0x00,0x00,0x80,0x80,0x80,0xB0,0xB0,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x0D,0x0D,0x01,0x01,0x01,0x00,0x00,//F7//247
0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0xE0,0xC0,0xE0,0xA0,0x00,0x00,0x2F,0x3F,0x18,0x3C,0x36,0x33,0x31,0x38,0x1F,0x0F,0x00,//F8//248
0x00,0xE0,0xE0,0x00,0x02,0x06,0x0C,0x08,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,//F9//249
0x00,0xE0,0xE0,0x00,0x08,0x0C,0x06,0x02,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,//FA//250
0x00,0xE0,0xE0,0x08,0x0C,0x06,0x06,0x0C,0x08,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,//FB//251
0x00,0xE0,0xE0,0x0C,0x0C,0x00,0x00,0x0C,0x0C,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,//FC//252
0x00,0x00,0x60,0xE0,0x80,0x10,0x18,0x8C,0xE4,0x60,0x00,0x00,0x00,0x00,0x00,0x81,0xE7,0x7E,0x1E,0x07,0x01,0x00,0x00,0x00,//FD//253
0x00,0x00,0x03,0xFF,0xFF,0x1B,0x18,0x18,0xF8,0xF0,0x00,0x00,0x00,0x00,0x30,0x3F,0x3F,0x36,0x06,0x06,0x07,0x03,0x00,0x00,//FE//254
0x00,0x00,0x60,0xEC,0x8C,0x00,0x00,0x8C,0xEC,0x60,0x00,0x00,0x00,0x00,0x00,0x81,0xE7,0x7E,0x1E,0x07,0x01,0x00,0x00,0x00,//FF//255
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x0F,0x0F,0x0F,0x0F,0x00,0x00,0x00,0x00,/*.*/
};
const uint8_t extendedFont[] = {
const uint8_t ExtraFontChars[] = {
0x00,0x0C,0x12,0x12,0x0C,0x00,0xF8,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x01,0x01,0x01,0x00,0x00,//Degrees F
0x00,0x0C,0x12,0x12,0x0C,0xE0,0x10,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x08,0x08,0x08,0x08,0x00, // Degrees C
0x00,0x00,0x00,0x10,0x18,0x1C,0xFE,0x1C,0x18,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,//UP arrow
/*
0x00,0x00,0x00,0x80,0x80,0xFE,0xFF,0x83,0x87,0x06,0x00,0x00,0x00,0x00,0x30,0x70,0x60,0x7F,0x3F,0x00,0x00,0x00,0x00,0x00,//Function?
0x00,0x70,0xFA,0xDB,0xDB,0xDB,0xDB,0xDB,0xDB,0xFF,0xFE,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,//a_
0x00,0x3C,0x7E,0xE7,0xC3,0xC3,0xC3,0xC3,0xE7,0x7E,0x3C,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,//0_
0x55,0x00,0xAA,0x00,0x55,0x00,0xAA,0x00,0x55,0x00,0xAA,0x00,0x55,0x00,0xAA,0x00,0x55,0x00,0xAA,0x00,0x55,0x00,0xAA,0x00,//25% block
0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,//50% pipe
0xAA,0xFF,0x55,0xFF,0xAA,0xFF,0x55,0xFF,0xAA,0xFF,0x55,0xFF,0xAA,0xFF,0x55,0xFF,0xAA,0xFF,0x55,0xFF,0xAA,0xFF,0x55,0xFF,//75% block
0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,//| pipe
0x80,0x80,0x80,0x80,0x80,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,//T pipe ,|
0xC0,0xC0,0xFF,0xFF,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0xFE,0xFE,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,//,| double pipe
0x00,0x00,0xFF,0xFF,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,// || double pipe
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0xFE,0xFE,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,//#NAME?//#NAME?
0xC0,0xC0,0xFF,0xFF,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x07,0x07,0x00,0x00,0x00,0x00,0x00,//,^ double pupe
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,//#NAME?//#NAME?
0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//,> pipe
0x80,0x80,0x80,0x80,0x80,0xFF,0xFF,0x80,0x80,0x80,0x80,0x80,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//_|_ pipe
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,//,|, pipe
0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,//|, pipe
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//#NAME?//#NAME?
0x80,0x80,0x80,0x80,0x80,0xFF,0xFF,0x80,0x80,0x80,0x80,0x80,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,//#NAME?//#NAME?
0x00,0x00,0xFF,0xFF,0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x07,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,//,> double pipe
0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0xFF,0xFF,0x00,0xFE,0xFE,0x06,0x06,0x06,0x06,0x06,//^, double pipe
0xC0,0xC0,0xFF,0xFF,0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,//_|_ double pipe
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x06,0x06,0xFE,0xFE,0x00,0xFE,0xFE,0x06,0x06,0x06,0x06,0x06,//,|, double pipe
0x00,0x00,0xFF,0xFF,0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0xFF,0xFF,0x00,0xFE,0xFE,0x06,0x06,0x06,0x06,0x06,//|, double pipe
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,//== double pipe
0xC0,0xC0,0xFF,0xFF,0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0x06,0x06,0xFE,0xFE,0x00,0xFE,0xFE,0x06,0x06,0x06,0x06,0x06,//#NAME?//#NAME?
0x00,0x00,0x00,0x78,0xFC,0xCC,0x8C,0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x3E,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,//Delta lowercase
0x00,0x00,0x00,0x00,0x00,0x7E,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//27 (')
0x80,0x80,0x80,0x80,0x80,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,//,^ pipe
0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,//| , pipe
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,//solid block
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,//half block bottom
0x00,0x00,0x00,0x00,0x00,0xBF,0xBF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,//7C (|)
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//top half solid block
0x00,0x00,0x0C,0xFC,0xFC,0x6C,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x00,0x30,0x3F,0x3F,0x36,0x06,0x06,0x07,0x03,0x00,0x00,//DE small
0x00,0x00,0x03,0xFF,0xFF,0x1B,0x18,0x18,0xF8,0xF0,0x00,0x00,0x00,0x00,0x30,0x3F,0x3F,0x36,0x06,0x06,0x07,0x03,0x00,0x00,//DE large
0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//? (,)
0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x00,//=
0x00,0x00,0x00,0x40,0x80,0x80,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//sideways comma
0x00,0x00,0x80,0xC0,0x80,0x00,0x00,0x80,0xC0,0x80,0x00,0x00,0x00,0x00,0x01,0x03,0x01,0x00,0x00,0x01,0x03,0x01,0x00,0x00,//..
0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x01,0x00,0x00,0x00,0x00,//.
0x00,0x00,0x02,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//tiny 1
0x00,0x00,0x00,0x00,0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x03,0x00,0x00,0x00,0x00,//small block
*/
};
const uint8_t FontSymbols[] = {
0x00,0x00,0xF8,0x08,0x0E,0x02,0x02,0x0E,0x08,0xF8,0x00,0x00,
0x00,0x00,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x00,0x00,/*Battery Empty*/
@@ -133,50 +301,24 @@ const uint8_t extendedFont[] = {
0x00,0x00,0xF8,0xF8,0xFE,0xF2,0xF2,0xFE,0xF8,0xF8,0x00,0x00,
0x00,0x00,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x00,0x00,/*Battery 10*/
0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,
0xFF,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFF,/*Bar Graph empty (0)*/
0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,
0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,/*Bar 1*/
0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,
0xFF,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xFF,/*Bar 2*/
0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,
0xFF,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xFF,/*Bar 3*/
0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,
0xFF,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xFF,/*Bar 4*/
0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,
0xFF,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFF,/*Bar 5*/
0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,
0xFF,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,/*Bar 6*/
0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*Bar 7*/
0xFF,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*Bar 8*/
0xFF,0xC1,0xC1,0xC1,0xC1,0xC1,0xC1,0xC1,0xC1,0xC1,0xC1,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*Bar 9*/
0xFF,0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,0xE1,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*Bar 10*/
0xFF,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xF1,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*Bar 11*/
0xFF,0xF9,0xF9,0xF9,0xF9,0xF9,0xF9,0xF9,0xF9,0xF9,0xF9,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*Bar 12*/
0xFF,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*Bar 13*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*Bar 14*/
0x00,0x00,0x00,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x0F,0x07,0x03,0x01,0x00,0x00,0x00,0x00,//Right block
0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0F,0x1F,0x00,0x00,0x00,//left block
0x00,0x00,0x00,0x10,0x18,0x1C,0xFE,0x1C,0x18,0x10,0x00,0x00,0x00,0x00,0x00,0x04,0x0C,0x1C,0x3F,0x1C,0x0C,0x04,0x00,0x00,//UD arrow
0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x37,0x00,0x00,0x37,0x37,0x00,0x00,0x00,//!!
0x00,0x38,0x7C,0xC6,0x82,0xFE,0xFE,0x02,0xFE,0xFE,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x3F,0x3F,0x00,0x00,//paragraph
0x00,0x00,0xDC,0xFE,0x22,0x22,0x22,0x22,0xE6,0xC4,0x00,0x00,0x00,0x00,0x08,0x19,0x11,0x11,0x11,0x11,0x1F,0x0E,0x00,0x00,//section
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x00,//cursor
0x00,0x00,0x00,0x08,0x0C,0x0E,0xFF,0x0E,0x0C,0x08,0x00,0x00,0x00,0x00,0x00,0x44,0x4C,0x5C,0x7F,0x5C,0x4C,0x44,0x00,0x00,//UD arrow
0x00,0x00,0x00,0x10,0x18,0x1C,0xFE,0x1C,0x18,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,//UP arrow
0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x0C,0x1C,0x3F,0x1C,0x0C,0x04,0x00,0x00,//Down arrow
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x03,0x01,0x00,0x00,//right arrow
0x00,0x00,0x80,0xC0,0xE0,0xF0,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x00,0x00,0x00,0x00,0x00,0x00,//left arrow
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,
0x00,0x80,0xC0,0xE0,0xF0,0x80,0x80,0x80,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x01,0x03,0x07,0x00,0x00,0x00,0x07,0x03,0x01,0x00,//LR arrow
0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x04,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x06,0x04,//UP block
0x00,0x20,0x60,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0x60,0x20,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x03,0x01,0x00,0x00,0x00,//Down block
};
const uint8_t DoubleWidthChars[]={
0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,

View File

@@ -8,40 +8,28 @@
/* Functions for access to data */
extern volatile uint32_t system_Ticks;
void delayMs(uint32_t ticks);
extern volatile uint32_t lastKeyPress;
extern volatile uint32_t lastMovement;
extern volatile uint8_t keyState;
extern volatile uint8_t rawKeys;
extern volatile uint8_t InterruptMask;//Used to mask interrupts
extern volatile uint8_t rawKeys;
inline uint32_t millis() {
return system_Ticks;
}
inline uint32_t getLastButtonPress() {
return lastKeyPress;
}
inline void resetLastButtonPress() {
lastKeyPress = millis();
}
inline void resetButtons() {
keyState = 0;
}
inline uint32_t getLastMovement() {
return lastMovement;
}
inline uint16_t getButtons() {
return keyState;
}
uint8_t getButtons();
uint32_t getLastButtonPress();
inline uint16_t getRawButtons() {
return rawKeys;
}
inline void restoreButtons() {
keyState = getRawButtons();
}
extern volatile uint8_t RotationChangedFlag;
/*IRQ prototypes*/
void NMI_Handler(void);

View File

@@ -10,6 +10,7 @@
#ifndef MODES_H_
#define MODES_H_
#include "Interrupt.h"
#include "S100V0_1.h"
#include "Oled.h"
@@ -18,6 +19,8 @@
#include "Analog.h"
#include "MMA8652FC.h"
#include <string.h>
#include "Strings.h"
typedef enum {
STARTUP, //we are sitting on the prompt to push a button
SOLDERING, //Normal operating mode
@@ -31,8 +34,12 @@ typedef enum {
TEMPCAL, //Cal tip temp offset
} operatingModeEnum;
#define SETTINGSOPTIONSCOUNT 11 /*Number of settings in the settings menu*/
//#define PIDTUNING
#ifdef PIDTUNING
#define SETTINGSOPTIONSCOUNT (13+3) /*Number of settings in the settings menu*/
#else
#define SETTINGSOPTIONSCOUNT (13) /*Number of settings in the settings menu*/
#endif
typedef enum {
UVCO = 0,
SLEEP_TEMP,
@@ -46,8 +53,16 @@ typedef enum {
BOOSTMODE,
BOOSTTEMP,
POWERDISPLAY,
AUTOSTART,
COOLINGBLINK,
#ifdef PIDTUNING
PIDP,
PIDI,
PIDD,
#endif
} settingsPageEnum;
void ProcessUI();
void DrawUI();
extern operatingModeEnum operatingMode;
#endif /* MODES_H_ */

View File

@@ -13,25 +13,26 @@
void Oled_DisplayOn(void);
void Oled_DisplayOff(void);
const u8* Oled_DrawArea(u8 x0, u8 y0, u8 wide, u8 high, const u8* ptr);
void OLED_Sync();
void Oled_DrawArea(u8 x0, u8 y0, u8 wide, u8 height, const u8* ptr);
void Set_ShowPos(u8 x, u8 y);
void Oled_DisplayFlip();
void OLED_InvertBuffer();
void GPIO_Init_OLED(void);
void Init_Oled(uint8_t leftHanded);
const u8* Data_Command(u8 len, const u8* ptr);
void Clear_Screen(void); //Clear the screen
/*Functions for writing to the screen*/
void OLED_DrawString(const char* string, const uint8_t length);
void OLED_DrawChar(char c, uint8_t x);
void OLED_DrawExtendedChar(uint8_t id, uint8_t x);
void OLED_DrawChar(char c, uint8_t x,char preCursor);
void OLED_DrawExtraFontChars(uint8_t id, uint8_t x);
void OLED_DrawSymbolChar(uint8_t id, uint8_t x);
void OLED_DrawWideChar(uint8_t id, uint8_t x);
void OLED_DrawTwoNumber(uint8_t in, uint8_t x);
void OLED_BlankSlot(uint8_t xStart, uint8_t width);
void OLED_DrawThreeNumber(uint16_t in, uint8_t x);
void OLED_DrawIDLELogo();
void OLED_DrawSymbol(uint8_t x, uint8_t symbol);
const u8* Oled_DrawArea(u8 x0, u8 y0, u8 wide, u8 high, const u8* ptr);
void OLED_SetOrientation(uint8_t ori);
uint8_t OLED_GetOrientation();
#endif

View File

@@ -18,4 +18,5 @@ typedef struct {
int32_t computePID(uint16_t setpoint);
void setupPID(void);
extern pidSettingsType pidSettings;
#endif /* PID_H_ */

View File

@@ -12,7 +12,7 @@
#include <stdint.h>
#include "stm32f10x_flash.h"
#include "Oled.h"
#define SETTINGSVERSION 14 /*Change this if you change the struct below to prevent people getting out of sync*/
#define SETTINGSVERSION 17 /*Change this if you change the struct below to prevent people getting out of sync*/
//Display Speeds
#define DISPLAYMODE_FAST (0x00)
#define DISPLAYMODE_MEDIUM (0x01)
@@ -34,14 +34,17 @@ typedef struct {
uint8_t powerDisplay:1; //Toggle to swap the arrows with a power readout instead
uint8_t displayTempInF:1; //If we need to convert the C reading to F
uint8_t OrientationMode:2; //If true we want to invert the display for lefties
uint8_t sensitivity:6; //Sensitivity of accelerometer (5 bits)
uint8_t sensitivity:5; //Sensitivity of accelerometer (5 bits)
uint8_t autoStart:2; //Should the unit automatically jump straight into soldering mode when power is applied
uint8_t ShutdownTime:6; //Time until unit shuts down if left alone
uint8_t displayUpdateSpeed:2; //How fast the display updates / temp showing mode
uint8_t temperatureRounding:2; //Rounding mode for the temperature
uint8_t boostModeEnabled:1; //Boost mode swaps BUT_A in soldering mode to temporary soldering temp over-ride
uint8_t coolingTempBlink:1; //Should the temperature blink on the cool down screen until its <50C
uint16_t tempCalibration; //Temperature calibration value
uint16_t voltageDiv; //Voltage divisor factor
uint16_t BoostTemp; //Boost mode set point for the iron
uint32_t padding;//This is here for in case we are not an even divisor so that nothing gets cut off
} systemSettingsType;
extern systemSettingsType systemSettings;

View File

@@ -0,0 +1,31 @@
/*
* Strings.h
*
* Created on: 4Aug.,2017
* Author: Ben V. Brown
*/
/*
* This file is used to allow for different language builds of the firmware
* This file houses all the strings for the text used on the iron.
*/
#ifndef STRINGS_H_
#define STRINGS_H_
extern const char* SettingsLongNames[14];
extern const char* SettingsShortNames[14];
extern const char* TempCalStatus[3]; //All fixed 8 chars
extern const char* UVLOWarningString; //Fixed width 8 chars
extern const char* CoolingPromptString; //Fixed width 5 chars
extern const char SettingTrueChar;
extern const char SettingFalseChar;
extern const char SettingSleepChar;
extern const char SettingFastChar;
extern const char SettingMediumChar;
extern const char SettingSlowChar;
extern const char SettingRightChar;
extern const char SettingLeftChar;
extern const char SettingAutoChar;
extern const char SettingTempCChar;
extern const char SettingTempFChar;
#endif /* STRINGS_H_ */

View File

@@ -14,6 +14,7 @@ uint16_t readDCVoltage(uint16_t divFactor) {
uint16_t reading = 0;
for (u8 i = 0; i < 10; i++) {
reading += ADC_GetConversionValue(ADC2);
delayMs(5);
}
reading /= divFactor; //take the average and convert to X10 voltage
return reading; //return the read voltage
@@ -23,7 +24,7 @@ uint16_t readDCVoltage(uint16_t divFactor) {
//This allows us to read it in X10 mode
//Returns temperature in C X10 mode
int16_t readTipTemp() {
static uint32_t rollingAverage[16];
static uint32_t rollingAverage[8];
static uint8_t rIndex = 0;
/*The head has a thermocouple inline with the heater
@@ -54,13 +55,10 @@ int16_t readTipTemp() {
ad_sum = ad_sum - max - min; //remove the two outliers
avg_data = ad_sum / 8; //take the average
rollingAverage[rIndex] = avg_data;
rIndex = (rIndex + 1) % 16;
rIndex = (rIndex + 1) % 8;
return (rollingAverage[0] + rollingAverage[1] + rollingAverage[2]
+ rollingAverage[3] + rollingAverage[4] + rollingAverage[5]
+ rollingAverage[6] + rollingAverage[7] + rollingAverage[8]
+ rollingAverage[9] + rollingAverage[10] + rollingAverage[11]
+ rollingAverage[12] + rollingAverage[13] + rollingAverage[14]
+ rollingAverage[15]) / 16; //get the average
+ rollingAverage[6] + rollingAverage[7]) / 8;
}

View File

@@ -5,7 +5,6 @@
#include "Bios.h"
#include "I2C.h"
#define ADC1_DR_Address ((u32)0x4001244C)
volatile uint32_t gHeat_cnt = 0;
@@ -56,7 +55,7 @@ void GPIO_Config(void) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); // GPIOB & AFIO
GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//disables jtag and maps pins for SWD
//------ PA7 TMP36 Analog input ----------------------------------------//
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
@@ -64,7 +63,7 @@ void GPIO_Config(void) {
GPIO_Init(GPIOA, &GPIO_InitStructure);
//------ OLED_RST_PIN(PB9) ---------------------------------------------//
GPIO_InitStructure.GPIO_Pin = OLED_RST_PIN;
GPIO_InitStructure.GPIO_Pin = OLED_RST_PIN|GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
@@ -92,10 +91,16 @@ void GPIO_Config(void) {
GPIO_Init(GPIOA, &GPIO_InitStructure);
//--------INT 1 == PB5 -------------------------------------------------//
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//pullup just in case something resets the accel
GPIO_InitStructure.GPIO_Pin = INT1_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //pullup just in case something resets the accel
GPIO_Init(GPIOB, &GPIO_InitStructure);
//--------INT 2 == PB3 -------------------------------------------------//
GPIO_InitStructure.GPIO_Pin = INT2_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //pullup just in case something resets the accel
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA, GPIO_Pin_12);//Write PA12 low so USB does not enumerate
}
/*
* Init the ADC's
@@ -150,7 +155,7 @@ void Adc_Init(void) {
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1,
ADC_SampleTime_239Cycles5); //28 or 55
ADC_RegularChannelConfig(ADC2, ADC_Channel_9, 1,
ADC_SampleTime_55Cycles5); //28 or 55
ADC_SampleTime_239Cycles5); //28 or 55
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
@@ -211,7 +216,8 @@ void Init_EXTI(void) {
GPIO_PinSource5); //PB5 == accelerometer
/* Configure EXTI5/6/9 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line5 | EXTI_Line6 | EXTI_Line9;
EXTI_InitStructure.EXTI_Line = EXTI_Line5 | EXTI_Line6 | EXTI_Line9
| EXTI_Line3;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //trigger on up and down
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
@@ -224,6 +230,13 @@ void Init_EXTI(void) {
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable and set EXTI9_5 Interrupt to the lowest priority */
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//Start the system watchdog with a timeout specified
//Note you cannot turn this off once you turn it on

View File

@@ -78,10 +78,10 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
uint16_t numByteToRead) {
__IO uint32_t temp = 0;
volatile int I2C_TimeOut = 0;
volatile int I2C_TimeOut = temp;
// /* While the bus is busy * /
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -92,7 +92,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
I2C_GenerateSTART(I2C1, ENABLE);
// / * Test on EV5 and clear it * /
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -103,7 +103,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
I2C_Send7bitAddress(I2C1, deviceAddr, I2C_Direction_Transmitter);
// / * Test on EV6 and clear it * /
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -114,7 +114,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
I2C_SendData(I2C1, readAddr);
/// * Test on EV8 and clear it * /
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -125,7 +125,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
I2C_GenerateSTART(I2C1, ENABLE);
/// * Test on EV5 and clear it * /
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -137,7 +137,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
if (numByteToRead == 1) {
/* Wait until ADDR is set */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->SR1 & 0x0002) != 0x0002) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -155,7 +155,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
/* Re-enable IRQs */
__enable_irq();
/* Wait until a data is received in DR register (RXNE = 1) EV7 */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->SR1 & 0x00040) != 0x000040) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -169,7 +169,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
/* Set POS bit */
I2C1->CR1 |= CR1_POS_Set;
/* Wait until ADDR is set: EV6 */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->SR1 & 0x0002) != 0x0002) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -186,7 +186,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
/*Re-enable IRQs */
__enable_irq();
/* Wait until BTF is set */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->SR1 & 0x00004) != 0x000004) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -210,7 +210,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
else { //numByteToRead > 2
// * Test on EV6 and clear it * /
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while (!I2C_CheckEvent(I2C1,
I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) {
if (I2C_TimeOut-- <= 0) {
@@ -223,7 +223,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
if (numByteToRead != 3) {
/* Poll on BTF to receive data because in polling mode we can not guarantee the
EV7 software sequence is managed before the current byte transfer completes */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->SR1 & 0x00004) != 0x000004) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -239,7 +239,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
/* it remains to read three data: data N-2, data N-1, Data N */
if (numByteToRead == 3) {
/* Wait until BTF is set: Data N-2 in DR and data N -1 in shift register */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->SR1 & 0x00004) != 0x000004) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -263,7 +263,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
/* Increment */
pBuffer++;
/* Wait until RXNE is set (DR contains the last data) */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->SR1 & 0x00040) != 0x000040) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -278,7 +278,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
}
/* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->CR1 & 0x200) == 0x200) {
if (I2C_TimeOut-- <= 0) {
return 1;

View File

@@ -3,10 +3,13 @@
#include "I2C.h"
volatile uint32_t system_Ticks;
volatile uint32_t lastKeyPress; //millis() at the last button event
volatile uint8_t keyState; //tracks the button status
volatile uint32_t BkeyChange; //millis() at the last button event
volatile uint32_t AkeyChange;
volatile uint8_t rawKeys;
volatile uint8_t LongKeys;
volatile uint32_t lastMovement; //millis() at last movement event
volatile uint8_t RotationChangedFlag;
volatile uint8_t InterruptMask;
//Delay in milliseconds using systemTick
void delayMs(uint32_t ticks) {
@@ -14,6 +17,104 @@ void delayMs(uint32_t ticks) {
while (millis() < endtime)
;
}
uint32_t getLastButtonPress() {
if (BkeyChange > AkeyChange)
return BkeyChange;
return AkeyChange;
}
uint8_t getButtons() {
//We want to check the times for the lat buttons & also the rawKeys state
//If a key has just gone down, rawKeys & KEY ==1
//This is effectively just a big switch statement to handle a small delay on triggering to stop bounce, and also handle key repeat
uint8_t out = 0;
//Special handling case for two keys down at once
//This is here to allow for people who do not manage to get both keys down within 50ms of each other.
if ((rawKeys & (BUT_A | BUT_B)) == (BUT_A | BUT_B)) {
//both keys are probably down
if (millis() - AkeyChange > 50)
if (millis() - BkeyChange > 50) {
out = (BUT_A | BUT_B);
AkeyChange = millis();
BkeyChange = millis();
rawKeys = 0;
}
LongKeys = 0;
} else {
if (millis() - AkeyChange > 80) {
if (LongKeys & BUT_A) {
if (rawKeys & BUT_A) {
if (millis() - AkeyChange > 800) {
out |= BUT_A;
AkeyChange = millis();
LongKeys &= ~BUT_A;
LongKeys |= (BUT_A << 2);
}
} else {
LongKeys &= ~BUT_A;
LongKeys &= ~(BUT_A << 2);
}
} else if (LongKeys & (BUT_A << 2)) {
if (rawKeys & BUT_A) {
if (millis() - AkeyChange > 100) {
out |= BUT_A;
AkeyChange = millis();
}
} else {
LongKeys &= ~BUT_A;
LongKeys &= ~(BUT_A << 2);
}
} else {
if (rawKeys & BUT_A) {
//The key is down
out |= BUT_A;
LongKeys |= BUT_A;
} else {
//The key has been lifted
LongKeys &= ~BUT_A;
LongKeys &= ~(BUT_A << 2);
}
}
}
if (millis() - BkeyChange > 80) {
if (LongKeys & BUT_B) {
if (rawKeys & BUT_B) {
if (millis() - BkeyChange > 800) {
out |= BUT_B;
BkeyChange = millis();
LongKeys |= (BUT_B << 2);
LongKeys &= ~BUT_B;
}
} else {
LongKeys &= ~BUT_B;
LongKeys &= ~(BUT_B << 2);
}
} else if (LongKeys & (BUT_B << 2)) {
if (rawKeys & BUT_B) {
if (millis() - BkeyChange > 100) {
out |= BUT_B;
BkeyChange = millis();
}
} else {
LongKeys &= ~BUT_B;
LongKeys &= ~(BUT_B << 2);
}
} else {
if (rawKeys & BUT_B) {
//The key is down
out |= BUT_B;
LongKeys |= BUT_B;
} else {
//The key has been lifted
LongKeys &= ~BUT_B;
LongKeys &= ~(BUT_B << 2);
}
}
}
}
return out;
}
void NMI_Handler(void) {
;
@@ -57,30 +158,33 @@ void EXTI9_5_IRQHandler(void) {
//Line 5 == movement
if (EXTI_GetITStatus(EXTI_Line9) != RESET) {
if (GPIO_ReadInputDataBit(GPIOA, KEY_A) == SET) {
keyState &= ~(BUT_A);
rawKeys &= ~BUT_A;
} else {
keyState |= BUT_A;
rawKeys |= BUT_A;
lastKeyPress = millis();
}
AkeyChange = millis();
EXTI_ClearITPendingBit(EXTI_Line9);
} else if (EXTI_GetITStatus(EXTI_Line6) != RESET) {
if (GPIO_ReadInputDataBit(GPIOA, KEY_B) == SET) {
keyState &= ~(BUT_B);
rawKeys &= ~BUT_B;
} else {
keyState |= BUT_B;
rawKeys |= BUT_B;
lastKeyPress = millis();
}
BkeyChange = millis();
EXTI_ClearITPendingBit(EXTI_Line6);
} else if (EXTI_GetITStatus(EXTI_Line5) != RESET) { //Movement Event
lastMovement = millis();
if (!InterruptMask)
lastMovement = millis();
EXTI_ClearITPendingBit(EXTI_Line5);
}
}
void EXTI3_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line3) != RESET) { //Orientation Change
RotationChangedFlag = 1;
EXTI_ClearITPendingBit(EXTI_Line3);
}
}
/*********************** UNUSED IRQ *****************************************/
void WWDG_IRQHandler(void) {
@@ -101,8 +205,7 @@ void EXTI1_IRQHandler(void) {
}
void EXTI2_IRQHandler(void) {
}
void EXTI3_IRQHandler(void) {
}
void EXTI4_IRQHandler(void) {
}
void DMA1_Channel1_IRQHandler(void) {

View File

@@ -52,9 +52,9 @@ void StartUp_Accelerometer(uint8_t sensitivity) {
I2C_RegisterWrite(PL_CFG_REG, 0x40); //Enable the orientation detection
I2C_RegisterWrite(PL_COUNT_REG, 200); //200 count debounce
I2C_RegisterWrite(PL_BF_ZCOMP_REG, 0b01000111); //Set the threshold to 42 degrees
I2C_RegisterWrite(P_L_THS_REG, 0b10011100);//Up the trip angles
I2C_RegisterWrite( CTRL_REG4, 0x04); // Enable motion interrupt
I2C_RegisterWrite( CTRL_REG5, 0x04);// Route motion interrupts to INT1 ->PB5 ->EXTI5
I2C_RegisterWrite(P_L_THS_REG, 0b10011100); //Up the trip angles
I2C_RegisterWrite( CTRL_REG4, 0x04 | (1<<4)); // Enable motion interrupt & orientation interrupt
I2C_RegisterWrite( CTRL_REG5, 0x04);// Route motion interrupts to INT1 ->PB5 ->EXTI5, leaving orientation routed to INT2
I2C_RegisterWrite( CTRL_REG1, 0x11); // ODR=800 Hz, Active mode
}

View File

@@ -14,15 +14,50 @@ void setup();
int main(void) {
setup();/*Setup the system*/
for(uint8_t i=0;i<100;i++)
readIronTemp(0, 1, 0xFFFF);
if (systemSettings.autoStart == 1)
operatingMode = SOLDERING;
else if (systemSettings.autoStart == 2)
operatingMode = SLEEP;
if (systemSettings.autoStart) {
InterruptMask = 1; //set the mask
lastMovement = 0;
} else
InterruptMask = 0;
if (readIronTemp(0, 1, 0xFFFF) > 500)
operatingMode = COOLING;
while (1) {
Clear_Watchdog(); //reset the Watch dog timer
ProcessUI();
DrawUI();
delayMs(50); //Slow the system down a little bit
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5) == Bit_RESET) {
OLED_Sync(); //Write out the screen buffer
delayMs(15); //Slow the system down waiting for the iron.
if (systemSettings.OrientationMode == 2) {
//Automatic mode
if (RotationChangedFlag) {
OLED_SetOrientation(!getOrientation());
RotationChangedFlag = 0;
} else if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3) == Bit_RESET) {
OLED_SetOrientation(!getOrientation());
RotationChangedFlag = 0;
//^ This is a workaround for the IRQ being set off before we have the handler setup and enabled.
}
}
if ((GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5) == Bit_RESET)
&& (!InterruptMask)) {
lastMovement = millis();
//This is a workaround for the line staying low as the user is still moving. (ie sensitivity is too high for their amount of movement)
}
delayMs(15); //Slow the system down waiting for the iron.
if (systemSettings.autoStart && (millis() > 10000) && InterruptMask) {
//If the user has setup the device to auto enter a startup mode, we normally have the interrupts on motion masked for the inital 10 seconds to prevent waking up during initalization
//This allows us to re-enable these interrupts.
InterruptMask = 0;
}
}
}
void setup() {
@@ -39,13 +74,25 @@ void setup() {
setupPID(); //Init the PID values
readIronTemp(systemSettings.tempCalibration, 0, 0); //load the default calibration value
if (systemSettings.OrientationMode == 2)
Init_Oled(!getOrientation()); //Init the OLED display
Init_Oled(0); //Init the OLED display in RH mode, since accel wont have started up yet
else
Init_Oled(systemSettings.OrientationMode); //Init the OLED display
Init_Oled(systemSettings.OrientationMode); //Init the OLED display
OLED_DrawString("VER 1.16", 8); //Version Number
delayMs(400); //Pause to show version number
OLED_DrawString("Ver 1.17", 8); //Version Number
OLED_Sync();
delayMs(400); //Pause to show version number
showBootLogoIfavailable();
Start_Watchdog(5000); //start the system watch dog as 5 second timeout
//RESETs settings
if (GPIO_ReadInputDataBit(GPIOA, KEY_B) == Bit_RESET) {
OLED_DrawString("Reset ?", 8);
delayMs(1000);
if (GPIO_ReadInputDataBit(GPIOA, KEY_B) == Bit_RESET) {
OLED_DrawString(" OK ", 8);
delayMs(1000);
resetSettings();
}
}
Start_Watchdog(5000); //start the system watch dog as 5 second timeout
}

View File

@@ -5,17 +5,7 @@
* Author: Ralim <ralim@ralimtek.com>
*/
#include "Modes.h"
const char *SettingsLongNames[] =
{ " Power source. Sets cutoff voltage. <DC 10V> <S 3.3V per cell>",
" Sleep Temperature <C>", " Sleep Timeout <Minutes>",
" Shutdown Timeout <Minutes>",
" Motion Sensitivity <0.Off 1.least sensitive 9.most sensitive>",
" Temperature Unit", " Temperature Rounding Amount",
" Temperature Display Update Rate",
" Display Orientation <A. Automatic L. Left Handed R. Right Handed>",
" Enable front key boost 450C mode when soldering",
" Temperature when in boost mode",
" Changes the arrows to a power display when soldering" };
uint8_t StatusFlags = 0;
uint32_t temporaryTempStorage = 0;
@@ -26,14 +16,6 @@ settingsPageEnum settingsPage;
void ProcessUI() {
uint8_t Buttons = getButtons(); //read the buttons status
static uint32_t lastModeChange = 0;
if (getRawButtons() && ((millis() - getLastButtonPress()) > 1000)) {
lastKeyPress = millis() - 700;
Buttons = getRawButtons();
} else if (millis() - getLastButtonPress() < 100) {
Buttons = 0;
} else if (Buttons != 0) {
resetButtons();
}
switch (operatingMode) {
case STARTUP:
@@ -51,6 +33,8 @@ void ProcessUI() {
}
break;
case SOLDERING:
//^ This is to make the button more delayed in timing for people to find A+B easier
//We need to check the buttons if we need to jump out
if ((Buttons == BUT_A && !systemSettings.boostModeEnabled)
|| Buttons == BUT_B) {
@@ -90,15 +74,20 @@ void ProcessUI() {
StatusFlags = 0;
}
//We need to check the timer for movement in case we need to goto idle
if (systemSettings.sensitivity)
if (millis() - getLastMovement()
> (systemSettings.SleepTime * 60000)) {
if (millis() - getLastButtonPress()
> (systemSettings.SleepTime * 60000)) {
if (systemSettings.sensitivity) {
uint32_t timeout = 0;
if (systemSettings.SleepTime < 6)
timeout = 1000 * 10 * systemSettings.SleepTime;
else
timeout = 60 * 1000 * (systemSettings.SleepTime - 5);
if (millis() - getLastMovement() > (timeout)) {
if (millis() - getLastButtonPress() > (timeout)) {
operatingMode = SLEEP;
return;
}
}
}
uint16_t voltage = readDCVoltage(systemSettings.voltageDiv); //get X10 voltage
if ((voltage) < lookupVoltageLevel(systemSettings.cutoutSetting)) {
operatingMode = UVLOWARN;
@@ -161,39 +150,49 @@ void ProcessUI() {
//The user pressed the button to breakout of the settings help prompt
StatusFlags = 0;
} else {
if (Buttons & BUT_B) {
if (Buttons == (BUT_A | BUT_B)) {
//Both buttons were pressed, exit back to the startup screen
settingsPage = 0; //reset
operatingMode = STARTUP; //reset back to the startup
saveSettings(); //Save the settings
StartUp_Accelerometer(systemSettings.sensitivity); //Start the accelerometer
} else if (Buttons & BUT_B) {
//A key iterates through the menu
if (settingsPage == SETTINGSOPTIONSCOUNT) {
//Roll off the end
settingsPage = 0; //reset
operatingMode = STARTUP; //reset back to the startup
operatingMode = STARTUP; //reset back to the startup
saveSettings(); //Save the settings
StartUp_Accelerometer(systemSettings.sensitivity); //Start the accelerometer
} else {
++settingsPage; //move to the next option
++settingsPage; //move to the next option
}
} else if (Buttons & BUT_A) {
//B changes the value selected
switch (settingsPage) {
case UVCO:
//we are incrementing the cutout voltage
systemSettings.cutoutSetting += 1; //Go up 1V at a jump
systemSettings.cutoutSetting += 1; //Go up 1V at a jump
systemSettings.cutoutSetting %= 5; //wrap 0->4
break;
case SLEEP_TEMP:
systemSettings.SleepTemp += 100; //Go up 10C at a time
if (systemSettings.SleepTemp > 3000)
systemSettings.SleepTemp = 1000;//cant sleep higher than 300
systemSettings.SleepTemp = 500; //cant sleep higher than 300 or less than 50
break;
case SLEEP_TIME:
++systemSettings.SleepTime; //Go up 1 minute at a time
if (systemSettings.SleepTime > 30)
++systemSettings.SleepTime; //Go up 1 minute at a time
if (systemSettings.SleepTime > 16)
systemSettings.SleepTime = 1;//can't set time over 30 mins
//Remember that ^ is the time of no movement
break;
case SHUTDOWN_TIME:
++systemSettings.ShutdownTime;
if (systemSettings.ShutdownTime > 60)
systemSettings.ShutdownTime = 0; //wrap to off
systemSettings.ShutdownTime = 0; //wrap to off
break;
case TEMPDISPLAY:
systemSettings.displayTempInF =
@@ -201,7 +200,8 @@ void ProcessUI() {
break;
case SCREENROTATION:
systemSettings.OrientationMode++;
systemSettings.OrientationMode = systemSettings.OrientationMode % 3;
systemSettings.OrientationMode =
systemSettings.OrientationMode % 3;
break;
case MOTIONSENSITIVITY:
@@ -232,6 +232,28 @@ void ProcessUI() {
case POWERDISPLAY:
systemSettings.powerDisplay = !systemSettings.powerDisplay;
break;
case AUTOSTART:
systemSettings.autoStart++;
systemSettings.autoStart %= 3;
break;
case COOLINGBLINK:
systemSettings.coolingTempBlink =
!systemSettings.coolingTempBlink;
break;
#ifdef PIDTUNING
case PIDP:
pidSettings.kp++;
pidSettings.kp %= 20;
break;
case PIDI:
pidSettings.ki++;
pidSettings.ki %= 10;
break;
case PIDD:
pidSettings.kd++;
pidSettings.kd %= 30;
break;
#endif
default:
break;
}
@@ -250,7 +272,7 @@ void ProcessUI() {
operatingMode = SOLDERING;
Oled_DisplayOn();
return;
} else if (systemSettings.sensitivity) {
} else if (systemSettings.sensitivity && !InterruptMask) {
if (millis() - getLastMovement() < 1000) {//moved in the last second
operatingMode = SOLDERING; //Goto active mode again
Oled_DisplayOn();
@@ -278,18 +300,7 @@ void ProcessUI() {
//Either button was pushed
operatingMode = STARTUP;
}
if (systemSettings.sensitivity) {
if (millis() - getLastMovement()
> (systemSettings.ShutdownTime * 60000)) {
if ((millis() - getLastButtonPress()
> systemSettings.ShutdownTime * 60000)) {
Oled_DisplayOff();
}
} else {
Oled_DisplayOn();
}
} else
Oled_DisplayOn();
}
break;
case UVLOWARN:
@@ -411,22 +422,24 @@ void DrawUI() {
static uint16_t lastSolderingDrawnTemp2 = 0;
static uint8_t settingsLongTestScrollPos = 0;
uint16_t temp = readIronTemp(0, 0, 0xFFFF);
if (systemSettings.OrientationMode == 2) {
//Automatic mode
OLED_SetOrientation(!getOrientation());
if (systemSettings.sensitivity) {
if (millis() - getLastMovement() > (5 * 60 * 1000)
&& (millis() - getLastButtonPress() > (5 * 60 * 1000))
&& (temp < 400)) {
//OLED off
Oled_DisplayOff();
} else {
Oled_DisplayOn();
}
}
switch (operatingMode) {
case STARTUP:
//We are chilling in the idle mode
//Check if movement in the last 5 minutes , if not sleep OLED
if (millis() - getLastMovement() > (5 * 60 * 1000)
&& (millis() - getLastButtonPress() > (5 * 60 * 1000))) {
//OLED off
Oled_DisplayOff();
} else {
Oled_DisplayOn();
OLED_DrawIDLELogo(); //Draw the icons for prompting the user
}
OLED_DrawIDLELogo(); //Draw the icons for prompting the user
temp = readIronTemp(0, 1, 0xFFFF);//to update the internal filter buffer
break;
case SOLDERING:
//The user is soldering
@@ -437,22 +450,23 @@ void DrawUI() {
else if (systemSettings.displayUpdateSpeed == DISPLAYMODE_MEDIUM
&& (millis() - lastOLEDDrawTime < 100))
return;
else if (systemSettings.displayUpdateSpeed == DISPLAYMODE_FAST
&& (millis() - lastOLEDDrawTime < 50))
return;
Clear_Screen();
Oled_DisplayOn();
uint32_t tempavg = (temp + lastSolderingDrawnTemp1
+ lastSolderingDrawnTemp2);
tempavg /= 3;
drawTemp(tempavg, 0, systemSettings.temperatureRounding);
lastSolderingDrawnTemp1 = temp;
lastSolderingDrawnTemp2 = lastSolderingDrawnTemp1;
lastOLEDDrawTime = millis();
//Now draw symbols
if (StatusFlags == 8)
OLED_DrawChar('B', 4);
OLED_DrawExtraFontChars(2, 4);
else {
OLED_DrawChar(' ', 4);
OLED_DrawChar(' ', 4, 0);
}
//Draw in battery symbol if desired
if (systemSettings.cutoutSetting) {
@@ -468,26 +482,26 @@ void DrawUI() {
cellV -= 33; //Should leave us a number of 0-9
if (cellV > 9)
cellV = 9;
OLED_DrawExtendedChar(cellV + 1, 5);
} else {
OLED_DrawChar(' ', 5);
OLED_DrawSymbolChar(cellV + 1, 5);
}
if (systemSettings.displayTempInF) {
OLED_DrawChar('F', 3);
//OLED_DrawChar(SettingTempFChar, 3);
OLED_DrawExtraFontChars(0, 3);
} else {
OLED_DrawChar('C', 3);
//OLED_DrawChar(SettingTempCChar, 3);
OLED_DrawExtraFontChars(1, 3);
}
//Optionally draw the arrows, or draw the power instead
if (systemSettings.powerDisplay) {
//We want to draw in a neat little bar graph of power being pushed to the tip
//ofset 11
uint16_t count = getIronTimer() / (30000 / 28);
uint16_t count = getIronTimer() / (1000 / 28);
if (count > 28)
count = 28;
OLED_DrawWideChar((count), 6);
} else {
//Draw in the arrows if the user has the power display turned off
OLED_BlankSlot(6 * 12 + 16, 24 - 16);//blank out the tail after the arrows
if (getIronTimer() == 0
&& (temp / 10) > (systemSettings.SolderingTemp / 10)) {
//Cooling
@@ -507,12 +521,12 @@ void DrawUI() {
case TEMP_ADJ:
//We are prompting the user to change the temp so we draw the current setpoint temp
//With the nifty arrows
OLED_DrawChar(' ', 0);
OLED_DrawChar('<', 1);
OLED_DrawChar(' ', 0,0);
OLED_DrawChar('<', 1,0);
drawTemp(systemSettings.SolderingTemp, 2, 0);
OLED_DrawChar(' ', 5);
OLED_DrawChar(' ', 7);
OLED_DrawChar('>', 6);
OLED_DrawChar(' ', 5,0);
OLED_DrawChar(' ', 7,0);
OLED_DrawChar('>', 6,0);
break;
case SETTINGS:
//We are prompting the user the setting name
@@ -532,7 +546,7 @@ void DrawUI() {
+ settingsLongTestScrollPos, lengthLeft);
if (lengthLeft < 8)
for (uint8_t i = lengthLeft; i < 8; i++)
OLED_DrawChar(' ', i);
OLED_DrawChar(' ', i, 0);
if (millis() - lastOLEDDrawTime > 120) {
settingsLongTestScrollPos++;
lastOLEDDrawTime = millis();
@@ -541,68 +555,79 @@ void DrawUI() {
settingsLongTestScrollPos = 0;
switch (settingsPage) {
case UVCO:
OLED_DrawString("PWRSC ", 6);
OLED_DrawString(SettingsShortNames[UVCO], 6);
if (systemSettings.cutoutSetting == 0) {
//DC
OLED_DrawChar('D', 6);
OLED_DrawChar('C', 7);
OLED_DrawChar('D', 6, 0);
OLED_DrawChar('C', 7, 0);
} else {
//S count
OLED_DrawChar('2' + systemSettings.cutoutSetting, 6);
OLED_DrawChar('S', 7);
OLED_DrawChar('2' + systemSettings.cutoutSetting, 6, 0);
OLED_DrawChar('S', 7, 0);
}
break;
case SLEEP_TEMP:
OLED_DrawString("STMP ", 5);
OLED_DrawString(SettingsShortNames[SLEEP_TEMP], 5);
OLED_DrawThreeNumber(systemSettings.SleepTemp / 10, 5);
break;
case SLEEP_TIME:
OLED_DrawString("SLTME ", 6);
OLED_DrawTwoNumber(systemSettings.SleepTime, 6);
Clear_Screen();
OLED_DrawString(SettingsShortNames[SLEEP_TIME], 5);
//Draw in the timescale
if (systemSettings.SleepTime < 6) {
OLED_DrawChar('S', 7, 0);
OLED_DrawTwoNumber(systemSettings.SleepTime * 10, 5);
} else {
OLED_DrawChar('M', 7, 0);
OLED_DrawTwoNumber(systemSettings.SleepTime - 5, 5);
}
break;
case SHUTDOWN_TIME:
OLED_DrawString("SHTME ", 6);
OLED_DrawString(SettingsShortNames[SHUTDOWN_TIME], 6);
OLED_DrawTwoNumber(systemSettings.ShutdownTime, 6);
break;
case TEMPDISPLAY:/*Are we showing in C or F ?*/
OLED_DrawString(SettingsShortNames[TEMPDISPLAY], 7);
if (systemSettings.displayTempInF)
OLED_DrawString("TMPUNT F", 8);
OLED_DrawChar(SettingTempFChar, 7, 0);
else
OLED_DrawString("TMPUNT C", 8);
OLED_DrawChar(SettingTempCChar, 7, 0);
break;
case SCREENROTATION:
OLED_DrawString(SettingsShortNames[SCREENROTATION], 7);
switch (systemSettings.OrientationMode) {
case 0:
OLED_DrawString("DSPROT R", 8);
OLED_DrawChar(SettingRightChar, 7, 0);
break;
case 1:
OLED_DrawString("DSPROT L", 8);
OLED_DrawChar(SettingLeftChar, 7, 0);
break;
case 2:
OLED_DrawString("DSPROT A", 8);
OLED_DrawChar(SettingAutoChar, 7, 0);
break;
}
break;
case MOTIONSENSITIVITY:
OLED_DrawString("MSENSE ", 7);
OLED_DrawChar('0' + systemSettings.sensitivity, 7);
OLED_DrawString(SettingsShortNames[MOTIONSENSITIVITY], 7);
OLED_DrawChar('0' + systemSettings.sensitivity, 7,0);
break;
case TEMPROUNDING:
//We are prompting the user about their display mode preferences
{
OLED_DrawString(SettingsShortNames[TEMPROUNDING], 7);
switch (systemSettings.temperatureRounding) {
case ROUNDING_NONE:
OLED_DrawString("TMPRND 1", 8);
OLED_DrawChar('1', 7,0);
break;
case ROUNDING_FIVE:
OLED_DrawString("TMPRND 5", 8);
OLED_DrawChar('5', 7,0);
break;
case ROUNDING_TEN:
OLED_DrawString("TMPRND10", 8);
break;
default:
OLED_DrawString("TMPRND 1", 8);
OLED_DrawChar('X', 7,0);
break;
}
}
@@ -610,45 +635,90 @@ void DrawUI() {
case DISPUPDATERATE:
//We are prompting the user about their display mode preferences
{
OLED_DrawString(SettingsShortNames[DISPUPDATERATE], 7);
switch (systemSettings.displayUpdateSpeed) {
case DISPLAYMODE_FAST:
OLED_DrawString("TMPSPD F", 8);
OLED_DrawChar(SettingFastChar, 7,0);
break;
case DISPLAYMODE_SLOW:
OLED_DrawString("TMPSPD S", 8);
OLED_DrawChar(SettingSlowChar, 7,0);
break;
case DISPLAYMODE_MEDIUM:
OLED_DrawString("TMPSPD M", 8);
OLED_DrawChar(SettingMediumChar, 7,0);
break;
}
}
break;
case BOOSTMODE:
OLED_DrawString(SettingsShortNames[BOOSTMODE], 7);
switch (systemSettings.boostModeEnabled) {
case 1:
OLED_DrawString("BOOST T", 8);
OLED_DrawChar(SettingTrueChar, 7,0);
break;
case 0:
OLED_DrawString("BOOST F", 8);
OLED_DrawChar(SettingFalseChar, 7,0);
break;
}
break;
case BOOSTTEMP:
OLED_DrawString("BTMP ", 5);
OLED_DrawString(SettingsShortNames[BOOSTTEMP], 5);
OLED_DrawThreeNumber(systemSettings.BoostTemp / 10, 5);
break;
case POWERDISPLAY:
OLED_DrawString(SettingsShortNames[POWERDISPLAY], 7);
switch (systemSettings.powerDisplay) {
case 1:
OLED_DrawString("PWRDSP T", 8);
OLED_DrawChar(SettingTrueChar, 7,0);
break;
case 0:
OLED_DrawString("PWRDSP F", 8);
OLED_DrawChar(SettingFalseChar, 7,0);
break;
}
break;
case AUTOSTART:
OLED_DrawString(SettingsShortNames[AUTOSTART], 7);
switch (systemSettings.autoStart) {
case 1:
OLED_DrawChar(SettingTrueChar, 7,0);
break;
case 0:
OLED_DrawChar(SettingFalseChar, 7,0);
break;
case 2:
OLED_DrawChar(SettingSleepChar, 7,0);
break;
}
break;
case COOLINGBLINK:
OLED_DrawString(SettingsShortNames[COOLINGBLINK], 7);
switch (systemSettings.coolingTempBlink) {
case 1:
OLED_DrawChar(SettingTrueChar, 7,0);
break;
case 0:
OLED_DrawChar(SettingFalseChar, 7,0);
break;
}
break;
#ifdef PIDTUNING
case PIDP:
OLED_DrawString("PIDP ", 5);
OLED_DrawThreeNumber(pidSettings.kp, 5);
break;
case PIDI:
OLED_DrawString("PIDI ", 5);
OLED_DrawThreeNumber(pidSettings.ki, 5);
break;
case PIDD:
OLED_DrawString("PIDD ", 5);
OLED_DrawThreeNumber(pidSettings.kd, 5);
break;
#endif
default:
break;
}
}
@@ -656,60 +726,54 @@ void DrawUI() {
case SLEEP:
//The iron is in sleep temp mode
//Draw in temp and sleep
Clear_Screen();
OLED_DrawString("SLP ", 4);
drawTemp(temp, 4, systemSettings.temperatureRounding);
OLED_BlankSlot(84, 96 - 85); //blank out after the temp
if (millis() - getLastMovement() > (10 * 60 * 1000)
&& (millis() - getLastButtonPress() > (10 * 60 * 1000))) {
//OLED off
Oled_DisplayOff();
} else {
Oled_DisplayOn();
}
Oled_DisplayOn();
break;
case COOLING:
//We are warning the user the tip is cooling
OLED_DrawString("COOL ", 5);
Clear_Screen();
OLED_DrawString(CoolingPromptString, 5);
temp = readIronTemp(0, 1, 0xFFFF); //force temp re-reading
drawTemp(temp, 5, systemSettings.temperatureRounding);
if (temp > 500 && systemSettings.coolingTempBlink
&& (millis() % 1000) > 500) {
} else {
drawTemp(temp, 5, systemSettings.temperatureRounding);
}
break;
case UVLOWARN:
OLED_DrawString("LOW VOLT", 8);
OLED_DrawString(UVLOWarningString, 8);
break;
case THERMOMETER:
temp = readIronTemp(0, 1, 0xFFFF); //Force a reading as heater is off
OLED_DrawString("TEMP ", 5);//extra one to it clears the leftover 'L' from IDLE
OLED_DrawString("Temp ", 5);//extra one to it clears the leftover 'L' from IDLE
drawTemp(temp, 5, 0);
break;
case DCINDISP: {
uint16_t voltage = readDCVoltage(systemSettings.voltageDiv); //get X10 voltage
if (StatusFlags == 0 || ((millis() % 1000) > 500)) {
OLED_DrawString("IN", 2);
OLED_DrawChar((voltage / 100) % 10, 2);
OLED_DrawChar(48 + ((voltage / 100) % 10), 2,0);
voltage -= (voltage / 100) * 100;
OLED_DrawChar((voltage / 10) % 10, 3);
OLED_DrawChar(48 + ((voltage / 10) % 10), 3,0);
voltage -= (voltage / 10) * 10;
OLED_DrawChar('.', 4);
OLED_DrawChar(voltage % 10, 5);
OLED_DrawChar('V', 6);
OLED_DrawChar(' ', 7);
OLED_DrawChar('.', 4,0);
OLED_DrawChar(48 + (voltage % 10), 5,0);
OLED_DrawChar('V', 6,0);
OLED_DrawChar(' ', 7,0);
} else {
OLED_DrawString("IN ", 8);
}
}
break;
case TEMPCAL: {
if (StatusFlags == 0) {
OLED_DrawString("CAL TEMP", 8);
} else if (StatusFlags == 1) {
OLED_DrawString("CAL OK ", 8);
} else if (StatusFlags == 2) {
OLED_DrawString("CAL FAIL", 8);
}
OLED_DrawString(TempCalStatus[StatusFlags], 8);
}
break;

View File

@@ -15,6 +15,9 @@
#include "Font.h"
int8_t displayOffset = 32;
uint8_t currentOrientation = 0;
uint8_t displayBuffer[2 * 96]; //This is used to allow us to draw locally before sync'ing to the screen.
/*Setup params for the OLED screen*/
/*http://www.displayfuture.com/Display/datasheet/controller/SSD1307.pdf*/
/*All commands are prefixed with 0x80*/
@@ -43,24 +46,30 @@ u8 OLED_Setup_Array[46] = { /**/
0x80, 0XA6,/*Normal display*/
0x80, 0xAF /*Dispaly on*/
};
uint8_t OLEDOnOffState = 0; //Used to lock out so we dont send it too often
/*
Function: Oled_DisplayOn
Description:Turn on the Oled display
*/
void Oled_DisplayOn(void) {
u8 data[6] = { 0x80, 0X8D, 0x80, 0X14, 0x80, 0XAF };
if (OLEDOnOffState != 1) {
u8 data[6] = { 0x80, 0X8D, 0x80, 0X14, 0x80, 0XAF };
I2C_PageWrite(data, 6, DEVICEADDR_OLED);
I2C_PageWrite(data, 6, DEVICEADDR_OLED);
OLEDOnOffState = 1;
}
}
/*
Function: Oled_DisplayOff
Description:Turn off the Oled display
*/
void Oled_DisplayOff(void) {
u8 data[6] = { 0x80, 0X8D, 0x80, 0X10, 0x80, 0XAE };
if (OLEDOnOffState != 2) {
u8 data[6] = { 0x80, 0X8D, 0x80, 0X10, 0x80, 0XAE };
I2C_PageWrite(data, 6, DEVICEADDR_OLED);
I2C_PageWrite(data, 6, DEVICEADDR_OLED);
OLEDOnOffState = 2;
}
}
/*
@@ -74,7 +83,7 @@ const u8* Data_Command(u8 length, const u8* data) {
//here are are inserting the data write command at the beginning
tx_data[0] = 0x40;
length++;
for (i = 1; i < length; i++) //Loop through the array of data
for (i = 1; i <= length; i++) //Loop through the array of data
{
if (data == 0)
tx_data[i] = 0;
@@ -84,6 +93,14 @@ const u8* Data_Command(u8 length, const u8* data) {
I2C_PageWrite(tx_data, length, DEVICEADDR_OLED); //write out the buffer
return data;
}
//This causes us to write out the buffered screen data to the display
void OLED_Sync() {
Set_ShowPos(0, 0);
Data_Command(96, displayBuffer);
Set_ShowPos(0, 1);
Data_Command(96, displayBuffer + 96);
}
/*******************************************************************************
Function:Set_ShowPos
Description:Set the current position in GRAM that we are drawing to
@@ -103,27 +120,26 @@ void Set_ShowPos(u8 x, u8 y) {
Inputs:(x,y) start point, (width,height) of enclosing rect, pointer to data
Output: pointer to the last byte written out
*******************************************************************************/
const u8* Oled_DrawArea(u8 x0, u8 y0, u8 wide, u8 high, const u8* ptr) {
u8 m, n, y;
n = y0 + high;
if (y0 % 8 == 0)
m = y0 / 8;
else
m = y0 / 8 + 1;
if (n % 8 == 0)
y = n / 8;
else
y = n / 8 + 1;
for (; m < y; m++) {
Set_ShowPos(x0, m);
ptr = Data_Command(wide, ptr);
void Oled_DrawArea(u8 x, u8 y, u8 wide, u8 height, const u8* ptr) {
//We want to blat the given data over the buffer
//X is the left right position (index's through the display buffer)
//Y is the height value (affects the bits)
//Y is either 0 or 8, we dont do smaller bit blatting
u8 lines = height / 8;
//We draw the 1 or two stripes seperately
for (u8 i = 0; i < (wide * lines); i++) {
u8 xp = x + (i % wide);
u8 yoffset = i < wide ? 0 : 96;
if (y == 8)
yoffset = 96;
displayBuffer[xp + yoffset] = ptr[i];
}
return ptr;
}
}
void OLED_InvertBuffer() {
for (uint16_t i = 0; i < (2 * 96); i++)
displayBuffer[i] = ~displayBuffer[i];
}
/*******************************************************************************
Function:GPIO_Init_OLED
Description:Init the outputs as needed for the OLED (in this case the RST line)
@@ -141,6 +157,7 @@ void GPIO_Init_OLED(void) {
Description: Initializes the Oled screen
*******************************************************************************/
void Init_Oled(uint8_t leftHanded) {
currentOrientation = leftHanded;
u8 param_len;
OLED_RST();
@@ -148,16 +165,18 @@ void Init_Oled(uint8_t leftHanded) {
OLED_ACT(); //Toggling reset to reset the oled
delayMs(5);
param_len = 46;
if (leftHanded) {
if (leftHanded == 1) {
OLED_Setup_Array[11] = 0xC8;
OLED_Setup_Array[19] = 0xA1;
displayOffset = 0;
} else {
} else if (leftHanded == 0) {
OLED_Setup_Array[11] = 0xC0;
OLED_Setup_Array[19] = 0x40;
displayOffset = 32;
}
I2C_PageWrite((u8 *) OLED_Setup_Array, param_len, DEVICEADDR_OLED);
for (uint8_t i = 0; i < 2 * 96; i++)
displayBuffer[i] = 0; //turn off screen
}
/*******************************************************************************
@@ -165,52 +184,55 @@ void Init_Oled(uint8_t leftHanded) {
Description:Clear the entire screen to off (black)
*******************************************************************************/
void Clear_Screen(void) {
u8 tx_data[128];
memset(tx_data, 0, 128);
for (u8 i = 0; i < 2; i++) {
Oled_DrawArea(0, i * 8, 128, 8, tx_data);
}
memset(displayBuffer, 0, 96 * 2);
}
/*
* Draws a string onto the screen starting at the left
*/
void OLED_DrawString(const char* string, const uint8_t length) {
for (uint8_t i = 0; i < length; i++) {
OLED_DrawChar(string[i], i);
if (string[i] >= 0x80) {
OLED_DrawChar(string[i + 1], i, string[i]);
i++;
OLED_DrawChar(' ', i,0);
} else
OLED_DrawChar(string[i], i, '\0');
}
}
/*
* Draw a char onscreen at letter index x
*/
void OLED_DrawChar(char c, uint8_t x) {
void OLED_DrawChar(char c, uint8_t x, char preCursor) {
if (x > 7)
return; //clipping
x *= FONT_WIDTH; //convert to a x coordinate
u8* ptr = (u8*) FONT;
if (c >= 'a' && c <= 'z') {
ptr += (c - 'a' + 10) * (FONT_WIDTH * 2); //alpha is ofset 10 chars into the array
} else if (c >= 'A' && c <= 'Z') {
ptr += (c - 'A' + 10) * (FONT_WIDTH * 2); //alpha is ofset 10 chars into the array
} else if (c >= '0' && c <= '9')
ptr += (c - '0') * (FONT_WIDTH * 2);
else if (c < 10)
ptr += (c) * (FONT_WIDTH * 2);
else if (c == ' ') {
//blank on space bar
ptr += (36) * (FONT_WIDTH * 2);
} else if (c == '<') {
ptr += (37) * (FONT_WIDTH * 2);
} else if (c == '>') {
ptr += (38) * (FONT_WIDTH * 2);
} else if (c == '.') {
ptr += (39) * (FONT_WIDTH * 2);
}
x *= FONT_WIDTH; //convert to a x coordinate
u8* ptr;
u16 offset = 0;
if (c < 0x80) {
ptr = (u8*) FONT;
offset = c - ' ';
} else if (preCursor>0) {
ptr = (u8*) FontLatin2;
offset = c - 0xA0+0x40; //this table starts at 0xA0
} else
return; //not in font
offset *= (2 * FONT_WIDTH);
ptr += offset;
Oled_DrawArea(x, 0, FONT_WIDTH, 16, (u8*) ptr);
}
void OLED_DrawExtendedChar(uint8_t id, uint8_t x) {
u8* ptr = (u8*) extendedFont;
void OLED_DrawExtraFontChars(uint8_t id, uint8_t x) {
u8* ptr = (u8*) ExtraFontChars;
ptr += (id) * (FONT_WIDTH * 2);
x *= FONT_WIDTH; //convert to a x coordinate
Oled_DrawArea(x, 0, FONT_WIDTH, 16, (u8*) ptr);
}
void OLED_DrawSymbolChar(uint8_t id, uint8_t x) {
u8* ptr = (u8*) FontSymbols;
ptr += (id) * (FONT_WIDTH * 2);
x *= FONT_WIDTH; //convert to a x coordinate
@@ -236,27 +258,27 @@ void OLED_BlankSlot(uint8_t xStart, uint8_t width) {
*/
void OLED_DrawTwoNumber(uint8_t in, uint8_t x) {
OLED_DrawChar((in / 10) % 10, x);
OLED_DrawChar(in % 10, x + 1);
OLED_DrawChar(48 + (in / 10) % 10, x,0);
OLED_DrawChar(48 + in % 10, x + 1,0);
}
/*
* Draw a 3 digit number to the display at letter slot x
*/
void OLED_DrawThreeNumber(uint16_t in, uint8_t x) {
OLED_DrawChar((in / 100) % 10, x);
OLED_DrawChar((in / 10) % 10, x + 1);
OLED_DrawChar(in % 10, x + 2);
OLED_DrawChar(48 + (in / 100) % 10, x,0);
OLED_DrawChar(48 + (in / 10) % 10, x + 1,0);
OLED_DrawChar(48 + in % 10, x + 2,0);
}
/*
* Draw a 4 digit number to the display at letter slot x
*/
void OLED_DrawFourNumber(uint16_t in, uint8_t x) {
OLED_DrawChar((in / 1000) % 10, x);
OLED_DrawChar((in / 100) % 10, x + 1);
OLED_DrawChar((in / 10) % 10, x + 2);
OLED_DrawChar(in % 10, x + 3);
OLED_DrawChar(48 + (in / 1000) % 10, x,0);
OLED_DrawChar(48 + (in / 100) % 10, x + 1,0);
OLED_DrawChar(48 + (in / 10) % 10, x + 2,0);
OLED_DrawChar(48 + (in % 10), x + 3,0);
}
void OLED_DrawIDLELogo() {
@@ -284,6 +306,8 @@ void OLED_DrawSymbol(uint8_t x, uint8_t symbol) {
}
void OLED_SetOrientation(uint8_t ori) {
if (ori > 1)
return;
if (ori != currentOrientation) {
Init_Oled(ori);
}

View File

@@ -7,38 +7,40 @@
#include "PID.h"
#define MAXPIDOUTPUT 50000
//MAXPIDOUTPUT is the maximum time duration we can support for the irons output, as anything longer than this will be cut off by the next PID iteration
pidSettingsType pidSettings;
//This function computes the new value for the ON time of the system
//This is the return value from this function
int32_t computePID(uint16_t setpoint) {
int32_t ITerm = 0;
static int16_t lastReading = 0;
uint16_t currentReading = readIronTemp(0, 1,setpoint); //get the current temp of the iron
static int32_t ITerm = 0; //Used to store the integral error
static int16_t lastError = 0;
uint16_t currentReading = readIronTemp(0, 1, setpoint); //get the current temp of the iron
int16_t error = (int16_t) setpoint - (int16_t) currentReading; //calculate the error term
ITerm += (pidSettings.ki * error);
if (ITerm > MAXPIDOUTPUT/2)
ITerm = MAXPIDOUTPUT/2;
else if (ITerm < 0)
ITerm = 0; //cap at 0 since we cant force the iron to cool itself :)
int16_t DInput = (error - lastError) / 10; //compute the input to the D term
int16_t DInput = (currentReading - lastReading); //compute the input to the D term
int32_t output = (pidSettings.kp * error) + (ITerm)
ITerm += ((error) / 20);
if (ITerm > 300)
ITerm = 0; //Prevents this accumulating too much during inital heatup
else if (ITerm < 0)
ITerm = 0; //Cap at 0 as we can't force cool
if (DInput > 1000)
DInput = 0;
int32_t output = (pidSettings.kp * error) + (ITerm * pidSettings.ki)
- (pidSettings.kd * DInput);
if (output > MAXPIDOUTPUT)
output = MAXPIDOUTPUT;
else if (output < 0)
output = 0;
lastReading = currentReading; //storing values for next iteration of the loop
lastError = error;
return output;
}
/*Sets up the pid values*/
/*Sets up the pid values to defaults*/
void setupPID(void) {
pidSettings.kp = 15;
pidSettings.ki = 2;
pidSettings.kd = 3;
pidSettings.kp = 8;
pidSettings.ki = 1;
pidSettings.kd = 0; //Not using D atm
}

View File

@@ -38,7 +38,6 @@ void restoreSettings() {
if (systemSettings.version != SETTINGSVERSION) {
//probably not setup
resetSettings();
saveSettings();
}
}
@@ -59,13 +58,13 @@ uint8_t lookupVoltageLevel(uint8_t level) {
void resetSettings() {
systemSettings.SleepTemp = 1500;//Temperature the iron sleeps at - default 150.0 C
systemSettings.SleepTime = 1;//How many minutes we wait until going to sleep - default 1 min
systemSettings.SleepTime = 6;//How many seconds/minutes we wait until going to sleep - default 1 min
systemSettings.SolderingTemp = 3200; //Default soldering temp is 320.0 C
systemSettings.cutoutSetting = 0; //default to no cut-off voltage
systemSettings.version = SETTINGSVERSION;//Store the version number to allow for easier upgrades
systemSettings.displayTempInF = 0; //default to C
systemSettings.OrientationMode = 2; //Default to automatic
systemSettings.sensitivity = 6; //Default high sensitivity
systemSettings.sensitivity = 7; //Default high sensitivity
systemSettings.tempCalibration = 239; //Default to their calibration value
systemSettings.voltageDiv = 144; //Default divider from schematic
systemSettings.ShutdownTime = 30;//How many minutes until the unit turns itself off
@@ -74,6 +73,9 @@ void resetSettings() {
systemSettings.boostModeEnabled = 0;//Default to safe, with no boost mode
systemSettings.BoostTemp = 4000; //default to 400C
systemSettings.powerDisplay = 0; //default to power display being off
systemSettings.autoStart = 0; //Auto start off for safety
systemSettings.coolingTempBlink = 0; //Blink the temperature on the cooling screen when its > 50C
saveSettings();
}
void showBootLogoIfavailable() {
@@ -111,6 +113,6 @@ void showBootLogoIfavailable() {
return;
Oled_DrawArea(0, 0, 96, 16, (uint8_t*) (temp8 + 4));
OLED_Sync();
delayMs(1000);
}

View File

@@ -0,0 +1,186 @@
/*
* Strings.c
*
* Created on: 5Aug.,2017
* Author: Ben V. Brown
*/
#include "Strings.h"
#define LANG_IT
#ifdef LANG_EN
const char* SettingsLongNames[14] = {
/*These are all the help text for all the settings.*/
/*All must start with 6 spaces so they come on screen nicely.*/
" Power source. Sets cutoff voltage. <DC=10V S=3.3V per cell>",
" Sleep Temperature <C>",
" Sleep Timeout <Minutes>",
" Shutdown Timeout <Minutes>",
" Motion Sensitivity <0=Off 1=Least sensitive 9=Most sensitive>",
" Temperature Unit <C=Celsius F=Farnheit>",
" Temperature Rounding Amount <Units>",
" Temperature Display Update Rate <S=Slow M=Medium F=Fast>",
" Display Orientation <A=Automatic L=Left Handed R=Right Handed>",
" Enable front key enters boost mode 450C mode when soldering <T=True F=False>",
" Temperature when in \"boost\" mode <C>",
" Changes the arrows to a power display when soldering <T=True F=False>",
" Automatically starts the iron into soldering on power up. <T=Soldering S=Sleep mode F=Off>",
" Blink the temperature on the cooling screen while the tip is still hot. <T=True F=False>"
};
const char* TempCalStatus[3] = { "Cal Temp", "Cal OK ", "Cal Fail" }; //All fixed 8 chars
const char* UVLOWarningString = "Low Volt"; //Fixed width 8 chars
const char* CoolingPromptString = "Off "; //Fixed width 5 chars
const char SettingTrueChar = 'T';
const char SettingFalseChar = 'F';
const char SettingSleepChar = 'S';
const char SettingFastChar = 'F';
const char SettingMediumChar = 'M';
const char SettingSlowChar = 'S';
const char SettingRightChar = 'R';
const char SettingLeftChar = 'L';
const char SettingAutoChar = 'A';
const char SettingTempCChar = 'C';
const char SettingTempFChar = 'F';
#endif
#ifdef LANG_ES
const char* SettingsLongNames[14] = {
/*These are all the help text for all the settings.*/
/*All must start with 6 spaces so they come on screen nicely.*/
" Fuente de energía. Ajusta el límite inferior de voltaje. <DC=10V S=3.3V por celda>",
" Temperatura en reposo. <C>",
" Tiempo hasta activar reposo. <Minutos>",
" Tiempo hasta apagado. <Minutos>",
" Sensibilidad del movimiento. <0=Apagado 1=El menos sensible 9=El más sensible>",
" Unidad de temperatura.",
" Redondeo de la temperatura.",
" Tasa de actualización de la temperatura.",
" Orientación de la pantalla <A=Automático I=Mano izquierda D=Mano derecha>",
" Activar el botón \"Boost\" en modo soldadura.",
" Temperatura en modo \"Boost\". <C>",
" Cambiar las flechas en pantalla por indicador de potencia en modo soldadura.",
" Iniciar modo soldadura en el encendido. <V=Sí S=Modo reposo F=No>",
" Parpadea la temperatura en el enfriamiento si la punta sigue caliente."
};
const char* TempCalStatus[3] = {"CAL TEMP", "CAL OK ", "CAL FAIL"}; //All fixed 8 chars
const char* UVLOWarningString = "LOW VOLT"; //Fixed width 8 chars
const char* CoolingPromptString = "Cool "; //Fixed width 5 chars
const char SettingTrueChar = 'V';
const char SettingFalseChar = 'F';
const char SettingSleepChar = 'S';
const char SettingFastChar = 'R';
const char SettingMediumChar = 'M';
const char SettingSlowChar = 'L';
const char SettingRightChar = 'D';
const char SettingLeftChar = 'I';
const char SettingAutoChar = 'A';
const char SettingTempCChar = 'C';
const char SettingTempFChar = 'F';
#endif
#ifdef LANG_DE
const char* SettingsLongNames[14] = {
/*These are all the help text for all the settings.*/
/*All must start with 6 spaces so they come on screen nicely.*/
" Stromversorgung. Setzt Abschaltspannung <DC=10V S=3.3V pro Zelle>",
" Ruhetemperatur <C>",
" Ruhemodus nach <Minuten>",
" Abschaltzeit <Minuten>",
" Bewegungsempfindlichkeit <0=Aus 1=Minimal 9=Maximal>",
" Temperatur Einheit",
" Temperatur Runden",
" Temperaturanzeige Updaterate",
" Anzeigerichtung <A=Auto L=Linkshändig R=Rechtshändig>",
" Fronttaste für Temperaturboost einschalten",
" Temperatur im \"boost\"-Modus <C>",
" Ändert \"Temperaturpfeile\" in Leistungsbalken",
" Automatischer Start beim Einschalten. <J=Löttemp R=Ruhemodus N=Aus>",
" Temperatur blinkt beim Abkühlen, solange noch heiß."
};
const char* TempCalStatus[3] = { "Cal Temp", "Cal OK ", "Cal Fehl" }; //All fixed 8 chars
const char* UVLOWarningString = "V gering"; //Fixed width 8 chars
const char* CoolingPromptString = "Kalt "; //Fixed width 5 chars
const char SettingTrueChar = 'J';
const char SettingFalseChar = 'N';
const char SettingSleepChar = 'R';
const char SettingFastChar = 'S';
const char SettingMediumChar = 'M';
const char SettingSlowChar = 'L';
const char SettingRightChar = 'R';
const char SettingLeftChar = 'L';
const char SettingAutoChar = 'A';
const char SettingTempCChar = 'C';
const char SettingTempFChar = 'F';
#endif
#ifdef LANG_FR
const char* SettingsLongNames[14] = {
/*These are all the help text for all the settings.*/
/*All must start with 6 spaces so they come on screen nicely.*/
" Type d\'alimentation. Regle la tension de coupure. <DC=10V S=3.3V par cellules>",
" Temperature en veille. <C>",
" Temps avant mise en veille. <Minutes>",
" Temps avant extinction. <Minutes>",
" Sensibilitee du capteur de mouvement. <0=Inactif 1=Peu sensible 9=Tres sensible>",
" Unitee de temperature.",
" Arrondissement de la temperature.",
" Taux de raffraichissement de la temperature.",
" Orientation de l\'affichage. <A=Automatique G=Gaucher D=Droitier>",
" Active le mode \"Boost\" 450C sur le bouton de devant pendant la soudure.",
" Temperature du mode \"Boost\". <C>",
" Change les fleches en affichage de la tension pendant la soudure.",
" Demarre automatiquement la soudure a l\'allumage. <A=Active, V=Mode Veille, D=Desactive>",
" Fait clignotter la temperature pendant la phase de refroidissement quand la panne est chaude."
};
const char* TempCalStatus[3] = { "Cal Temp", "Cal OK ", "Cal Err " }; //All fixed 8 chars
const char* UVLOWarningString = "Batt Bas"; //Fixed width 8 chars
const char* CoolingPromptString = "Etein"; //Fixed width 5 chars
const char SettingTrueChar = 'A';
const char SettingFalseChar = 'D';
const char SettingSleepChar = 'V';
const char SettingFastChar = 'R';
const char SettingMediumChar = 'M';
const char SettingSlowChar = 'L';
const char SettingRightChar = 'D';
const char SettingLeftChar = 'G';
const char SettingAutoChar = 'A';
const char SettingTempCChar = 'C';
const char SettingTempFChar = 'F';
#endif
#ifdef LANG_IT
const char* SettingsLongNames[14] = {
/*These are all the help text for all the settings.*/
/*All must start with 6 spaces so they come on screen nicely.*/
" Sorgente di alimentazione. Imposta il limite inferiore di tensione. <DC=10V S=3.3V per cella>",
" Temperatura modalità riposo <C>",
" Timeout per passaggio a modalità riposo <Minuti>",
" Timeout spegnimento <Minuti>",
" Sensibilità al movimento <0=Spento 1=Sensibilità minima 9=Sensibilità massima>",
" Unità di temperatura",
" Arrotondamento temperatura",
" Velocità di aggiornamento temperatura",
" Orientamento del display <A=Automatico S=Sinistrorso D=Destrorso>",
" Il tasto anteriore abilita modalità \"boost\" fino a 450C durante la saldatura",
" Temperatura in modalità \"boost\" <C>",
" Visualizza il grafico della potenza assorbita al posto delle frecce",
" Avvia automaticamente il saldatore quando viene alimentato. <S=Modalità saldatura R=Modalità riposo N=Spento>",
" Durante lo spegnimento la temperatura lampeggia sul display finché la punta è calda."
};
const char* TempCalStatus[3] = { "Cal Temp", "Cal OK ", "Cal Err " }; //All fixed 8 chars
const char* UVLOWarningString = "LOW VOLT"; //Fixed width 8 chars
const char* CoolingPromptString = "Cool"; //Fixed width 5 chars
const char SettingTrueChar = 'S';
const char SettingFalseChar = 'N';
const char SettingSleepChar = 'R';
const char SettingFastChar = 'V';
const char SettingMediumChar = 'M';
const char SettingSlowChar = 'L';
const char SettingRightChar = 'D';
const char SettingLeftChar = 'S';
const char SettingAutoChar = 'A';
const char SettingTempCChar = 'C';
const char SettingTempFChar = 'F';
#endif
const char* SettingsShortNames[14] = { "PWRSC ", "STMP ", "STME ", "SHTME ",
"MSENSE ", "TMPUNT ", "TMPRND ", "TMPSPD ", "DSPROT ", "BOOST ",
"BTMP ", "PWRDSP ", "ASTART ", "CLBLNK " };