Jump to content

Jittery output for Altimeter data


lesthegrngo

Recommended Posts

I have just written this sketch, it works on a 128 X 64 OLED module and it just displays the 100ft count for the altimeter as raw output (0 to 65535) on the OLED. And it appears to glitch.

 

Setting a quick flight for takeoff, I used the pressure set wheel on the altimeter to control the baro alt, which has the effect of moving the altimeter 100 ft pointer and digit, and even though it should be a smooth flow of numbers, you can clearly see the numbers jump, to the point where three digits becomes 5 and then back to three in a split second.

 

I had the LCD output running next to it, and that does not glitch

 

These are the sketches I was using

 

 

first the OLED code

 

#define DCSBIOS_DEFAULT_SERIAL

#include <DcsBios.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>

U8G2_SSD1306_128X64_ALT0_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

void setup() {
 
 u8g2.begin();

DcsBios::setup();
}

void onAlt100ftChange(unsigned int newValue) {
 
u8g2.clearBuffer();
 u8g2.setFont(u8g2_font_fub20_tn );
 //u8g2.setTextSize(2);
 u8g2.setCursor(0, 24);
 u8g2.print(newValue);
 u8g2.sendBuffer();

 delay (5);
}
DcsBios::IntegerBuffer alt100ftBuffer(0x107e, 0xffff, 0, onAlt100ftChange);


void loop() {
 DcsBios::loop();

}

 

and the LCD code

 

#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>
#define DCSBIOS_IRQ_SERIAL

#include <DcsBios.h>

LiquidCrystal_PCF8574 lcd(0x27); // set the LCD address to 0x27 for a 16 chars and 2 line display

int show;

void onAlt10000ftCntChange(unsigned int newValue) {
   lcd.setCursor(0, 0);
lcd.print(newValue);
}
DcsBios::IntegerBuffer alt10000ftCntBuffer(0x1080, 0xffff, 0, onAlt10000ftCntChange);

void onAlt1000ftCntChange(unsigned int newValue) {
  lcd.setCursor(7, 0);
lcd.print(newValue);
}
DcsBios::IntegerBuffer alt1000ftCntBuffer(0x1082, 0xffff, 0, onAlt1000ftCntChange);

void onAlt100ftChange(unsigned int newValue) {
   lcd.setCursor(0, 1);
lcd.print(newValue);
}
DcsBios::IntegerBuffer alt100ftBuffer(0x107e, 0xffff, 0, onAlt100ftChange);



void setup() {
lcd.begin(16, 2);
lcd.clear();
DcsBios::setup();


}

void loop() {
DcsBios::loop();
lcd.setBacklight(255);
}

 

So is it possible that the OLED or the OLED library has greater sensitivity and can react to the very fast spurious BIOS output (assuming that that is where the glitch originates?) whereas the LCD system is somehow damped or smoothed?

 

Or is it possible that the way that the Arduino and OLED work together to process the signal has some kind of internal interaction that generates noise in the signal?

 

Edit

 

Here's a video - sorry for the incorrect formatting of the LCD it is left justified rather than right justified so the number stays five digits even when it is back down to three. But you can clearly see the glitching in the OLED readout

 

 

Cheers

 

Les


Edited by lesthegrngo
Link to comment
Share on other sites

47 year-old electronics engineer here. ;)

I'm self-taught with microcontrollers too. Started with PIC microcontrollers, then moved to Arduino.

 

I'm wondering if it's an interruption problem. Driving the OLED probably requires a lot of data to be sent. Maybe that's somehow interfering with the onchange processes.

When the aircraft is flying, far more data flows. The character LCD has far less data to transfer than the OLED, so is less likely to be affected.

I just read the wire library has a 32-byte buffer. The LCD messages would be well withing that, but the OLED would probably go way over.

 

The only thing I can think of right now would be to have one processor to extract the required numbers from the main data flow and send only those numbers to another processor for the display.

I'm not 100% sure how to implement that at the moment, but I'm thinking along the lines of using something like Ian's polling code in a "sub-master" arduino with a software serial output to send the 8 or 10 bytes (2 per digit) to a display arduino, which has no DCS-BIOS running and uses the simple hardware UART receiver to decode the data and then display it as in all the previously-tried sketches.

If the "sub-master" sends all 18 bytes, both displays could share the data as it is "broadcast" and has no handshaking.

 

I'm not sure if both displays could run from the same arduino under these circumstances.

Link to comment
Share on other sites

I have been running the LCD and OLED 'monitors' for the last hour and a half with the aircraft static at the end of the runway.. During that time I have not seen the OLED figure even twitch, it only glitches when the number is changing. Which is even more bizarre because my video from whenever it was I posted it was for similar conditions and clearly shows the display glitching.

 

I think I am going to go ahead and try the concept of getting the sketch to ignore values that are too different from the ones before it, I have nothing to lose but some time - which being on lockdown has given me plenty of. If you know how to ode and splice something like that in, I am all ears!

 

Cheers

 

Les

Link to comment
Share on other sites

I'm shielding at the mo, so I'm putting WAY more time into this than I might otherwise be able to. ;)

 

Anyway...

Back in post #4 I gave this example of comparison code:

pressureDifference = newPressure - oldPressure; // Get the difference
pressureDifference = abs(pressureDifference);   // Make sure the number is positive

if (pressureDifference < pressureDifferenceLimit){
     // Enter your gauge change code here
}
else {  // Insert ignore it code here (if any) 
}

That would compare a single number.

You then have two options:

1) Combine all your digits into one number, then compare to a previous value.

2) Compare each digit to the last value of itself, accounting for change in the next highest, or lowest digit depending on which way the change runs.

 

Having said all that, if the number output to a character LCD is stable, I don't think the comparison idea will help.

It seems as though the source of the numbers is OK, and the problem lies with how they get used.

Link to comment
Share on other sites

Not sure if you're using Middlefart's altimeter code, but I found a bug with the altimeter display part.

 

It's here for reference:

https://forums.eagle.ru/showpost.php?p=4194969&postcount=58

 

While it mostly works well, I noticed the altimeter 10000ft digit only displays the \\\ for 0 and 1.

The service ceiling quoted in Chuck's guide for the A-10 is 45000 feet.

I managed to get one up to 20000ft, and while the onscreen numbers went to 20000, the OLED displayed a blank character and 0000.

 

I've modified the code like this.

Remove this:

 void onAlt10000FtChange(unsigned int newValue)
 {
   if (newValue == 6553)
   {
     oled.digits[0].digit = 1;
     oled.digits[0].y = 0;
   }
   else if (newValue == 0)
   {
     oled.digits[0].digit = -1;
     oled.digits[0].y = 0;
   }
   else
   {
     oled.digits[0].digit = -1;
     oled.digits[0].y = map(newValue, 0, 6553, 0, YPos());
   }
 }

And replace it with this:

  void onAlt10000FtChange(unsigned int newValue)  // Modified to allow more numbers than \\\ and 1
 {
    if (newValue == 0)
   {
     oled.digits[0].digit = -1;
     oled.digits[0].y = 0;
   }
   else
   {
   unsigned int mappedValue = newValue / 6553;
   unsigned int y = map(newValue, mappedValue * 6553, mappedValue * 6553 + 6553, 0, YPos());
 
   oled.digits[0].digit = mappedValue;
   oled.digits[0].y = y;
   }
 }

This now works like the on-screen gauge.

 

I've not solved the glitching yet, but I found this on the way.

 

BTW, it seems the A-10 DOES NOT like flying that high. ;)

Link to comment
Share on other sites

Great, nice spot.

 

I was thinking about this overnight, and am concluding the same as you. I let the game just sit there at the end of the runway with the altimeter OLED display connected plus the LCD altimeter 100ft counter output monitor and the OLED 100ft counter monitor running.

 

The OLED altimeter display was glitching, but there was no simultaneous change to either the LCD or OLED monitors. Both were totally static, and stable. I know that the Baro alt glitching happens much more when you change the values, while the Altimeter display glitches even on stable and static values, but when you fly, the Altimeter glitching is more frequent. So I believe you are correct in that something in the sketch is corrupting the output.

 

Maybe the scrolling part is introducing some random factor, but the curious thing is that the baro alt sketch I have has no scrolling - it simply remaps the value then prints it. There's not too much for it to do with the data, if you see what I mean. Of course, when it glitches, it changes the number rather than showing the number scrolled part way, but maybe that's a clue in itself. It's like the numbers the display is being told to display are being swapped.

 

The puzzler is why that would happen while the input value is static, like when it is on the ground. The non-scrolling baro display is not so sensitive when the altimeter counter is static too, but in the air, despite the baro alt value being static, with changes to the Altimeter it starts glitching. However, due to the fact that it uses the U8G2 protocol, it needs much more memory usage, driving the need for the ATmega328 nanos as the ATmega168 can't load it due to memory issues. I also know that the scrolling sketch needs the larger memory size nano, I think mostly due to the need for the bitmaps for the characters.

 

So is it possible that it is becoming unstable due to memory issues? I tested the scrolling altimeter on a Mega, which has more memory I believe but it still glitched, but maybe it's the way it uses the memory? But why would changing data output for one signal affect another?

 

I'll keep picking away at this, but one thought was to try and use the scrolling sketch, but replace character map with a standard font, and the \\\ with a letter, just to see if lightening the load reduces the glitching.

 

Ian's code for his version appears to uses a single bitmap that displays all the characters in a ribbon, then chooses which part of that ribbon to show, I believe by clipping the image. Maybe a simpler concept?

 

And lastly, I made a simple sketch with the help of the guys on the Arduino forum for the small 64 x 32 OLEDS for the TISL code wheels displays. So far as I have been able to test it, that does not glitch, although the output values from DCS bios are a simpler string of numbers.

 

Food for thought...

 

Les


Edited by lesthegrngo
Link to comment
Share on other sites

Here's the TISL codewheel sketch I discussed above

 

#define DCSBIOS_DEFAULT_SERIAL

#include <DcsBios.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
//#include "XBM.h"     //64x32 XBM format

U8G2_SSD1306_64X32_1F_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

static const unsigned char c24_0[] PROGMEM = {

 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x05, 0x00, 0x00, 0x00,
 0x00, 0x00, 0xC0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x0F, 0x00, 0x00,
 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x17,
 0xFD, 0x3F, 0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0xC0, 0x7F, 0x00, 0x00,
 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00,
 0x00, 0xFC, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xF8, 0x00, 0x00,
 0x00, 0xE0, 0x03, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xE0, 0x03, 0x00,
 0x00, 0xF8, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xF8, 0x01, 0x00,
 0x00, 0xE0, 0x07, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00,
 0x00, 0xFF, 0x00, 0x00, 0x00, 0xE0, 0x3F, 0x00, 0xC0, 0x7F, 0x00, 0x00,
 0x00, 0x80, 0xFF, 0x02, 0xF8, 0x7F, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF,
 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00,
 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF,
 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x07, 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, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};

static const unsigned char c24_1[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x80, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0xFE, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00,
 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xE4, 0xFF, 0x01,
 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0xF0, 0xFF, 0xFF, 0xFF,
 0x00, 0x00, 0x80, 0x0F, 0xF8, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xC0, 0x07,
 0xF8, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xC0, 0x0F, 0xF8, 0xFF, 0xFF, 0xFF,
 0x00, 0x00, 0xE0, 0x07, 0xF0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xF0, 0x07,
 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00,
 0x2F, 0xC0, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01,
 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00,
 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x07, 0x00,
 0x00, 0x00, 0x00, 0x00, 0xD0, 0x7F, 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, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};

static const unsigned char c24_2[] PROGMEM = {
 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x80, 0xFF, 0xFF,
 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 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, 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, 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, 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, 0x00,
 0x00, 0x00, 0x00, 0x00,
};

static const unsigned char c24_3[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
 0xC0, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x07, 0x00,
 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
 0xF8, 0xC3, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x81, 0x3F, 0x00,
 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00,
 0xF8, 0x00, 0x7E, 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0x78, 0x00, 0xFC, 0x00,
 0xFF, 0xFF, 0xFF, 0x0F, 0xFC, 0x00, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0x0F,
 0xF8, 0x00, 0xF0, 0x07, 0xFF, 0xFF, 0xFF, 0x07, 0xF8, 0x01, 0xF0, 0x07,
 0xFF, 0xFF, 0xFF, 0x03, 0xF8, 0x03, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00,
 0xF0, 0x3F, 0xC0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x7F, 0x80, 0xFF,
 0x00, 0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
 0x80, 0x7F, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0xF0,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 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, 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, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};


static const unsigned char c24_4[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x03, 0x00,
 0x00, 0x00, 0xF0, 0x3F, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0xFC, 0x7F,
 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x00, 0x80, 0x0F, 0x00,
 0x00, 0x00, 0xFE, 0xFF, 0x03, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x7E, 0xF8,
 0x03, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x07, 0x80, 0x07, 0x00,
 0x00, 0x00, 0x1F, 0xE0, 0x0F, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x1F, 0x80,
 0x0F, 0x80, 0x07, 0x00, 0x00, 0x80, 0x0F, 0x80, 0x1F, 0x80, 0x0F, 0x00,
 0x00, 0x00, 0x1F, 0x00, 0x3F, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00,
 0x7E, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0xFE, 0xC1, 0x07, 0x00,
 0x00, 0x00, 0x7E, 0x00, 0xFC, 0xC3, 0x0F, 0x00, 0x00, 0x00, 0xFE, 0x07,
 0xF8, 0x8F, 0x07, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0xF0, 0xFF, 0x0F, 0x00,
 0x00, 0x00, 0xF8, 0x0F, 0xE0, 0xFF, 0x07, 0x00, 0x00, 0x00, 0xF0, 0x0F,
 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0xFE, 0x0F, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0xC0, 0x07, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};


static const unsigned char c24_5[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x3D, 0x1F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0xFF,
 0x7F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x00, 0x00, 0x1F,
 0xF0, 0x00, 0xF8, 0xFF, 0xFF, 0x03, 0x80, 0x0F, 0xF0, 0x03, 0xFC, 0xFF,
 0xFF, 0x07, 0x00, 0x1F, 0xF0, 0x07, 0xFC, 0xE1, 0xF0, 0x07, 0x80, 0x0F,
 0xF0, 0x0F, 0xFE, 0x00, 0xE0, 0x0F, 0x00, 0x1F, 0xF0, 0x1F, 0x3E, 0x00,
 0xC0, 0x1F, 0x00, 0x1F, 0xF0, 0x3F, 0x3F, 0x00, 0x80, 0x1F, 0x80, 0x0F,
 0xF0, 0xFF, 0x1F, 0x00, 0x00, 0x3F, 0x00, 0x1F, 0xF0, 0xFF, 0x1F, 0x00,
 0x00, 0xFE, 0x80, 0x0F, 0xF0, 0xFD, 0x1F, 0x00, 0x00, 0xFC, 0x80, 0x1F,
 0xF0, 0xF9, 0x1F, 0x00, 0x00, 0xFC, 0x03, 0x0F, 0xF0, 0xE1, 0x1F, 0x00,
 0x00, 0xF8, 0x07, 0x1F, 0xF0, 0xC0, 0x1F, 0x00, 0x0F, 0xF0, 0x9F, 0x0F,
 0xF0, 0x81, 0x1F, 0x00, 0x1F, 0xC0, 0xFF, 0x0F, 0xF0, 0x01, 0x1F, 0x00,
 0x1F, 0xC0, 0xFF, 0x1F, 0xF0, 0x01, 0x04, 0x00, 0x1F, 0x00, 0xFF, 0x0F,
 0xF0, 0x01, 0x00, 0x80, 0x0F, 0x00, 0xFC, 0x1F, 0xF0, 0x01, 0x00, 0xF0,
 0x00, 0x00, 0xF0, 0x0F, 0xE0, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x80, 0x07,
 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 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, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};


static const unsigned char c24_6[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80,
 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0xFF, 0xFF, 0x01, 0x00,
 0x00, 0x00, 0x7F, 0xC0, 0x1F, 0xFE, 0x03, 0x00, 0x00, 0x00, 0xFF, 0xE0,
 0x0F, 0xF0, 0x03, 0x00, 0x00, 0x00, 0xFF, 0xE1, 0x03, 0xE0, 0x07, 0x00,
 0x00, 0x00, 0xFF, 0xF3, 0x03, 0xC0, 0x07, 0x00, 0x00, 0x00, 0xFF, 0xFF,
 0x01, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0xC0, 0x0F, 0x00,
 0x00, 0x00, 0xDF, 0xFF, 0x01, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x9F, 0xFF,
 0x01, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x1F, 0xFE, 0x01, 0x80, 0x0F, 0x00,
 0x00, 0x00, 0x1F, 0xFC, 0x01, 0x80, 0x07, 0x00, 0x00, 0x00, 0x1F, 0xF8,
 0x01, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0xF0, 0x01, 0xE0, 0x07, 0x00,
 0x00, 0x00, 0x0F, 0x40, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00,
 0x00, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xFF, 0x01, 0x00,
 0x00, 0x00, 0x0E, 0x00, 0x80, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x80, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 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, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};


static const unsigned char c24_7[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xC0, 0x07, 0x00,
 0x00, 0x00, 0x00, 0xF0, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xF0,
 0x00, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xFF, 0xFF, 0x01,
 0x00, 0x00, 0x00, 0xF0, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0xF0,
 0x80, 0x7F, 0xF8, 0x07, 0x00, 0x00, 0xA0, 0xF9, 0xC1, 0x0F, 0xE0, 0x07,
 0x00, 0x00, 0xF8, 0xFF, 0xE3, 0x0F, 0xC0, 0x0F, 0x00, 0x00, 0xF8, 0xFF,
 0xE7, 0x07, 0x80, 0x0F, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x03, 0x80, 0x0F,
 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x03, 0x80, 0x1F, 0x00, 0x00, 0x60, 0xF9,
 0xFF, 0x03, 0x00, 0x1F, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x03, 0x00, 0x1F,
 0xC0, 0x00, 0x00, 0xF0, 0xFC, 0x03, 0x00, 0x1F, 0xF0, 0x07, 0x00, 0xF0,
 0xF8, 0x03, 0x80, 0x0F, 0xF0, 0x3F, 0x00, 0xF0, 0xF0, 0x03, 0x80, 0x0F,
 0xF0, 0xFF, 0x01, 0xF0, 0xE0, 0x03, 0xC0, 0x0F, 0xE0, 0xFF, 0x0F, 0xF0,
 0x80, 0x00, 0xE0, 0x0F, 0x80, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xF0, 0x07,
 0x00, 0xFC, 0xFF, 0xF3, 0x00, 0x00, 0xFE, 0x03, 0x00, 0xE0, 0xFF, 0xFF,
 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00,
 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x80, 0xFF,
 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};


static const unsigned char c24_8[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x80, 0xE6, 0xAF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0,
 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x03, 0x00,
 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xE0,
 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xD5, 0x5F, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
 0xC0, 0x0F, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x80, 0x07, 0x00, 0x00,
 0x00, 0xC0, 0xFF, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x07,
 0xC0, 0x07, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x3F, 0xC0, 0x07, 0x00, 0x00,
 0x00, 0x00, 0xFE, 0xFF, 0xC1, 0x07, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
 0xCF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00,
 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x80, 0x03, 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, 0x00,
};


static const unsigned char c24_9[] PROGMEM = {
 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, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x3F,
 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x1F, 0x00,
 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0xF8, 0xFF,
 0x00, 0x65, 0xBF, 0x01, 0x30, 0x00, 0xFC, 0xFF, 0x80, 0xFF, 0xFF, 0x07,
 0x78, 0x00, 0xFE, 0xE0, 0x80, 0xFF, 0xFF, 0x0F, 0xF8, 0x00, 0x3F, 0x00,
 0x80, 0xFF, 0xFF, 0x0F, 0x78, 0x00, 0x3F, 0x00, 0x80, 0xFF, 0xFF, 0x07,
 0xF8, 0x00, 0x1F, 0x00, 0x00, 0x59, 0x7F, 0x02, 0xF8, 0x80, 0x0F, 0x00,
 0x00, 0x00, 0x1F, 0x00, 0xF8, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x1F, 0x00,
 0xF8, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x78, 0x80, 0x0F, 0x00,
 0x03, 0x00, 0x3F, 0x00, 0xF8, 0x80, 0x0F, 0x00, 0x1F, 0x00, 0x1E, 0x00,
 0xF8, 0x80, 0x0F, 0x00, 0xFF, 0x00, 0x1F, 0x00, 0xF8, 0x48, 0x1F, 0x00,
 0xFF, 0x0F, 0x1F, 0x00, 0xF8, 0xFF, 0x3F, 0x00, 0xFF, 0x7F, 0x3F, 0x00,
 0xF8, 0xFF, 0x3F, 0x80, 0xFE, 0xFF, 0x1F, 0x00, 0xF8, 0xFF, 0x3F, 0xC0,
 0xF0, 0xFF, 0x1F, 0x00, 0xF8, 0xFF, 0x3F, 0xC0, 0x00, 0xFF, 0x1F, 0x00,
 0x80, 0x59, 0x05, 0xC0, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x80,
 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 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,
 0x00, 0x00, 0x00, 0x00,
};


static const unsigned char c24_10[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0x00,
 0x00, 0x00, 0x06, 0xC0, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x1F, 0xC0,
 0x1F, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x1F, 0xE0, 0x0F, 0xF0, 0x03, 0x00,
 0x00, 0x00, 0x1F, 0xE0, 0x07, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0xE0,
 0x03, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x01, 0x80, 0x0F, 0x00,
 0x00, 0x00, 0x1F, 0xF0, 0x01, 0x80, 0x07, 0x00, 0x00, 0x00, 0x1F, 0xF0,
 0x01, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x1F, 0xF0, 0x01, 0x80, 0x0F, 0x00,
 0x00, 0x00, 0x1F, 0xF0, 0x01, 0x80, 0x07, 0x00, 0x00, 0x00, 0x1F, 0xF0,
 0x03, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x1F, 0xF4, 0x03, 0xC0, 0x07, 0x00,
 0x00, 0x00, 0xFF, 0xFF, 0x07, 0xE0, 0x07, 0x00, 0x00, 0x00, 0xFF, 0xFF,
 0x07, 0xF0, 0x03, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x07, 0xF8, 0x03, 0x00,
 0x00, 0x00, 0xFF, 0xFF, 0x07, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x98, 0x9A,
 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 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, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};


static const unsigned char c24_11[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x09, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0xC0, 0xFF,
 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x00, 0xFE, 0x7F, 0x00,
 0x00, 0x00, 0xF8, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC, 0xFF,
 0xC0, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xFE, 0xF7, 0xC0, 0x1F, 0xF8, 0x03,
 0x30, 0x00, 0x7E, 0x80, 0xE0, 0x0F, 0xF0, 0x03, 0xF8, 0x00, 0x3F, 0x00,
 0xE0, 0x03, 0xC0, 0x07, 0xF8, 0x00, 0x1F, 0x00, 0xE0, 0x03, 0xC0, 0x07,
 0xF8, 0x01, 0x1F, 0x00, 0xF0, 0x01, 0xC0, 0x0F, 0xF0, 0x03, 0x1F, 0x00,
 0xF0, 0x01, 0x80, 0x07, 0xF0, 0x87, 0x0F, 0x00, 0xF0, 0x01, 0x80, 0x0F,
 0xE0, 0x8F, 0x0F, 0x00, 0xF0, 0x01, 0x80, 0x0F, 0xC0, 0x9F, 0x0F, 0x00,
 0xF0, 0x01, 0x80, 0x07, 0x80, 0x7F, 0x1F, 0x00, 0xF0, 0x01, 0xC0, 0x0F,
 0x00, 0xFF, 0x1F, 0x00, 0xE0, 0x03, 0xC0, 0x07, 0x00, 0xFE, 0x3F, 0x00,
 0xFF, 0x07, 0xE0, 0x07, 0x00, 0xFC, 0x7F, 0x80, 0xFF, 0x07, 0xF0, 0x03,
 0x00, 0xF0, 0xFF, 0xC0, 0xFF, 0x07, 0xF8, 0x03, 0x00, 0xE0, 0xFF, 0xFF,
 0xFF, 0x07, 0xF8, 0x01, 0x00, 0x80, 0xFF, 0xFF, 0x99, 0x02, 0xF8, 0x00,
 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xF8, 0xFF,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7F, 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, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};


static const unsigned char c24_12[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x01, 0x00,
 0x00, 0x00, 0x00, 0xC0, 0x7F, 0xFD, 0x03, 0x00, 0x00, 0x00, 0x04, 0xC0,
 0x0F, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x1F, 0xE0, 0x07, 0xE0, 0x07, 0x00,
 0x00, 0x00, 0x1F, 0xE0, 0x03, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x3F, 0xE0,
 0x03, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x7E, 0xE0, 0x03, 0xC0, 0x07, 0x00,
 0x00, 0x00, 0xFE, 0xF0, 0x01, 0x80, 0x0F, 0x00, 0x00, 0x00, 0xFC, 0xF1,
 0x01, 0x80, 0x0F, 0x00, 0x00, 0x00, 0xF8, 0xE3, 0x01, 0xC0, 0x0F, 0x00,
 0x00, 0x00, 0xF0, 0xFF, 0x03, 0x80, 0x07, 0x00, 0x00, 0x00, 0xE0, 0xFF,
 0x03, 0xC0, 0x07, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x07, 0xE0, 0x07, 0x00,
 0x00, 0x00, 0x80, 0xFF, 0x0F, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0xFE,
 0x1F, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x01, 0x00,
 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xC0,
 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 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, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};


static const unsigned char c24_13[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0xFC, 0xFF, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x01,
 0xF0, 0x07, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0xF0, 0x3F, 0x00, 0x00,
 0x80, 0xFF, 0xFD, 0x07, 0xF0, 0xFF, 0x03, 0x00, 0x80, 0x1F, 0xE0, 0x07,
 0xF0, 0xFF, 0x1F, 0x00, 0xC0, 0x0F, 0xC0, 0x0F, 0xF0, 0xFF, 0xFF, 0x00,
 0xC0, 0x07, 0x80, 0x0F, 0xF0, 0xF9, 0xFF, 0x07, 0xE0, 0x07, 0x80, 0x0F,
 0xF0, 0xE1, 0xFF, 0x3F, 0xC0, 0x07, 0x80, 0x1F, 0xF0, 0x01, 0xFF, 0xFF,
 0xE1, 0x03, 0x00, 0x1F, 0xF0, 0x01, 0xF0, 0xFF, 0xE3, 0x03, 0x00, 0x1F,
 0xF0, 0x01, 0x80, 0xFF, 0xE7, 0x03, 0x00, 0x1F, 0xF0, 0x01, 0x00, 0xFC,
 0xDF, 0x07, 0x80, 0x0F, 0xF0, 0x01, 0x00, 0xE0, 0xFF, 0x07, 0x80, 0x0F,
 0xF0, 0x01, 0x00, 0x00, 0xFF, 0x0F, 0xC0, 0x0F, 0xF0, 0x01, 0x00, 0x00,
 0xFF, 0x1F, 0xE0, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0xF8, 0x07,
 0xF0, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x03, 0xF0, 0x01, 0x00, 0x00,
 0xE0, 0xFF, 0xFF, 0x03, 0xF0, 0x01, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x00,
 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0xC0, 0x0F, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};



static const unsigned char c24_14[] PROGMEM = {
 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, 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, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7F, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x80, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00,
 0x00, 0x80, 0xCF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0F, 0xFE,
 0xFF, 0x03, 0x00, 0x00, 0x00, 0x80, 0x0F, 0xF8, 0xFF, 0x0F, 0x00, 0x00,
 0x00, 0x80, 0x0F, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x0F, 0x00,
 0xFC, 0xFF, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0xE0, 0xFF, 0x07, 0x00,
 0x00, 0x80, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0x80, 0x0F, 0x00,
 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xC0, 0x03, 0x00,
 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0F, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 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,
 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, 0x00, 0x00, 0x00,
};


static const unsigned char c24_15[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80,
 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0xFC, 0x01, 0x00, 0x00, 0x00,
 0x00, 0xFE, 0x1F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xBF, 0xFF,
 0xFF, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00,
 0xC0, 0xBF, 0xFF, 0x7F, 0xFF, 0x3F, 0x00, 0x00, 0xC0, 0x0F, 0xFC, 0x0F,
 0xFF, 0xFF, 0x01, 0x00, 0xE0, 0x07, 0xF8, 0x03, 0xF0, 0xFF, 0x0F, 0x00,
 0xE0, 0x03, 0xF0, 0x03, 0xC0, 0xFF, 0x7F, 0x00, 0xE0, 0x03, 0xF0, 0x03,
 0x00, 0xFC, 0xFF, 0x07, 0xE0, 0x03, 0xF0, 0x01, 0x00, 0xE0, 0xFF, 0x1F,
 0xE0, 0x03, 0xF0, 0x01, 0x00, 0x00, 0xFF, 0x3F, 0xE0, 0x03, 0xF0, 0x03,
 0x00, 0x00, 0xF8, 0x3F, 0xE0, 0x07, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x1F,
 0xC0, 0x07, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x1E, 0xC0, 0x1F, 0xFE, 0x0F,
 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
 0x80, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0xFF,
 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00,
 0x00, 0xF8, 0x07, 0xF8, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};



static const unsigned char c24_16[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
 0x00, 0x00, 0xF0, 0x3F, 0xF0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F,
 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFE, 0xFF, 0x00, 0x00,
 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFD,
 0xFF, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x1F, 0xF8, 0x03, 0x00,
 0x00, 0x80, 0x1F, 0xE0, 0x0F, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x1F, 0xC0,
 0x0F, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0xC0, 0x0F, 0xE0, 0x07, 0x00,
 0x00, 0x80, 0x0F, 0xC0, 0x07, 0xC0, 0x07, 0x00, 0x00, 0x80, 0x0F, 0xC0,
 0x07, 0xC0, 0x07, 0x00, 0x00, 0x80, 0x0F, 0xC0, 0x0F, 0xE0, 0x07, 0x00,
 0x00, 0x80, 0x1F, 0xC0, 0x0F, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x1F, 0xE0,
 0x1F, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x7F, 0xF8, 0x3F, 0xF8, 0x03, 0x00,
 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0xFE, 0xFF,
 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFC, 0x7F, 0x00, 0x00,
 0x00, 0x00, 0xF0, 0x7F, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F,
 0xC0, 0x0F, 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, 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,
};


static const unsigned char c24_17[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x50, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xFE, 0x07, 0x00,
 0x3F, 0xF0, 0x1F, 0x00, 0x80, 0xFF, 0x1F, 0x00, 0x7F, 0xF8, 0x3F, 0x00,
 0xC0, 0xFF, 0xFF, 0x00, 0xFF, 0xFE, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x01,
 0xFF, 0xFF, 0xFF, 0x01, 0xF0, 0x9F, 0xFF, 0x07, 0xFD, 0xFF, 0xFE, 0x01,
 0xF0, 0x03, 0xFC, 0x0F, 0xF0, 0x1F, 0xF0, 0x03, 0xF8, 0x01, 0xF8, 0x3F,
 0xE0, 0x1F, 0xE0, 0x03, 0xF8, 0x00, 0xF0, 0x7F, 0xC0, 0x0F, 0xE0, 0x03,
 0xF8, 0x00, 0xF0, 0xFF, 0xC0, 0x0F, 0xE0, 0x07, 0x7C, 0x00, 0xF0, 0xFF,
 0xC0, 0x07, 0xC0, 0x07, 0x7C, 0x00, 0xE0, 0xFB, 0xC0, 0x07, 0xC0, 0x07,
 0x7C, 0x00, 0xE0, 0xF3, 0xC0, 0x0F, 0xC0, 0x07, 0xFC, 0x00, 0xE0, 0xE3,
 0xC0, 0x0F, 0xE0, 0x03, 0x7C, 0x00, 0xF0, 0xC1, 0xE0, 0x1F, 0xF0, 0x03,
 0xFC, 0x00, 0xF0, 0xC1, 0xF8, 0x3F, 0xF8, 0x03, 0xF8, 0x01, 0xF8, 0x81,
 0xFF, 0xFF, 0xFF, 0x01, 0xF8, 0x01, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0x00,
 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xFC, 0x7F, 0x00, 0xE0, 0xFF, 0x7F, 0x00,
 0x7F, 0xF8, 0x3F, 0x00, 0xC0, 0xFF, 0x3F, 0x00, 0x0F, 0xE0, 0x0F, 0x00,
 0x80, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x03, 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, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};

static const unsigned char c24_18[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x1F, 0x00, 0x00, 0x00,
 0x00, 0x00, 0xFF, 0xF9, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0,
 0xFF, 0x01, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x80, 0xFF, 0x03, 0x00, 0x00,
 0x00, 0x80, 0x0F, 0x00, 0xFF, 0x07, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00,
 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0xFE, 0x1F, 0x00, 0x00,
 0x00, 0x80, 0x07, 0x00, 0xBE, 0x3F, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00,
 0x3E, 0x3F, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x3F, 0x7E, 0x00, 0x00,
 0x00, 0xC0, 0x07, 0x00, 0x1E, 0xFC, 0x00, 0x00, 0x00, 0x80, 0x0F, 0x00,
 0x3F, 0xFC, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x80, 0x1F, 0xF8, 0x01, 0x00,
 0x00, 0x80, 0x1F, 0xC0, 0x0F, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x7F, 0xE0,
 0x0F, 0xF0, 0x03, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x07, 0xE0, 0x03, 0x00,
 0x00, 0x00, 0xFE, 0xFF, 0x03, 0xC0, 0x01, 0x00, 0x00, 0x00, 0xF8, 0xFF,
 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x80, 0x1F, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};


static const unsigned char c24_19[] PROGMEM = {
 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00,
 0xFF, 0x03, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x1F, 0xFF, 0x0F, 0x00, 0x00,
 0x00, 0xFE, 0xFF, 0x7F, 0xFF, 0x3F, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF,
 0xF3, 0xFF, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0x01, 0x00,
 0xE0, 0xFF, 0xA1, 0xFF, 0x00, 0xFF, 0x07, 0x00, 0xF0, 0x1F, 0x00, 0xF0,
 0x00, 0xFE, 0x0F, 0x00, 0xF8, 0x03, 0x00, 0xC0, 0x00, 0xFE, 0x1F, 0x00,
 0xF8, 0x01, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0xFC, 0x00, 0x00, 0x00,
 0x00, 0x7C, 0x7F, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7E, 0x00,
 0x7C, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xFC, 0x00, 0xFC, 0x00, 0x00, 0x00,
 0x00, 0x7E, 0xF8, 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3E, 0xF8, 0x01,
 0xF8, 0x03, 0x00, 0xC0, 0x00, 0x3F, 0xF0, 0x03, 0xF8, 0x07, 0x00, 0xF0,
 0x80, 0x1F, 0xE0, 0x07, 0xF0, 0xBF, 0x00, 0xFE, 0xC0, 0x1F, 0xE0, 0x07,
 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xC0, 0x07, 0xC0, 0xFF, 0xFF, 0xFF,
 0xFF, 0x07, 0x80, 0x03, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x01,
 0x00, 0xF8, 0xFF, 0x1F, 0xFF, 0x01, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x01,
 0x7F, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00,
};

const unsigned char* aBitmaps[] = {  //array of pointers to PROGMEM
   c24_0, c24_1, c24_2, c24_3, c24_4, c24_5, c24_6, c24_7, c24_8,
   c24_9, c24_10, c24_11, c24_12, c24_13, c24_14, c24_15, c24_16,
   c24_17, c24_18, c24_19
};

void onTislCode2Change(unsigned int newValue)         //simpler with array index
{
   u8g2.clearBuffer();
   u8g2.drawXBMP( 0, 0, 64, 32, aBitmaps[newValue]); //direct from PROGMEM
   u8g2.sendBuffer();
}
DcsBios::IntegerBuffer tislCode2Buffer(0x111a, 0x1f00, 8, onTislCode2Change);

void setup()
{
   u8g2.begin();
   DcsBios::setup();
}

void loop()
{
   DcsBios::loop();
}

 

As far as I can tell this does not glitch.

 

I also modified Middlefart's scrolling sketch to do the fuel quantity display, and also the left fuel gauge - I know that the scrolling sketch slows down the gauge update speed terribly, but for the fuel gauge that isn't important

 

#define DCSBIOS_DEFAULT_SERIAL

#include <AccelStepper.h>
#include "DcsBios.h"

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "charactersbak.h"

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)

//Comment for barometric pressure
#define ALTIMETER

int updateInterval = 100; //the number of milliseconds between updates

struct scrollDigit {
 int digit; //The digit that is displayed
 int y; // The vertical position of the digit
};

struct disp {
 Adafruit_SSD1306 display;
 int width;
 int numberOfDigits;
 scrollDigit digits[5];
};


 disp oled = {Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET), 24, 5, {{0,0},{0,0},{0,0},{0,0},{0,0}}};


struct StepperConfig {
 unsigned int maxSteps;
 unsigned int acceleration;
 unsigned int maxSpeed;
};


class Vid29Stepper : public DcsBios::Int16Buffer {
 private:
   AccelStepper& stepper;
   StepperConfig& stepperConfig;
   unsigned int (*map_function)(unsigned int);
   unsigned char initState;
 public:
   Vid29Stepper(unsigned int address, AccelStepper& stepper, StepperConfig& stepperConfig, unsigned int (*map_function)(unsigned int))
   : Int16Buffer(address), stepper(stepper), stepperConfig(stepperConfig), map_function(map_function), initState(0) {
   }

   virtual void loop() {
     if (initState == 0) { // not initialized yet
       stepper.setMaxSpeed(stepperConfig.maxSpeed);
       stepper.setAcceleration(stepperConfig.acceleration);
       stepper.moveTo(-((long)stepperConfig.maxSteps));
       initState = 1;
     }
     if (initState == 1) { // zeroing
       stepper.run();
       if (stepper.currentPosition() <= -((long)stepperConfig.maxSteps)) {
        stepper.setCurrentPosition(0);
         initState = 2;
         stepper.moveTo(stepperConfig.maxSteps/2);
       }
     }
     if (initState == 2) { // running normally
       if (hasUpdatedData()) {
         unsigned int newPosition = map_function(getData());
         newPosition = constrain(newPosition, 0, stepperConfig.maxSteps);
         stepper.moveTo(newPosition);
       }
       stepper.run();
     }
   }
};


struct StepperConfig stepperConfig = {
 600,  // maxSteps
 1000, // maxSpeed
 1000 // acceleration
 };


AccelStepper stepper(AccelStepper::DRIVER, 10, 11);


Vid29Stepper lHydPressBuffer(0x10c2, stepper, stepperConfig, [](unsigned int newValue) -> unsigned int {
 
 return map(newValue, 65535, 0, 0, stepperConfig.maxSteps);
}); 

void setup() {
 if(!oled.display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
   for(;;); // Don't proceed, loop forever
 }

 DcsBios::setup();
}

void UpdateDisplay()
{
 oled.display.clearDisplay();
 for (int i = 0; i < oled.numberOfDigits; i++)
 {
   printScrollingDigit(oled.digits[i].digit, oled.width, oled.digits[i].y, i + 1, &oled);
 }

 if (oled.width == 16)
 {
   oled.display.fillRect(0, 25, 67, 7, BLACK);
 }
 
 oled.display.display();
}

int YPos()
{
 return (oled.width + 9) * -1;
}

void printScrollingDigit(int digit, int width, int y, int pos, disp *oled)
{
 int x = (width * pos) - width + pos;
#ifdef ALTIMETER
   switch (digit)
   {
     case -1: oled->display.drawBitmap(x, y, c24_Empty, 24, 32, 1); oled->display.drawBitmap(x, y+33, c24_1, 24, 32, 1); break;
     case 1: oled->display.drawBitmap(x, y, c24_1, 24, 32, 1); oled->display.drawBitmap(x, y+33, c24_2, 24, 32, 1); break;
     case 2: oled->display.drawBitmap(x, y, c24_2, 24, 32, 1); oled->display.drawBitmap(x, y+33, c24_3, 24, 32, 1); break;
     case 3: oled->display.drawBitmap(x, y, c24_3, 24, 32, 1); oled->display.drawBitmap(x, y+33, c24_4, 24, 32, 1); break;
     case 4: oled->display.drawBitmap(x, y, c24_4, 24, 32, 1); oled->display.drawBitmap(x, y+33, c24_5, 24, 32, 1); break;
     case 5: oled->display.drawBitmap(x, y, c24_5, 24, 32, 1); oled->display.drawBitmap(x, y+33, c24_6, 24, 32, 1); break;
     case 6: oled->display.drawBitmap(x, y, c24_6, 24, 32, 1); oled->display.drawBitmap(x, y+33, c24_7, 24, 32, 1); break;
     case 7: oled->display.drawBitmap(x, y, c24_7, 24, 32, 1); oled->display.drawBitmap(x, y+33, c24_8, 24, 32, 1); break;
     case 8: oled->display.drawBitmap(x, y, c24_8, 24, 32, 1); oled->display.drawBitmap(x, y+33, c24_9, 24, 32, 1); break;
     case 9: oled->display.drawBitmap(x, y, c24_9, 24, 32, 1); oled->display.drawBitmap(x, y+33, c24_0, 24, 32, 1); break;
     default: oled->display.drawBitmap(x, y, c24_0, 24, 32, 1); oled->display.drawBitmap(x, y+33, c24_1, 24, 32, 1); break;
   }

   
#endif
}

#ifdef ALTIMETER


 void onfuelQty10000change(unsigned int newValue)
 {
   unsigned int mappedValue = newValue / 6553;
   unsigned int y = map(newValue, mappedValue * 6553, mappedValue * 6553 + 6553, 0, YPos());
 
   oled.digits[0].digit = mappedValue;
   oled.digits[0].y = y;
   }

 
 void onfuelQty1000change(unsigned int newValue)
 {
   unsigned int mappedValue = newValue / 6553;
   unsigned int y = map(newValue, mappedValue * 6553, mappedValue * 6553 + 6553, 0, YPos());
 
   oled.digits[1].digit = mappedValue;
   oled.digits[1].y = y;
 }
 
 void onfuelQty100change(unsigned int newValue)
 {
   unsigned int mappedValue = newValue / 6553;
   unsigned int y = map(newValue, mappedValue * 6553, mappedValue * 6553 + 6553, 0, YPos());
 
   oled.digits[2].digit = mappedValue;
   oled.digits[2].y = y;
 }
 
 DcsBios::IntegerBuffer fuelQty10000Buffer(0x10ce, 0xffff, 0, onfuelQty10000change);
 DcsBios::IntegerBuffer fuelQty1000Buffer(0x10d0, 0xffff, 0, onfuelQty1000change);
 DcsBios::IntegerBuffer fuelQty100Buffer(0x10d2, 0xffff, 0, onfuelQty100change);
#else

#endif

unsigned long time = 0;

void loop() {
 DcsBios::loop();

 time = millis();
 if (time % updateInterval == 0)
 {
   UpdateDisplay();
 }
}

 

While this has the occasional glitch, it is nowhere near as bad as the altimeter pair.

 

I put these in for you to try (if you have the hardware) and see if you can replicate what I'm seeing

 

Cheers

 

Les

Link to comment
Share on other sites

Another update - this is bugging me and it's become a bit obsessive I'm afraid!

 

I made another instance of the Baro Alt display, but this time using a Mega, so basically two identical sketches pulling from the same source, the only difference being the use of a Mega rather than a Nano. My reasoning was maybe it would eliminate memory constraints.

 

In flight, they both glitch, but here's the thing - they glitch differently, at different times and totally out of synch.

 

I did the same for the Altimeter scrolling display - same result, both glitching but in different ways at different times.

 

So whatever is happening, it's happening inside the Arduino and OLED

 

Not sure where we go from here.....

 

Les

Link to comment
Share on other sites

Yeah. I can't let it go either. :geek:

 

I'm in the process of writing the code for my "submaster"/slave idea. That's how I found the bug with Middlefart's code.

 

I put in some test numbers to initialise the display, and got a blank space. Then I went bug-hunting. :D

 

I've got the first version of the slave receiver code sorted. Only 32-line, though. I've not got a 64 line to try yet.

It runs the display properly, but I've not built a transmitter to send numbers to it yet. That's next.

 

I'm going to build a standalone transmitter first, then see about getting the data from DCS-BIOS.

Link to comment
Share on other sites

I just hope that the dreaded RS485 system doesn't creep into this ....!

 

Good luck, I will help with what I can but the coding is beyond my skills. However I do have an abundance of hardware, so can test things if you give me the info

 

Cheers

 

Les

Link to comment
Share on other sites

hmmm. I tested without the fancy font/bitmaps and without scrolling/rolling (just printing the mapped value using println) and still got the jitters.

 

I don't think its a problem with the OLED not keeping up with the data being pushed to it, rather something funny going on with the data itself, either the mapped values goes totally bonkers or DCS Bios sends strange values. My bet is on my code :-)

 

I'll keep testing

Link to comment
Share on other sites

It just struck me. I’ve seen this kind of behavior before in another sketch and without any oleds or I2C.

 

When I was testing a stepper motor for the altimeter everything was working as it should except for once in a while where the motor all of a sudden would jerk and move the needle to completely the wrong position and then move back again to the correct position.

That could be caused of an invalid value from DCS bios (or DCS).

 

Im not sure if I got to the bottom of it or if it’s still a problem. That was just on a test board which has been torn apart so I can’t check it. I’ll try to find the sketch however, I should have that somewhere.

 

I’ll also try to do some logging of the raw data that the arduino gets and check if all looks good there.

Link to comment
Share on other sites

I certainly don't want to put you off doing an empiric test, especially if you are able to actually record the data output from DCS, as it would clear up once an for all whether it was a corrupted DCS data stream or not. We'd certainly appreciate the help and feedback,

 

However, I did some tests with a number of things, including a monitor that showed me the DCS output and it appeared, at least visually, to be stable, which is why we are suspecting the interaction within the Arduino. But with the limited knowledge I have, it may be that it wasn't up to scratch.

 

As for the gauge jittering, I have encountered that before too, on other sketches. One was traced to a dry joint on a stepper motor, which for all the world looked like a perfect joint, but in reality was an intermittent contact. Another couple were with the EasyDriver boards, which when swapped for another board cured the problem - whether it was a contact in the headers or a problem with the EasyDriver itself, I can't say for sure, but I started swapping to A4988 driver boards and found them to be more reliable, more robust, and also give a much smoother gauge action. All the jittery gauges have been eliminated by hardware fixes.

 

But it's not impossible that the DCS output is at least contributory so we welcome anything you can find out.

 

Cheers for the assistance, it's appreciated!

 

Les

Link to comment
Share on other sites

My progress so far:

I have a test transmitter running a software serial port transmitter, sending data to an arduino with the hardware receiver and the OLED.

The display receiver is responding to the transmitter, but the wrong digits.:doh:

 

One REALLY puzzling thing is that I grafted Middlefart's display code onto my serial receiver, and the "baro" option doesn't work, but the "altimeter" does. :confused:

If I comment out the serial receiver code, the default baro data works properly! :confused::confused:

But that's a problem to look at after getting the altimeter working properly first.

Link to comment
Share on other sites

maybe it would be best to start with a non scrolling sketch, like this one?

 

#define DCSBIOS_DEFAULT_SERIAL

#include <DcsBios.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>

//U8G2_SSD1306_128X64_ALT0_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
U8G2_SSD1306_64X32_1F_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);


char* displayString = "----";


DcsBios::Int16Buffer altPressure0Buffer(0x1086);
DcsBios::Int16Buffer altPressure1Buffer(0x1088);
DcsBios::Int16Buffer altPressure2Buffer(0x108a);
DcsBios::Int16Buffer altPressure3Buffer(0x108c);

void setup() {
 
 u8g2.begin();

DcsBios::setup();
}


void loop() {
 DcsBios::loop();

 

 if (altPressure0Buffer.hasUpdatedData()) { displayString[3] = mapeo(altPressure0Buffer.getData()); }
 if (altPressure1Buffer.hasUpdatedData()) { displayString[2] = mapeo(altPressure1Buffer.getData()); }
 if (altPressure2Buffer.hasUpdatedData()) { displayString[1] = mapeo(altPressure2Buffer.getData()); }
 if (altPressure3Buffer.hasUpdatedData()) { displayString[0] = mapeo(altPressure3Buffer.getData()); }

 u8g2.clearBuffer();
 u8g2.setFont(u8g2_font_fub20_tn );
 u8g2.setCursor(0, 24);
 u8g2.print(displayString);
 u8g2.sendBuffer();

 delay (5);

}

char mapeo(unsigned int valor){

 if (valor < 6553) { return '0'; }
 if (valor < 13107) { return '1'; }
 if (valor < 19660) { return '2'; }
 if (valor < 26214) { return '3'; }
 if (valor < 32767) { return '4'; }
 if (valor < 39321) { return '5'; }
 if (valor < 45874) { return '6'; }
 if (valor < 52428) { return '7'; }
 if (valor < 58981) { return '8'; }
 return '9' ;

}

 

This glitches when you are flying

 

Cheers

 

Les

Link to comment
Share on other sites

Well the receiver is working properly now.

 

It looks like the bug that caused the Altimeter setting to be off by a few digits is also what caused the baro reading to not work.

See Video:

 

The LCD shows the data being sent by software serial from an Arduino Uno.

The OLED is receiving that data via the hardware serial port of a Nano.

 

Export from DCS-BIOS is next... :pilotfly:

DCS_alt_test_rig_1.thumb.jpg.8b041962480962a18d874f495acc3cb8.jpg

Link to comment
Share on other sites

I think I found it.

Change

#define DCSBIOS_DEFAULT_SERIAL

to

#define DCSBIOS_IRQ_SERIAL

 

In the example sketch for DCSBIOS_DEFAULT_SERIAL there is a comment.

 

/*
 Tell DCS-BIOS to use a serial connection and use the default Arduino Serial
 library. This will work on the vast majority of Arduino-compatible boards,
 [b]but you can get corrupted data[/b] if you have too many or too slow outputs
 (e.g. when you have multiple character displays), because the receive
 buffer can fill up if the sketch spends too much time updating them.
 
 If you can, use the IRQ Serial connection instead.
*/

 

I think this is the problem. I tested using #define DCSBIOS_IRQ_SERIAL and didn't get a glitch on a 5 minute test flight.

 

When i developed this I used an rs485 network and maybe that is the reason to why I didn't get any problems then.

When people asked for the sketch i threw together this sketch and changed to DCSBIOS_DEFAULT_SERIAL from RS485

 

Could you please test it?

Link to comment
Share on other sites

No glitches/jitters since I changed this.

DCS has been running for 15 minutes.

I really think this solved it.

If that's the case I was right. Bad data, not bad code :D Well. Not very bad code at least :music_whistling:

 

I've uploaded my latest sketch to https://www.dropbox.com/sh/uaozt4p6z1yx0wd/AAAMB3i172vHYOTcYdFYZRcKa?dl=0

 

Feel free to use it

 

I'm gonna try to set up a GitHub repository for this and other sketches I've created.

Link to comment
Share on other sites

Not necessarily good news, I'm afraid.

I did that mod to my version of your original code and while I didn't get adverse reading glitches, it just stopped responding for a few seconds, then caught up. This is on a free flight going up to 20000 feet.

 

I'll try the one from your drop box in the same test next.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...