diff --git a/Adafruit_SSD1306.cpp b/Adafruit_SSD1306.cpp index 0ab81a4c..249889a6 100644 --- a/Adafruit_SSD1306.cpp +++ b/Adafruit_SSD1306.cpp @@ -463,16 +463,20 @@ void Adafruit_SSD1306::ssd1306_command(uint8_t c) { bool Adafruit_SSD1306::begin(uint8_t vcs, uint8_t addr, bool reset, bool periphBegin) { - if ((!buffer) && !(buffer = (uint8_t *)malloc(WIDTH * ((HEIGHT + 7) / 8)))) + if ((!buffer) && + !(buffer = (uint8_t *)malloc(SSD1306_SEGMENTS * ((HEIGHT + 7) / 8)))) return false; clearDisplay(); - if (HEIGHT > 32) { + if (WIDTH > 64 && HEIGHT > 32) { drawBitmap((WIDTH - splash1_width) / 2, (HEIGHT - splash1_height) / 2, splash1_data, splash1_width, splash1_height, 1); - } else { + } else if (WIDTH > 64) { drawBitmap((WIDTH - splash2_width) / 2, (HEIGHT - splash2_height) / 2, splash2_data, splash2_width, splash2_height, 1); + } else { + drawBitmap((WIDTH - splash3_width) / 2, (HEIGHT - splash3_height) / 2, + splash3_data, splash3_width, splash3_height, 1); } vccstate = vcs; @@ -538,11 +542,17 @@ bool Adafruit_SSD1306::begin(uint8_t vcs, uint8_t addr, bool reset, ssd1306_command1(HEIGHT - 1); static const uint8_t PROGMEM init2[] = {SSD1306_SETDISPLAYOFFSET, // 0xD3 - 0x0, // no offset - SSD1306_SETSTARTLINE | 0x0, // line #0 - SSD1306_CHARGEPUMP}; // 0x8D + 0x0}; // no offset ssd1306_commandList(init2, sizeof(init2)); + if ((WIDTH == 64) && (HEIGHT == 32)) { + ssd1306_command1(0x00); // line #0 + } else { + ssd1306_command1(SSD1306_SETSTARTLINE); // 0x40 + } + + ssd1306_command1(SSD1306_CHARGEPUMP); // 0x8D + ssd1306_command1((vccstate == SSD1306_EXTERNALVCC) ? 0x10 : 0x14); static const uint8_t PROGMEM init3[] = {SSD1306_MEMORYMODE, // 0x20 @@ -563,6 +573,9 @@ bool Adafruit_SSD1306::begin(uint8_t vcs, uint8_t addr, bool reset, } else if ((WIDTH == 96) && (HEIGHT == 16)) { comPins = 0x2; // ada x12 contrast = (vccstate == SSD1306_EXTERNALVCC) ? 0x10 : 0xAF; + } else if ((WIDTH == 64) && ((HEIGHT == 48) || (HEIGHT == 32))) { + comPins = 0x12; + contrast = (vccstate == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF; } else { // Other screen varieties -- TBD } @@ -622,15 +635,17 @@ void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color) { y = HEIGHT - y - 1; break; } + if ((WIDTH == 64) && (HEIGHT == 48)) + x += 32; switch (color) { case SSD1306_WHITE: - buffer[x + (y / 8) * WIDTH] |= (1 << (y & 7)); + buffer[x + (y / 8) * SSD1306_SEGMENTS] |= (1 << (y & 7)); break; case SSD1306_BLACK: - buffer[x + (y / 8) * WIDTH] &= ~(1 << (y & 7)); + buffer[x + (y / 8) * SSD1306_SEGMENTS] &= ~(1 << (y & 7)); break; case SSD1306_INVERSE: - buffer[x + (y / 8) * WIDTH] ^= (1 << (y & 7)); + buffer[x + (y / 8) * SSD1306_SEGMENTS] ^= (1 << (y & 7)); break; } } @@ -644,7 +659,7 @@ void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color) { commands as needed by one's own application. */ void Adafruit_SSD1306::clearDisplay(void) { - memset(buffer, 0, WIDTH * ((HEIGHT + 7) / 8)); + memset(buffer, 0, SSD1306_SEGMENTS * ((HEIGHT + 7) / 8)); } /*! @@ -707,7 +722,10 @@ void Adafruit_SSD1306::drawFastHLineInternal(int16_t x, int16_t y, int16_t w, w = (WIDTH - x); } if (w > 0) { // Proceed only if width is positive - uint8_t *pBuf = &buffer[(y / 8) * WIDTH + x], mask = 1 << (y & 7); + if ((WIDTH == 64) && (HEIGHT == 48)) + x += 32; + uint8_t *pBuf = &buffer[x + (y / 8) * SSD1306_SEGMENTS]; + uint8_t mask = 1 << (y & 7); switch (color) { case SSD1306_WHITE: while (w--) { @@ -793,7 +811,9 @@ void Adafruit_SSD1306::drawFastVLineInternal(int16_t x, int16_t __y, // this display doesn't need ints for coordinates, // use local byte registers for faster juggling uint8_t y = __y, h = __h; - uint8_t *pBuf = &buffer[(y / 8) * WIDTH + x]; + if ((WIDTH == 64) && (HEIGHT == 48)) + x += 32; + uint8_t *pBuf = &buffer[x + (y / 8) * SSD1306_SEGMENTS]; // do the first partial byte, if necessary - this requires some masking uint8_t mod = (y & 7); @@ -821,7 +841,7 @@ void Adafruit_SSD1306::drawFastVLineInternal(int16_t x, int16_t __y, *pBuf ^= mask; break; } - pBuf += WIDTH; + pBuf += SSD1306_SEGMENTS; } if (h >= mod) { // More to go? @@ -832,17 +852,17 @@ void Adafruit_SSD1306::drawFastVLineInternal(int16_t x, int16_t __y, // separate copy of the code so we don't impact performance of // black/white write version with an extra comparison per loop do { - *pBuf ^= 0xFF; // Invert byte - pBuf += WIDTH; // Advance pointer 8 rows - h -= 8; // Subtract 8 rows from height + *pBuf ^= 0xFF; // Invert byte + pBuf += SSD1306_SEGMENTS; // Advance pointer 8 rows + h -= 8; // Subtract 8 rows from height } while (h >= 8); } else { // store a local value to work with uint8_t val = (color != SSD1306_BLACK) ? 255 : 0; do { - *pBuf = val; // Set byte - pBuf += WIDTH; // Advance pointer 8 rows - h -= 8; // Subtract 8 rows from height + *pBuf = val; // Set byte + pBuf += SSD1306_SEGMENTS; // Advance pointer 8 rows + h -= 8; // Subtract 8 rows from height } while (h >= 8); } } @@ -902,7 +922,9 @@ bool Adafruit_SSD1306::getPixel(int16_t x, int16_t y) { y = HEIGHT - y - 1; break; } - return (buffer[x + (y / 8) * WIDTH] & (1 << (y & 7))); + if ((WIDTH == 64) && (HEIGHT == 48)) + x += 32; + return (buffer[x + (y / 8) * SSD1306_SEGMENTS] & (1 << (y & 7))); } return false; // Pixel out of bounds } @@ -925,13 +947,14 @@ uint8_t *Adafruit_SSD1306::getBuffer(void) { return buffer; } */ void Adafruit_SSD1306::display(void) { TRANSACTION_START - static const uint8_t PROGMEM dlist1[] = { - SSD1306_PAGEADDR, - 0, // Page start address - 0xFF, // Page end (not really, but works here) - SSD1306_COLUMNADDR, 0}; // Column start address + static const uint8_t PROGMEM dlist1[] = {SSD1306_PAGEADDR, + 0}; // Page start address ssd1306_commandList(dlist1, sizeof(dlist1)); - ssd1306_command1(WIDTH - 1); // Column end address + ssd1306_command1((HEIGHT + 7) / 8 - 1); // Page end address + static const uint8_t PROGMEM dlist2[] = {SSD1306_COLUMNADDR, + 0}; // Column start address + ssd1306_commandList(dlist2, sizeof(dlist2)); + ssd1306_command1(SSD1306_SEGMENTS - 1); // Column end address #if defined(ESP8266) // ESP8266 needs a periodic yield() call to avoid watchdog reset. @@ -942,7 +965,7 @@ void Adafruit_SSD1306::display(void) { // 32-byte transfer condition below. yield(); #endif - uint16_t count = WIDTH * ((HEIGHT + 7) / 8); + uint16_t count = SSD1306_SEGMENTS * ((HEIGHT + 7) / 8); uint8_t *ptr = buffer; if (wire) { // I2C wire->beginTransmission(i2caddr); diff --git a/Adafruit_SSD1306.h b/Adafruit_SSD1306.h index 5100c015..711298e6 100644 --- a/Adafruit_SSD1306.h +++ b/Adafruit_SSD1306.h @@ -24,10 +24,12 @@ #ifndef _Adafruit_SSD1306_H_ #define _Adafruit_SSD1306_H_ -// ONE of the following three lines must be #defined: +// ONE of the following lines must be #defined: //#define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen #define SSD1306_128_32 ///< DEPRECATED: old way to specify 128x32 screen //#define SSD1306_96_16 ///< DEPRECATED: old way to specify 96x16 screen +//#define SSD1306_64_48 ///< DEPRECATED: old way to specify 64x48 screen +//#define SSD1306_64_32 ///< DEPRECATED: old way to specify 64x32 screen // This establishes the screen dimensions in old Adafruit_SSD1306 sketches // (NEW CODE SHOULD IGNORE THIS, USE THE CONSTRUCTORS THAT ACCEPT WIDTH // AND HEIGHT ARGUMENTS). @@ -105,6 +107,8 @@ typedef uint32_t PortMask; #define SSD1306_ACTIVATE_SCROLL 0x2F ///< Start scroll #define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3 ///< Set scroll range +#define SSD1306_SEGMENTS 128 ///< See datasheet + // Deprecated size stuff for backwards compatibility with old sketches #if defined SSD1306_128_64 #define SSD1306_LCDWIDTH 128 ///< DEPRECATED: width w/SSD1306_128_64 defined @@ -118,6 +122,14 @@ typedef uint32_t PortMask; #define SSD1306_LCDWIDTH 96 ///< DEPRECATED: width w/SSD1306_96_16 defined #define SSD1306_LCDHEIGHT 16 ///< DEPRECATED: height w/SSD1306_96_16 defined #endif +#if defined SSD1306_64_48 +#define SSD1306_LCDWIDTH 64 ///< DEPRECATED: width w/SSD1306_64_48 defined +#define SSD1306_LCDHEIGHT 48 ///< DEPRECATED: height w/SSD1306_64_48 defined +#endif +#if defined SSD1306_64_32 +#define SSD1306_LCDWIDTH 64 ///< DEPRECATED: width w/SSD1306_64_32 defined +#define SSD1306_LCDHEIGHT 32 ///< DEPRECATED: height w/SSD1306_64_32 defined +#endif /*! @brief Class that stores state and functions for interacting with diff --git a/examples/ssd1306_64x48_i2c/ssd1306_64x48_i2c.ino b/examples/ssd1306_64x48_i2c/ssd1306_64x48_i2c.ino new file mode 100644 index 00000000..cc4e7317 --- /dev/null +++ b/examples/ssd1306_64x48_i2c/ssd1306_64x48_i2c.ino @@ -0,0 +1,415 @@ +/************************************************************************** + This is an example for our Monochrome OLEDs based on SSD1306 drivers + + Pick one up today in the adafruit shop! + ------> http://www.adafruit.com/category/63_98 + + This example is for a 64x48 pixel display using I2C to communicate + 3 pins are required to interface (two I2C and one reset). + + Adafruit invests time and resources providing this open + source code, please support Adafruit and open-source + hardware by purchasing products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries, + with contributions from the open source community. + BSD license, check license.txt for more information + All text above, and the splash screen below must be + included in any redistribution. + **************************************************************************/ + +#include +#include +#include +#include + +#define SCREEN_WIDTH 64 // OLED display width, in pixels +#define SCREEN_HEIGHT 48 // OLED display height, in pixels + +// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) +// The pins for I2C are defined by the Wire-library. +// On an arduino UNO: A4(SDA), A5(SCL) +// On an arduino MEGA 2560: 20(SDA), 21(SCL) +// On an arduino LEONARDO: 2(SDA), 3(SCL), ... +#define OLED_RESET 0 // GPIO0 - Reset pin # (or -1 if sharing Arduino reset pin) +#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32, 0x3C for 64x48 +Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); + +#define NUMFLAKES 10 // Number of snowflakes in the animation example + +#define LOGO_HEIGHT 16 +#define LOGO_WIDTH 16 +static const unsigned char PROGMEM logo_bmp[] = +{ B00000000, B11000000, + B00000001, B11000000, + B00000001, B11000000, + B00000011, B11100000, + B11110011, B11100000, + B11111110, B11111000, + B01111110, B11111111, + B00110011, B10011111, + B00011111, B11111100, + B00001101, B01110000, + B00011011, B10100000, + B00111111, B11100000, + B00111111, B11110000, + B01111100, B11110000, + B01110000, B01110000, + B00000000, B00110000 }; + +void setup() { + Serial.begin(9600); + + // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally + if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { + Serial.println(F("SSD1306 allocation failed")); + for(;;); // Don't proceed, loop forever + } + + // Show initial display buffer contents on the screen -- + // the library initializes this with an Adafruit splash screen. + display.display(); + delay(2000); // Pause for 2 seconds + + // Clear the buffer + display.clearDisplay(); + + // Draw a single pixel in white + display.drawPixel(10, 10, SSD1306_WHITE); + + // Show the display buffer on the screen. You MUST call display() after + // drawing commands to make them visible on screen! + display.display(); + delay(2000); + // display.display() is NOT necessary after every single drawing command, + // unless that's what you want...rather, you can batch up a bunch of + // drawing operations and then update the screen all at once by calling + // display.display(). These examples demonstrate both approaches... + + testdrawline(); // Draw many lines + + testdrawrect(); // Draw rectangles (outlines) + + testfillrect(); // Draw rectangles (filled) + + testdrawcircle(); // Draw circles (outlines) + + testfillcircle(); // Draw circles (filled) + + testdrawroundrect(); // Draw rounded rectangles (outlines) + + testfillroundrect(); // Draw rounded rectangles (filled) + + testdrawtriangle(); // Draw triangles (outlines) + + testfilltriangle(); // Draw triangles (filled) + + testdrawchar(); // Draw characters of the default font + + testdrawstyles(); // Draw 'stylized' characters + + testscrolltext(); // Draw scrolling text + + testdrawbitmap(); // Draw a small bitmap image + + // Invert and restore display, pausing in-between + display.invertDisplay(true); + delay(1000); + display.invertDisplay(false); + delay(1000); + + testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps +} + +void loop() { +} + +void testdrawline() { + int16_t i; + + display.clearDisplay(); // Clear display buffer + + for(i=0; i=0; i-=4) { + display.drawLine(0, display.height()-1, display.width()-1, i, SSD1306_WHITE); + display.display(); + delay(1); + } + delay(250); + + display.clearDisplay(); + + for(i=display.width()-1; i>=0; i-=4) { + display.drawLine(display.width()-1, display.height()-1, i, 0, SSD1306_WHITE); + display.display(); + delay(1); + } + for(i=display.height()-1; i>=0; i-=4) { + display.drawLine(display.width()-1, display.height()-1, 0, i, SSD1306_WHITE); + display.display(); + delay(1); + } + delay(250); + + display.clearDisplay(); + + for(i=0; i0; i-=3) { + // The INVERSE color is used so circles alternate white/black + display.fillCircle(display.width() / 2, display.height() / 2, i, SSD1306_INVERSE); + display.display(); // Update screen with each newly-drawn circle + delay(1); + } + + delay(2000); +} + +void testdrawroundrect(void) { + display.clearDisplay(); + + for(int16_t i=0; i0; i-=5) { + // The INVERSE color is used so triangles alternate white/black + display.fillTriangle( + display.width()/2 , display.height()/2-i, + display.width()/2-i, display.height()/2+i, + display.width()/2+i, display.height()/2+i, SSD1306_INVERSE); + display.display(); + delay(1); + } + + delay(2000); +} + +void testdrawchar(void) { + display.clearDisplay(); + + display.setTextSize(1); // Normal 1:1 pixel scale + display.setTextColor(SSD1306_WHITE); // Draw white text + display.setCursor(0, 0); // Start at top-left corner + display.cp437(true); // Use full 256 char 'Code Page 437' font + + // Not all the characters will fit on the display. This is normal. + // Library will draw what it can and the rest will be clipped. + for(int16_t i=0; i<256; i++) { + if(i == '\n') display.write(' '); + else display.write(i); + } + + display.display(); + delay(2000); +} + +void testdrawstyles(void) { + display.clearDisplay(); + + display.setTextSize(1); // Normal 1:1 pixel scale + display.setTextColor(SSD1306_WHITE); // Draw white text + display.setCursor(0,0); // Start at top-left corner + display.println(F("Hello, world!")); + + display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text + display.println(3.141592); + + display.setTextSize(2); // Draw 2X-scale text + display.setTextColor(SSD1306_WHITE); + display.print(F("0x")); display.println(0xDEADBEEF, HEX); + + display.display(); + delay(2000); +} + +void testscrolltext(void) { + display.clearDisplay(); + + display.setTextSize(2); // Draw 2X-scale text + display.setTextColor(SSD1306_WHITE); + display.setCursor(10, 0); + display.println(F("scroll")); + display.display(); // Show initial text + delay(100); + + // Scroll in various directions, pausing in-between: + display.startscrollright(0x00, 0x0F); + delay(2000); + display.stopscroll(); + delay(1000); + display.startscrollleft(0x00, 0x0F); + delay(2000); + display.stopscroll(); + delay(1000); + display.startscrolldiagright(0x00, 0x07); + delay(2000); + display.startscrolldiagleft(0x00, 0x07); + delay(2000); + display.stopscroll(); + delay(1000); +} + +void testdrawbitmap(void) { + display.clearDisplay(); + + display.drawBitmap( + (display.width() - LOGO_WIDTH ) / 2, + (display.height() - LOGO_HEIGHT) / 2, + logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1); + display.display(); + delay(1000); +} + +#define XPOS 0 // Indexes into the 'icons' array in function below +#define YPOS 1 +#define DELTAY 2 + +void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) { + int8_t f, icons[NUMFLAKES][3]; + + // Initialize 'snowflake' positions + for(f=0; f< NUMFLAKES; f++) { + icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width()); + icons[f][YPOS] = -LOGO_HEIGHT; + icons[f][DELTAY] = random(1, 6); + Serial.print(F("x: ")); + Serial.print(icons[f][XPOS], DEC); + Serial.print(F(" y: ")); + Serial.print(icons[f][YPOS], DEC); + Serial.print(F(" dy: ")); + Serial.println(icons[f][DELTAY], DEC); + } + + for(;;) { // Loop forever... + display.clearDisplay(); // Clear the display buffer + + // Draw each snowflake: + for(f=0; f< NUMFLAKES; f++) { + display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, SSD1306_WHITE); + } + + display.display(); // Show the display buffer on the screen + delay(200); // Pause for 1/10 second + + // Then update coordinates of each flake... + for(f=0; f< NUMFLAKES; f++) { + icons[f][YPOS] += icons[f][DELTAY]; + // If snowflake is off the bottom of the screen... + if (icons[f][YPOS] >= display.height()) { + // Reinitialize to a random position, just off the top + icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width()); + icons[f][YPOS] = -LOGO_HEIGHT; + icons[f][DELTAY] = random(1, 6); + } + } + } +} diff --git a/scripts/Makefile b/scripts/Makefile index 9e892ecb..d4ae7199 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -4,6 +4,7 @@ PY=python3 splash.h: make_splash.py splash1.png splash2.png ${PY} make_splash.py splash1.png splash1 >$@ ${PY} make_splash.py splash2.png splash2 >>$@ + ${PY} make_splash.py splash3.png splash3 >>$@ clean: rm -f splash.h diff --git a/scripts/splash3.png b/scripts/splash3.png new file mode 100644 index 00000000..cfc9b07d Binary files /dev/null and b/scripts/splash3.png differ diff --git a/splash.h b/splash.h index 1520e321..7a2e7dee 100644 --- a/splash.h +++ b/splash.h @@ -180,3 +180,40 @@ const uint8_t PROGMEM splash2_data[] = { B01111111, B11111111, B11111111, B11111111, B11111110, B10110101, B10101101, B11101101, B10110101, B01111110, B11100000, }; + +#define splash3_width 64 +#define splash3_height 48 + +const uint8_t PROGMEM splash3_data[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf1, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xbf, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x78, 0xbf, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, + 0xc3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0e, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, + 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xdc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x01, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x18, 0x03, + 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x30, 0x00, + 0x00, 0xf9, 0xf9, 0xf3, 0xb6, 0xc4, 0xbc, 0x00, 0x01, 0x99, 0xb9, 0x1b, + 0x3e, 0xc4, 0xb0, 0x00, 0x00, 0x0b, 0x18, 0x1b, 0x30, 0xc4, 0xb0, 0x00, + 0x01, 0xfb, 0x19, 0xfb, 0x30, 0xc4, 0xb0, 0x00, 0x01, 0x8b, 0x1b, 0x1b, + 0x30, 0xc4, 0xb0, 0x00, 0x01, 0x8b, 0x1b, 0x1b, 0x30, 0xc4, 0xb0, 0x00, + 0x01, 0xf9, 0xfb, 0xfb, 0x30, 0xf4, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xff, 0xff, 0xfe, 0x67, 0x59, 0xdc, 0x00, 0x01, 0xff, 0xff, 0xfe, + 0x67, 0x59, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};