0

I have code to run an SH1106 display that works perfectly fine on a Mega328 (basic Uno clone) and Sparkfun Redboard Artemis (ARM M4). The code for the ESP8266 (NodeMCU v1 clone) should be pretty similar to the ARM (i.e. bypassing the PROGMEM/memcpy_P stuff). However, I've found that the ESP8266 goes into an infinite reboot loop with the following error message seen on the serial monitor:


 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1392, room 16 
tail 0
chksum 0xd0
csum 0xd0
v3d128e5c
~ld

I've tracked down the crash to the line where the Font Array data is accessed in my PutBigChar function in my My_SSH1106.h. In fact, any attempt to access the array using a variable index causes an immediate reboot. Using a constant literal index with the array does not cause the reboot. Hence the horrible, ugly hack workaround in the code below.

Main sketch:


#include"My_SH1106.h"

void setup() {
  pinMode(LED_BUILTIN,OUTPUT);
  digitalWrite(LED_BUILTIN,HIGH);
  MySH1106_Init();
  MySH1106_Clear();
}

void loop() {

  MySH1106_PutBigString("I'm an arduino!",2,0);
  MySH1106_PutBigString("I'm an arduino!",2,14);

  delay(200);
}

My_SH1106.h

#include<Wire.h>
#include"lcdfont.h"

#define SH1106_SLAVE_ADDR 0x3c

#define CTRL_LAST_CMD 0x00
#define CTRL_NEXT_CMD 0x80
#define CTRL_LAST_RAM 0x40
#define CTRL_NEXT_RAM 0xC0

#define SH1106_OPT_INVERT 0x01
#define SH1106_OPT_UNDERL 0x02
#define SH1106_BIG_ROWS 4
#define SH1106_BIG_COLS 16



unsigned char MySH1106_workingBuffer[132];
unsigned char MySH1106_X, MySH1106_Y, MySH1106_options;


void MySH1106_Init() {
#ifdef ESP8266
    Wire.begin(D1,D2);  //sda, scl
#else
    Wire.begin();
#endif
    Wire.beginTransmission(SH1106_SLAVE_ADDR);
    Wire.write(CTRL_NEXT_CMD);
    Wire.write(0xaf); //display on
    Wire.write(CTRL_LAST_CMD);
    Wire.write(0xa5); //all on.
    //Wire.write(0xa4); //normal
    Wire.endTransmission(1);
    delay(200);
    Wire.beginTransmission(SH1106_SLAVE_ADDR);
    Wire.write(CTRL_LAST_CMD);
    Wire.write(0xa4);  //normal display
    Wire.endTransmission(1);
    MySH1106_X=0;
    MySH1106_Y=0;

}


void MySH1106_SetCol(unsigned char col) {
    Wire.beginTransmission(SH1106_SLAVE_ADDR);
    Wire.write(CTRL_NEXT_CMD);
    Wire.write(col & 0x0f);
    Wire.write(CTRL_LAST_CMD);
    Wire.write(0x10 | ((col>>4)&0xf));
    Wire.endTransmission(1);
}


void MySH1106_SetPage(unsigned char page) {
    Wire.beginTransmission(SH1106_SLAVE_ADDR);
    Wire.write(CTRL_LAST_CMD);
    Wire.write(0xb0 | (page & 0xf));
    Wire.endTransmission(1);
}

void MySH1106_SetPageCol(unsigned char page, unsigned char col) {
    Wire.beginTransmission(SH1106_SLAVE_ADDR);
    Wire.write(CTRL_NEXT_CMD);
    Wire.write(0xb0 | (page & 0xf));
    Wire.write(CTRL_NEXT_CMD);
    Wire.write(col & 0x0f);
    Wire.write(CTRL_LAST_CMD);
    Wire.write(0x10 | ((col>>4)&0xf));
    Wire.endTransmission(1);
}

void MySH1106_Clear() {
    for(unsigned char page=0;page<8;page++) {
        MySH1106_SetPage(page);
        MySH1106_SetCol(1);
        for(unsigned char x=0;x<129;x++) {
#ifdef ESP8266
            yield();
#endif
            Wire.beginTransmission(SH1106_SLAVE_ADDR);
            Wire.write(CTRL_LAST_RAM);
            Wire.write(0x00);
            Wire.endTransmission(1);
        } //of all columns

    }//of all pages
}

void MySH1106_PutBigChar(char c, unsigned char x, unsigned char y) {
    unsigned char remainder, offset, startPage, endPage, filldat, currentPage;
    unsigned char temp, curY, curX;

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
    unsigned char glyphBuf[CHAR_HEIGHT];
//#elif defined(ESP8266)
//    const unsigned char* glyphBuf;
#else
    unsigned char glyphBuf[CHAR_HEIGHT];
#endif

    unsigned char glyphRow=0, glyphCol,glyphByte;
    unsigned char args[4];

    offset = y % 8;
    remainder =(y+CHAR_HEIGHT) % 8;
    startPage = y/8;
    endPage = (y+CHAR_HEIGHT)/8;
    currentPage = startPage;
#ifdef ESP8266
    yield();
#endif

    //memcpy_P is for AVR8 based processors.
    //when running on Artemis, use a regular copy.
    //#ifdef __AVR__ would cover other AVRs.

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
    memcpy_P(glyphBuf, (unsigned char *)pgm_read_word(&(FontArray[c])),CHAR_HEIGHT);
#elif defined(ESP8266)
    //oddly, any attempt to dereference glyphBuf or use it as an array results in an exception.
    //glyphBuf = FontArray[c];

    //horrible, brutal hack.
    switch(c) {
        case ' ':
            glyphBuf[0]=NullArray[0];
            glyphBuf[1]=NullArray[1];
            glyphBuf[2]=NullArray[2];
            glyphBuf[3]=NullArray[3];
            glyphBuf[4]=NullArray[4];
            glyphBuf[5]=NullArray[5];
            glyphBuf[6]=NullArray[6];
            glyphBuf[7]=NullArray[7];
            glyphBuf[8]=NullArray[8];
            glyphBuf[9]=NullArray[9];
            glyphBuf[10]=NullArray[10];
            glyphBuf[11]=NullArray[11];
            glyphBuf[12]=NullArray[12];
            glyphBuf[13]=NullArray[13];
            break;
        case 'I':
            glyphBuf[0]=IArray[0];
            glyphBuf[1]=IArray[1];
            glyphBuf[2]=IArray[2];
            glyphBuf[3]=IArray[3];
            glyphBuf[4]=IArray[4];
            glyphBuf[5]=IArray[5];
            glyphBuf[6]=IArray[6];
            glyphBuf[7]=IArray[7];
            glyphBuf[8]=IArray[8];
            glyphBuf[9]=IArray[9];
            glyphBuf[10]=IArray[10];
            glyphBuf[11]=IArray[11];
            glyphBuf[12]=IArray[12];
            glyphBuf[13]=IArray[13];

            break;
        case 'a':
            glyphBuf[0]=aArray[0];
            glyphBuf[1]=aArray[1];
            glyphBuf[2]=aArray[2];
            glyphBuf[3]=aArray[3];
            glyphBuf[4]=aArray[4];
            glyphBuf[5]=aArray[5];
            glyphBuf[6]=aArray[6];
            glyphBuf[7]=aArray[7];
            glyphBuf[8]=aArray[8];
            glyphBuf[9]=aArray[9];
            glyphBuf[10]=aArray[10];
            glyphBuf[11]=aArray[11];
            glyphBuf[12]=aArray[12];
            glyphBuf[13]=aArray[13];
            break;
        case 'm':
            glyphBuf[0]=mArray[0];
            glyphBuf[1]=mArray[1];
            glyphBuf[2]=mArray[2];
            glyphBuf[3]=mArray[3];
            glyphBuf[4]=mArray[4];
            glyphBuf[5]=mArray[5];
            glyphBuf[6]=mArray[6];
            glyphBuf[7]=mArray[7];
            glyphBuf[8]=mArray[8];
            glyphBuf[9]=mArray[9];
            glyphBuf[10]=mArray[10];
            glyphBuf[11]=mArray[11];
            glyphBuf[12]=mArray[12];
            glyphBuf[13]=mArray[13];
            break;
        case 'n':
            glyphBuf[0]=nArray[0];
            glyphBuf[1]=nArray[1];
            glyphBuf[2]=nArray[2];
            glyphBuf[3]=nArray[3];
            glyphBuf[4]=nArray[4];
            glyphBuf[5]=nArray[5];
            glyphBuf[6]=nArray[6];
            glyphBuf[7]=nArray[7];
            glyphBuf[8]=nArray[8];
            glyphBuf[9]=nArray[9];
            glyphBuf[10]=nArray[10];
            glyphBuf[11]=nArray[11];
            glyphBuf[12]=nArray[12];
            glyphBuf[13]=nArray[13];
            break;
        default:
            glyphBuf[0]=NullArray[0];
            glyphBuf[1]=NullArray[1];
            glyphBuf[2]=NullArray[2];
            glyphBuf[3]=NullArray[3];
            glyphBuf[4]=NullArray[4];
            glyphBuf[5]=NullArray[5];
            glyphBuf[6]=NullArray[6];
            glyphBuf[7]=NullArray[7];
            glyphBuf[8]=NullArray[8];
            glyphBuf[9]=NullArray[9];
            glyphBuf[10]=NullArray[10];
            glyphBuf[11]=NullArray[11];
            glyphBuf[12]=NullArray[12];
            glyphBuf[13]=NullArray[13];
    }//of switch

#else
//this should work for ESP, but doesn't
    for(int i=0;i<CHAR_HEIGHT;i++) {
        glyphBuf[i]=FontArray[c][i];
    }
#endif

    MySH1106_SetPageCol(startPage,x);
    Wire.beginTransmission(SH1106_SLAVE_ADDR);//set up for ram read
    Wire.write(CTRL_LAST_RAM);
    Wire.endTransmission(1);

    Wire.requestFrom(SH1106_SLAVE_ADDR, 9, 1);
    while(Wire.available()<9) {
#ifdef ESP8266
        yield();
#endif
    };
    Wire.read(); //dummy read
    for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
        MySH1106_workingBuffer[curX] = Wire.read(); //real read.
    }
#ifdef ESP8266
    yield();
#endif

    for(curY=offset;curY<8;curY++) {
        glyphByte = glyphBuf[glyphRow++];
        glyphCol=0;
        for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
#ifdef ESP8266
            yield();
#endif
            if ((0x80>>glyphCol) & glyphByte) {
                MySH1106_workingBuffer[curX] |= (0x01<<curY);
            } else {
                MySH1106_workingBuffer[curX] &= ~(0x01<<curY);
            }

            glyphCol++;
#ifdef ESP8266
            yield();
#endif
        }

    }//of y offsets in first page.


    MySH1106_SetCol(x);
    Wire.beginTransmission(SH1106_SLAVE_ADDR);
    Wire.write(CTRL_LAST_RAM);
    for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
        Wire.write(MySH1106_workingBuffer[curX] );
    }
    Wire.endTransmission(1);
    currentPage++;

    //middle page
    if(currentPage<endPage) {
        MySH1106_SetPageCol(currentPage,x);
        Wire.beginTransmission(SH1106_SLAVE_ADDR);//set up for ram read
        Wire.write(CTRL_LAST_RAM);
        Wire.endTransmission(1);

        Wire.requestFrom(SH1106_SLAVE_ADDR, 9, 1);
        while(Wire.available()<9){
#ifdef ESP8266
            yield();
#endif
        };
        Wire.read(); //dummy read
        for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
            MySH1106_workingBuffer[curX] = Wire.read(); //real read.
        }

        for(curY=0;curY<8;curY++) {
            glyphByte = glyphBuf[glyphRow++];
            glyphCol=0;
            for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
                if(glyphByte & (0x80>>glyphCol)) {
                    MySH1106_workingBuffer[curX] |= (0x01<<curY);
                } else {
                    MySH1106_workingBuffer[curX] &= ~(0x01<<curY);
                }
                glyphCol++;
            }
#ifdef ESP8266
            yield();
#endif
        }//of y offsets in intermediate page

        MySH1106_SetCol(x);
        Wire.beginTransmission(SH1106_SLAVE_ADDR);
        Wire.write(CTRL_LAST_RAM);
        for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
            Wire.write(MySH1106_workingBuffer[curX] );
        }
        Wire.endTransmission(1);
        currentPage++;
    }

    MySH1106_SetPageCol(currentPage,x);
    Wire.beginTransmission(SH1106_SLAVE_ADDR);//set up for ram read
    Wire.write(CTRL_LAST_RAM);
    Wire.endTransmission(1);

    Wire.requestFrom(SH1106_SLAVE_ADDR, 9, 1);
    while(Wire.available()<9){
#ifdef ESP8266
        yield();
#endif
    };
    Wire.read(); //dummy read
    for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
        MySH1106_workingBuffer[curX] = Wire.read(); //real read.
    }

    for(curY=0;curY<remainder;curY++) {
        glyphByte = glyphBuf[glyphRow++];
        glyphCol=0;
        for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
            if(glyphByte & (0x80>>glyphCol)) {
                MySH1106_workingBuffer[curX] |= (0x01<<curY);
            } else {
                MySH1106_workingBuffer[curX] &= ~(0x01<<curY);
            }
            glyphCol++;
        }
#ifdef ESP8266
        yield();
#endif
    }//of y offsets in last page

    MySH1106_SetCol(x);
    Wire.beginTransmission(SH1106_SLAVE_ADDR);
    Wire.write(CTRL_LAST_RAM);
    for(curX=x;curX<(x+CHAR_WIDTH);curX++) {
        Wire.write(MySH1106_workingBuffer[curX] );
    }
    Wire.endTransmission(1);


}//of PutBigChar


void MySH1106_PutBigString(const char* c, unsigned char x, unsigned char y) {
    int8_t stringIndex=0;

    while(c[stringIndex]) {
        MySH1106_PutBigChar(c[stringIndex++],x,y);

        x+=CHAR_WIDTH;
    }
}

lcdfont.h

/* 
 * File:   
 * Author: 
 * Comments:
 * Revision history: 
 */

//the font is shamelessly extracted from the "BIOS" of DosBox.

// This is a guard condition so that contents of this file are not included
// more than once.  
#ifndef LCD_FONT_DATA_H
#define  LCD_FONT_DATA_H

#define CHAR_HEIGHT 14
#define CHAR_WIDTH 8
// TODO Insert appropriate #include <>

// TODO Insert C++ class definitions if appropriate

// TODO Insert declarations
const unsigned char NullArray[] PROGMEM = { // 0x20
0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char BangArray[] PROGMEM = { // 0x21
0x0, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00};
const unsigned char DquoteArray[] PROGMEM = { // 0x22
0x0, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char HashArray[] PROGMEM = { // 0x23
0x0, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00};
const unsigned char DollarArray[] PROGMEM = { // 0x24
0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00};
const unsigned char PercentArray[] PROGMEM = { // 0x25
0x0, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x66, 0xc6, 0x00, 0x00, 0x00};
const unsigned char AmpersandArray[] PROGMEM = { // 0x26
0x0, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00};
const unsigned char SquoteArray[] PROGMEM = { // 0x27
0x0, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char LparenArray[] PROGMEM = { // 0x28
0x0, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00};
const unsigned char RparenArray[] PROGMEM = { // 0x29
0x0, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00};
const unsigned char AsteriskArray[] PROGMEM = { // 0x2a
0x0, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char PlusArray[] PROGMEM = { // 0x2b
0x0, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char CommaArray[] PROGMEM = { // 0x2c
0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00};
const unsigned char DashArray[] PROGMEM = { // 0x2d
0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char PeriodArray[] PROGMEM = { // 0x2e
0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00};
const unsigned char SlashArray[] PROGMEM = { // 0x2f
0x0, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00};
const unsigned char n0Array[] PROGMEM = { // 0x30
0x0, 0x00, 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char n1Array[] PROGMEM = { // 0x31
0x0, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00};
const unsigned char n2Array[] PROGMEM = { // 0x32
0x0, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00};
const unsigned char n3Array[] PROGMEM = { // 0x33
0x0, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char n4Array[] PROGMEM = { // 0x34
0x0, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00};
const unsigned char n5Array[] PROGMEM = { // 0x35
0x0, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char n6Array[] PROGMEM = { // 0x36
0x0, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char n7Array[] PROGMEM = { // 0x37
0x0, 0x00, 0xfe, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00};
const unsigned char n8Array[] PROGMEM = { // 0x38
0x0, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char n9Array[] PROGMEM = { // 0x39
0x0, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00};
const unsigned char ColonArray[] PROGMEM = { // 0x3a
0x0, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00};
const unsigned char SemicolonArray[] PROGMEM = { // 0x3b
0x0, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00};
const unsigned char LtArray[] PROGMEM = { // 0x3c
0x0, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00};
const unsigned char EqualArray[] PROGMEM = { // 0x3d
0x0, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char GtArray[] PROGMEM = { // 0x3e
0x0, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00};
const unsigned char QuestionArray[] PROGMEM = { // 0x3f
0x0, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00};
const unsigned char AtArray[] PROGMEM = { // 0x40
0x0, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00};
const unsigned char AArray[] PROGMEM = { // 0x41
0x0, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00};
const unsigned char BArray[] PROGMEM = { // 0x42
0x0, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00};
const unsigned char CArray[] PROGMEM = { // 0x43
0x0, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00};
const unsigned char DArray[] PROGMEM = { // 0x44
0x0, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00};
const unsigned char EArray[] PROGMEM = { // 0x45
0x0, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00};
const unsigned char FArray[] PROGMEM = { // 0x46
0x0, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00};
const unsigned char GArray[] PROGMEM = { // 0x47
0x0, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00};
const unsigned char HArray[] PROGMEM = { // 0x48
0x0, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00};
const unsigned char IArray[] PROGMEM = { // 0x49
0x0, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00};
const unsigned char JArray[] PROGMEM = { // 0x4a
0x0, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00};
const unsigned char KArray[] PROGMEM = { // 0x4b
0x0, 0x00, 0xe6, 0x66, 0x6c, 0x6c, 0x78, 0x6c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00};
const unsigned char LArray[] PROGMEM = { // 0x4c
0x0, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00};
const unsigned char MArray[] PROGMEM = { // 0x4d
0x0, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00};
const unsigned char NArray[] PROGMEM = { // 0x4e
0x0, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00};
const unsigned char OArray[] PROGMEM = { // 0x4f
0x0, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00};
const unsigned char PArray[] PROGMEM = { // 0x50
0x0, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00};
const unsigned char QArray[] PROGMEM = { // 0x51
0x0, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00};
const unsigned char RArray[] PROGMEM = { // 0x52
0x0, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00};
const unsigned char SArray[] PROGMEM = { // 0x53
0x0, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char TArray[] PROGMEM = { // 0x54
0x0, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00};
const unsigned char UArray[] PROGMEM = { // 0x55
0x0, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char VArray[] PROGMEM = { // 0x56
0x0, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00};
const unsigned char WArray[] PROGMEM = { // 0x57
0x0, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00};
const unsigned char XArray[] PROGMEM = { // 0x58
0x0, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00};
const unsigned char YArray[] PROGMEM = { // 0x59
0x0, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00};
const unsigned char ZArray[] PROGMEM = { // 0x5a
0x0, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00};
const unsigned char LbracketArray[] PROGMEM = { // 0x5b
0x0, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00};
const unsigned char BslashArray[] PROGMEM = { // 0x5c
0x0, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00};
const unsigned char RbracketArray[] PROGMEM = { // 0x5d
0x0, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00};
const unsigned char CaretArray[] PROGMEM = { // 0x5e
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char _Array[] PROGMEM = { // 0x5f
0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00};
const unsigned char BquoteArray[] PROGMEM = { // 0x60
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char aArray[] PROGMEM = { // 0x61
0x0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00};
const unsigned char bArray[] PROGMEM = { // 0x62
0x0, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00};
const unsigned char cArray[] PROGMEM = { // 0x63
0x0, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char dArray[] PROGMEM = { // 0x64
0x0, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00};
const unsigned char eArray[] PROGMEM = { // 0x65
0x0, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char fArray[] PROGMEM = { // 0x66
0x0, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00};
const unsigned char gArray[] PROGMEM = { // 0x67
0x0, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00};
const unsigned char hArray[] PROGMEM = { // 0x68
0x0, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00};
const unsigned char iArray[] PROGMEM = { // 0x69
0x0, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00};
const unsigned char jArray[] PROGMEM = { // 0x6a
0x0, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00};
const unsigned char kArray[] PROGMEM = { // 0x6b
0x0, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00};
const unsigned char lArray[] PROGMEM = { // 0x6c
0x0, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00};
const unsigned char mArray[] PROGMEM = { // 0x6d
0x0, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00};
const unsigned char nArray[] PROGMEM = { // 0x6e
0x0, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00};
const unsigned char oArray[] PROGMEM = { // 0x6f
0x0, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char pArray[] PROGMEM = { // 0x70
0x0, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00};
const unsigned char qArray[] PROGMEM = { // 0x71
0x0, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00};
const unsigned char rArray[] PROGMEM = { // 0x72
0x0, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00};
const unsigned char sArray[] PROGMEM = { // 0x73
0x0, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, 0x00};
const unsigned char tArray[] PROGMEM = { // 0x74
0x0, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00};
const unsigned char uArray[] PROGMEM = { // 0x75
0x0, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00};
const unsigned char vArray[] PROGMEM = { // 0x76
0x0, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00};
const unsigned char wArray[] PROGMEM = { // 0x77
0x0, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00};
const unsigned char xArray[] PROGMEM = { // 0x78
0x0, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00};
const unsigned char yArray[] PROGMEM = { // 0x79
0x0, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00};
const unsigned char zArray[] PROGMEM = { // 0x7a
0x0, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xfe, 0x00, 0x00, 0x00};
const unsigned char LbraceArray[] PROGMEM = { // 0x7b
0x0, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00};
const unsigned char PipeArray[] PROGMEM = { // 0x7c
0x0, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00};
const unsigned char RbraceArray[] PROGMEM = { // 0x7d
0x0, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00};
const unsigned char TildeArray[] PROGMEM = { // 0x7e
0x0, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/*I'll say Kana is allowed to use one more row since there are no descenders.*/
/*on second thought, I don't want to have to come up with a separate 8x8 font*/
/*on third thought, 8x8 would be ugly.*/


const unsigned char dummy[] PROGMEM = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0};


const unsigned char *const FontArray[] PROGMEM = {
dummy,  // 0x00
dummy,  // 0x01
dummy,  // 0x02
dummy,  // 0x03
dummy,  // 0x04
dummy,  // 0x05
dummy,  // 0x06
dummy,  // 0x07
dummy,  // 0x08
dummy,  // 0x09
dummy,  // 0x0a
dummy,  // 0x0b
dummy,  // 0x0c
dummy,  // 0x0d
dummy,  // 0x0e
dummy,  // 0x0f
dummy,  // 0x10
dummy,  // 0x11
dummy,  // 0x12
dummy,  // 0x13
dummy,  // 0x14
dummy,  // 0x15
dummy,  // 0x16
dummy,  // 0x17
dummy,  // 0x18
dummy,  // 0x19
dummy,  // 0x1a
dummy,  // 0x1b
dummy,  // 0x1c
dummy,  // 0x1d
dummy,  // 0x1e
dummy,  // 0x1f
NullArray, // 0x20
BangArray, // 0x21
DquoteArray, // 0x22
HashArray, // 0x23
DollarArray, // 0x24
PercentArray, // 0x25
AmpersandArray, // 0x26
SquoteArray, // 0x27
LparenArray, // 0x28
RparenArray, // 0x29
AsteriskArray, // 0x2a
PlusArray, // 0x2b
CommaArray, // 0x2c
DashArray, // 0x2d
PeriodArray, // 0x2e
SlashArray, // 0x2f
n0Array, // 0x30
n1Array, // 0x31
n2Array, // 0x32
n3Array, // 0x33
n4Array, // 0x34
n5Array, // 0x35
n6Array, // 0x36
n7Array, // 0x37
n8Array, // 0x38
n9Array, // 0x39
ColonArray, // 0x3a
SemicolonArray, // 0x3b
LtArray, // 0x3c
EqualArray, // 0x3d
GtArray, // 0x3e
QuestionArray, // 0x3f
AtArray, // 0x40
AArray, // 0x41
BArray, // 0x42
CArray, // 0x43
DArray, // 0x44
EArray, // 0x45
FArray, // 0x46
GArray, // 0x47
HArray, // 0x48
IArray, // 0x49
JArray, // 0x4a
KArray, // 0x4b
LArray, // 0x4c
MArray, // 0x4d
NArray, // 0x4e
OArray, // 0x4f
PArray, // 0x50
QArray, // 0x51
RArray, // 0x52
SArray, // 0x53
TArray, // 0x54
UArray, // 0x55
VArray, // 0x56
WArray, // 0x57
XArray, // 0x58
YArray, // 0x59
ZArray, // 0x5a
LbracketArray, // 0x5b
BslashArray, // 0x5c
RbracketArray, // 0x5d
CaretArray, // 0x5e
_Array, // 0x5f
BquoteArray, // 0x60
aArray, // 0x61
bArray, // 0x62
cArray, // 0x63
dArray, // 0x64
eArray, // 0x65
fArray, // 0x66
gArray, // 0x67
hArray, // 0x68
iArray, // 0x69
jArray, // 0x6a
kArray, // 0x6b
lArray, // 0x6c
mArray, // 0x6d
nArray, // 0x6e
oArray, // 0x6f
pArray, // 0x70
qArray, // 0x71
rArray, // 0x72
sArray, // 0x73
tArray, // 0x74
uArray, // 0x75
vArray, // 0x76
wArray, // 0x77
xArray, // 0x78
yArray, // 0x79
zArray, // 0x7a
LbraceArray, // 0x7b
PipeArray, // 0x7c
RbraceArray, // 0x7d
TildeArray, // 0x7e

};

#endif 

The horrible, ugly hack should not be necessary. Is this some shortcoming of the ESP, or am I misusing the tool in some way? Is there a simpler way to make this work?

  • Could it be a power issue? Reset cause 2 is a power reset (espressif.com/sites/default/files/documentation/…). From my experience the esp is much more sensitive than the atmegas. – Sim Son Feb 16 at 7:20
  • I don't have any issues running any other script, and I made sure the SH1106 was powered off of a separate supply. I added additional storage caps to the 3.3V rail for good measure. It doesn't feel like a power issue. Other sketches that draw to the SH106 without accessing the font routine also have no problem. – compuser Feb 18 at 8:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.