.
Koden skall läsa av adc värden och sedan i slutändan visa dem i Oled displayen (detta är inte implementerat). Jag skickar först en bild i INIT_main funktionen och sedan väntar 2s. Sedan skriver jag ut värdet på Vbat som jag för tillfället satt till 245 som test. Detta funkar bra så länge jag har skrivraderna direkt efter initieringen. Det funkar även efter ADC_Init();
Men har jag det någonstans senare i koden så skriver den inte ut ngt. Den försöker inte ens skicka ngt på I2C, har kollat med scope. Uppfyller jag inte ngr write kriterie eller vad kan tänkas hända? Vad kan jag testa för att komma vidare?
EN1-4 togglar i while loopen så koden har INTE hängt sig. Det är det enda jag kan säga i nuläget
Kod: Markera allt
#include "SSD1306driver_lite.h"
uint8_t _i2caddr, _vccstate, x_pos = 0, y_pos = 0, text_size = 1;
bool wrap = true, SSD1306_Color = true;
const uint8_t Font[] = {
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5F, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00,
0x14, 0x7F, 0x14, 0x7F, 0x14,
0x24, 0x2A, 0x7F, 0x2A, 0x12,
0x23, 0x13, 0x08, 0x64, 0x62,
0x36, 0x49, 0x56, 0x20, 0x50,
0x00, 0x08, 0x07, 0x03, 0x00,
0x00, 0x1C, 0x22, 0x41, 0x00,
0x00, 0x41, 0x22, 0x1C, 0x00,
0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
0x08, 0x08, 0x3E, 0x08, 0x08,
0x00, 0x80, 0x70, 0x30, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x60, 0x60, 0x00,
0x20, 0x10, 0x08, 0x04, 0x02,
0x3E, 0x51, 0x49, 0x45, 0x3E,
0x00, 0x42, 0x7F, 0x40, 0x00,
0x72, 0x49, 0x49, 0x49, 0x46,
0x21, 0x41, 0x49, 0x4D, 0x33,
0x18, 0x14, 0x12, 0x7F, 0x10,
0x27, 0x45, 0x45, 0x45, 0x39,
0x3C, 0x4A, 0x49, 0x49, 0x31,
0x41, 0x21, 0x11, 0x09, 0x07,
0x36, 0x49, 0x49, 0x49, 0x36,
0x46, 0x49, 0x49, 0x29, 0x1E,
0x00, 0x00, 0x14, 0x00, 0x00,
0x00, 0x40, 0x34, 0x00, 0x00,
0x00, 0x08, 0x14, 0x22, 0x41,
0x14, 0x14, 0x14, 0x14, 0x14,
0x00, 0x41, 0x22, 0x14, 0x08,
0x02, 0x01, 0x59, 0x09, 0x06,
0x3E, 0x41, 0x5D, 0x59, 0x4E,
0x7C, 0x12, 0x11, 0x12, 0x7C,
0x7F, 0x49, 0x49, 0x49, 0x36,
0x3E, 0x41, 0x41, 0x41, 0x22,
0x7F, 0x41, 0x41, 0x41, 0x3E,
0x7F, 0x49, 0x49, 0x49, 0x41,
0x7F, 0x09, 0x09, 0x09, 0x01,
0x3E, 0x41, 0x41, 0x51, 0x73,
0x7F, 0x08, 0x08, 0x08, 0x7F,
0x00, 0x41, 0x7F, 0x41, 0x00,
0x20, 0x40, 0x41, 0x3F, 0x01,
0x7F, 0x08, 0x14, 0x22, 0x41,
0x7F, 0x40, 0x40, 0x40, 0x40,
0x7F, 0x02, 0x1C, 0x02, 0x7F,
0x7F, 0x04, 0x08, 0x10, 0x7F,
0x3E, 0x41, 0x41, 0x41, 0x3E,
0x7F, 0x09, 0x09, 0x09, 0x06,
0x3E, 0x41, 0x51, 0x21, 0x5E,
0x7F, 0x09, 0x19, 0x29, 0x46,
0x26, 0x49, 0x49, 0x49, 0x32,
0x03, 0x01, 0x7F, 0x01, 0x03,
0x3F, 0x40, 0x40, 0x40, 0x3F,
0x1F, 0x20, 0x40, 0x20, 0x1F,
0x3F, 0x40, 0x38, 0x40, 0x3F,
0x63, 0x14, 0x08, 0x14, 0x63,
0x03, 0x04, 0x78, 0x04, 0x03,
0x61, 0x59, 0x49, 0x4D, 0x43,
0x00, 0x7F, 0x41, 0x41, 0x41,
0x02, 0x04, 0x08, 0x10, 0x20,
0x00, 0x41, 0x41, 0x41, 0x7F,
0x04, 0x02, 0x01, 0x02, 0x04,
0x40, 0x40, 0x40, 0x40, 0x40,
0x00, 0x03, 0x07, 0x08, 0x00,
0x20, 0x54, 0x54, 0x78, 0x40,
0x7F, 0x28, 0x44, 0x44, 0x38,
0x38, 0x44, 0x44, 0x44, 0x28,
0x38, 0x44, 0x44, 0x28, 0x7F,
0x38, 0x54, 0x54, 0x54, 0x18,
0x00, 0x08, 0x7E, 0x09, 0x02,
0x18, 0xA4, 0xA4, 0x9C, 0x78,
0x7F, 0x08, 0x04, 0x04, 0x78,
0x00, 0x44, 0x7D, 0x40, 0x00,
0x20, 0x40, 0x40, 0x3D, 0x00,
0x7F, 0x10, 0x28, 0x44, 0x00,
0x00, 0x41, 0x7F, 0x40, 0x00,
0x7C, 0x04, 0x78, 0x04, 0x78,
0x7C, 0x08, 0x04, 0x04, 0x78,
0x38, 0x44, 0x44, 0x44, 0x38,
0xFC, 0x18, 0x24, 0x24, 0x18,
0x18, 0x24, 0x24, 0x18, 0xFC,
0x7C, 0x08, 0x04, 0x04, 0x08,
0x48, 0x54, 0x54, 0x54, 0x24,
0x04, 0x04, 0x3F, 0x44, 0x24,
0x3C, 0x40, 0x40, 0x20, 0x7C,
0x1C, 0x20, 0x40, 0x20, 0x1C,
0x3C, 0x40, 0x30, 0x40, 0x3C,
0x44, 0x28, 0x10, 0x28, 0x44,
0x4C, 0x90, 0x90, 0x90, 0x7C,
0x44, 0x64, 0x54, 0x4C, 0x44,
0x00, 0x08, 0x36, 0x41, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00,
0x02, 0x01, 0x02, 0x04, 0x02
};
/*
To create own logos/pictures use online Hex creator from https://javl.github.io/image2cpp/
Create a picture or logo with Paint and output hexfile
divide the hex file into 3 sections of 12,20 and 32 rows and replace the files below to
display own pic
*/
#define ssd1306_swap(a, b) { int16_t t = a; a = b; b = t; }
static uint8_t buffer[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x80, 0x80, 0xc0, 0x70, 0x7c, 0x7c, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0xb3, 0xff, 0xf7,
0xe7, 0xe7, 0x27, 0xf7, 0xff, 0x7f, 0x4f, 0x6f, 0x8f, 0xce, 0xfe, 0xfc, 0xfc, 0xdc, 0x98, 0x18,
0x10, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x20, 0x70,
#if (SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH > 96*16)
0x50, 0x50, 0x90, 0x00, 0xf0, 0xf0, 0x50, 0x50, 0xf0, 0x80, 0x00, 0x00, 0x00, 0xe0, 0xb0, 0x10,
0x10, 0x10, 0x00, 0x00, 0xf0, 0x20, 0x20, 0xe0, 0x00, 0x80, 0xa0, 0xa0, 0xe0, 0x00, 0xc0, 0xe0,
0x20, 0x00, 0xc0, 0x20, 0x20, 0xe0, 0xc0, 0x80, 0xe0, 0xa0, 0xe0, 0x40, 0x00, 0xe0, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x01, 0x01,
0x00, 0x00, 0x01, 0x01, 0x11, 0x08, 0x05, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xbf,
0x7e, 0xfc, 0xf8, 0xf0, 0xf0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc3, 0xe2, 0x01, 0x01, 0xc0, 0x61, 0x21,
0x22, 0x43, 0x01, 0x00, 0xe1, 0x83, 0x82, 0xc2, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x80, 0x01, 0x82,
0x02, 0x01, 0x00, 0x00, 0x63, 0x20, 0xe0, 0xc3, 0x00, 0x01, 0xe2, 0x60, 0xe1, 0x00, 0x01, 0x03,
0x00, 0x00, 0x05, 0x06, 0x00, 0x07, 0x03, 0x00, 0x01, 0x02, 0x01, 0x00, 0x00, 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, 0x2f, 0x10, 0x08,
0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0xfd, 0xf7, 0xb3, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x07, 0x02, 0x00, 0x03, 0x06, 0x04,
0x04, 0x06, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x00, 0x04, 0x07, 0x03, 0x06,
0x00, 0x00, 0x00, 0x00, 0x06, 0x07, 0x05, 0x04, 0x00, 0x07, 0x02, 0x02, 0x03, 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,
#if (SSD1306_LCDHEIGHT == 64)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x05, 0x87, 0x07, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xa0, 0xf8, 0xff, 0xff, 0xdf, 0xdf, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x6f, 0x6f, 0xaf, 0xcf, 0xef, 0xcf, 0x0f, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x08, 0x04, 0x1b, 0x31, 0x20, 0x00, 0x37,
0x25, 0x2d, 0x3b, 0x10, 0x20, 0x33, 0x29, 0x2f, 0x26, 0x0c, 0x3f, 0x21, 0x3f, 0x1e, 0x00, 0x02,
0x3f, 0x1f, 0x00, 0x06, 0x3f, 0x29, 0x3f, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0e, 0x1c, 0x18, 0x18, 0x78,
0x78, 0x1c, 0x0f, 0x07, 0x07, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x03,
0x07, 0x07, 0x07, 0x0f, 0x07, 0x07, 0x87, 0x87, 0xc7, 0xff, 0x7d, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#endif
#endif
};
void ssd1306_command(uint8_t c) {
SSD1306_Start();
SSD1306_Write(_i2caddr);
SSD1306_Write(0);
SSD1306_Write(c);
SSD1306_Stop();
}
void SSD1306_Begin(uint8_t vccstate, uint8_t i2caddr) {
_vccstate = vccstate;
_i2caddr = i2caddr;
#ifdef SSD1306_RST
SSD1306_RST = 0;
#ifdef SSD1306_RST_DIR
SSD1306_RST_DIR = 0;
#endif
delay_ms(10);
SSD1306_RST = 1;
#endif
// init sequence
ssd1306_command(SSD1306_DISPLAYOFF); // 0xAE
ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
ssd1306_command(0x80); // the suggested ratio 0x80
ssd1306_command(SSD1306_SETMULTIPLEX); // 0xA8
ssd1306_command(SSD1306_LCDHEIGHT - 1);
ssd1306_command(SSD1306_SETDISPLAYOFFSET); // 0xD3
ssd1306_command(0x0); // no offset
ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0
ssd1306_command(SSD1306_CHARGEPUMP); // 0x8D
if (vccstate == SSD1306_EXTERNALVCC)
{ ssd1306_command(0x10); }
else
{ ssd1306_command(0x14); }
ssd1306_command(SSD1306_MEMORYMODE); // 0x20
ssd1306_command(0x00); // 0x0 act like ks0108
ssd1306_command(SSD1306_SEGREMAP | 0x1);
ssd1306_command(SSD1306_COMSCANDEC);
#if defined SSD1306_128_32
ssd1306_command(SSD1306_SETCOMPINS); // 0xDA
ssd1306_command(0x02);
ssd1306_command(SSD1306_SETCONTRAST); // 0x81
ssd1306_command(0x8F);
#elif defined SSD1306_128_64
ssd1306_command(SSD1306_SETCOMPINS); // 0xDA
ssd1306_command(0x12);
ssd1306_command(SSD1306_SETCONTRAST); // 0x81
if (vccstate == SSD1306_EXTERNALVCC)
{ ssd1306_command(0x9F); }
else
{ ssd1306_command(0xCF); }
#elif defined SSD1306_96_16
ssd1306_command(SSD1306_SETCOMPINS); // 0xDA
ssd1306_command(0x2); //ada x12
ssd1306_command(SSD1306_SETCONTRAST); // 0x81
if (vccstate == SSD1306_EXTERNALVCC)
{ ssd1306_command(0x10); }
else
{ ssd1306_command(0xAF); }
#endif
ssd1306_command(SSD1306_SETPRECHARGE); // 0xd9
if (vccstate == SSD1306_EXTERNALVCC)
{ ssd1306_command(0x22); }
else
{ ssd1306_command(0xF1); }
ssd1306_command(SSD1306_SETVCOMDETECT); // 0xDB
ssd1306_command(0x40);
ssd1306_command(SSD1306_DISPLAYALLON_RESUME); // 0xA4
ssd1306_command(SSD1306_NORMALDISPLAY); // 0xA6
ssd1306_command(SSD1306_DEACTIVATE_SCROLL);
ssd1306_command(SSD1306_DISPLAYON);//--turn on oled panel
}
void SSD1306_DrawPixel(uint8_t x, uint8_t y) {
if ((x >= SSD1306_LCDWIDTH) || (y >= SSD1306_LCDHEIGHT))
return;
if (SSD1306_Color)
buffer[x + (uint16_t)(y / 8) * SSD1306_LCDWIDTH] |= (1 << (y & 7));
else
buffer[x + (uint16_t)(y / 8) * SSD1306_LCDWIDTH] &= ~(1 << (y & 7));
}
void SSD1306_StartScrollRight(uint8_t start, uint8_t stop) {
ssd1306_command(SSD1306_RIGHT_HORIZONTAL_SCROLL);
ssd1306_command(0X00);
ssd1306_command(start);
ssd1306_command(0X00);
ssd1306_command(stop);
ssd1306_command(0X00);
ssd1306_command(0XFF);
ssd1306_command(SSD1306_ACTIVATE_SCROLL);
}
void SSD1306_StartScrollLeft(uint8_t start, uint8_t stop) {
ssd1306_command(SSD1306_LEFT_HORIZONTAL_SCROLL);
ssd1306_command(0X00);
ssd1306_command(start);
ssd1306_command(0X00);
ssd1306_command(stop);
ssd1306_command(0X00);
ssd1306_command(0XFF);
ssd1306_command(SSD1306_ACTIVATE_SCROLL);
}
void SSD1306_StartScrollDiagRight(uint8_t start, uint8_t stop) {
ssd1306_command(SSD1306_SET_VERTICAL_SCROLL_AREA);
ssd1306_command(0X00);
ssd1306_command(SSD1306_LCDHEIGHT);
ssd1306_command(SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL);
ssd1306_command(0X00);
ssd1306_command(start);
ssd1306_command(0X00);
ssd1306_command(stop);
ssd1306_command(0X01);
ssd1306_command(SSD1306_ACTIVATE_SCROLL);
}
void SSD1306_StartScrollDiagLeft(uint8_t start, uint8_t stop) {
ssd1306_command(SSD1306_SET_VERTICAL_SCROLL_AREA);
ssd1306_command(0X00);
ssd1306_command(SSD1306_LCDHEIGHT);
ssd1306_command(SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL);
ssd1306_command(0X00);
ssd1306_command(start);
ssd1306_command(0X00);
ssd1306_command(stop);
ssd1306_command(0X01);
ssd1306_command(SSD1306_ACTIVATE_SCROLL);
}
void SSD1306_StopScroll(void) {
ssd1306_command(SSD1306_DEACTIVATE_SCROLL);
}
void SSD1306_Dim(bool dim) {
uint8_t contrast;
if (dim)
contrast = 0; // Dimmed display
else {
if (_vccstate == SSD1306_EXTERNALVCC)
contrast = 0x9F;
else
contrast = 0xCF;
}
// the range of contrast to too small to be really useful
// it is useful to dim the display
ssd1306_command(SSD1306_SETCONTRAST);
ssd1306_command(contrast);
}
void SSD1306_Display(void) {
uint16_t i;
uint8_t x;
ssd1306_command(SSD1306_COLUMNADDR);
ssd1306_command(0); // Column start address (0 = reset)
ssd1306_command(SSD1306_LCDWIDTH-1); // Column end address (127 = reset)
ssd1306_command(SSD1306_PAGEADDR);
ssd1306_command(0); // Page start address (0 = reset)
#if SSD1306_LCDHEIGHT == 64
ssd1306_command(7); // Page end address
#endif
#if SSD1306_LCDHEIGHT == 32
ssd1306_command(3); // Page end address
#endif
#if SSD1306_LCDHEIGHT == 16
ssd1306_command(1); // Page end address
#endif
for (i = 0; i < (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT / 8); i++) {
// send a bunch of data in one xmission
SSD1306_Start();
SSD1306_Write(_i2caddr);
SSD1306_Write(0x40);
for (x = 0; x < 16; x++) {
SSD1306_Write(buffer[i]);
i++;
}
i--;
SSD1306_Stop();
}
}
void SSD1306_ClearDisplay(void) {
int16_t i;
for (i = 0; i < (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT / 8); i++)
buffer[i] = 0;
}
void SSD1306_DrawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1) {
bool steep;
int8_t ystep;
uint8_t dx, dy;
int16_t err;
steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) {
ssd1306_swap(x0, y0);
ssd1306_swap(x1, y1);
}
if (x0 > x1) {
ssd1306_swap(x0, x1);
ssd1306_swap(y0, y1);
}
dx = x1 - x0;
dy = abs(y1 - y0);
err = dx / 2;
if (y0 < y1)
ystep = 1;
else
ystep = -1;
for (; x0 <= x1; x0++) {
if (steep)
SSD1306_DrawPixel(y0, x0);
else
SSD1306_DrawPixel(x0, y0);
err -= dy;
if (err < 0) {
y0 += ystep;
err += dx;
}
}
}
void SSD1306_DrawFastHLine(uint8_t x, uint8_t y, uint8_t w) {
SSD1306_DrawLine(x, y, x + w - 1, y);
}
void SSD1306_DrawFastVLine(uint8_t x, uint8_t y, uint8_t h) {
SSD1306_DrawLine(x, y, x, y + h - 1);
}
void SSD1306_FillRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h) {
int16_t i;
for (i = x; i < x + w; i++)
SSD1306_DrawFastVLine(i, y, h);
}
void SSD1306_DrawCircle(int16_t x0, int16_t y0, int16_t r) {
int16_t f = 1 - r;
int16_t ddF_x = 1;
int16_t ddF_y = -2 * r;
int16_t x = 0;
int16_t y = r;
SSD1306_DrawPixel(x0 , y0 + r);
SSD1306_DrawPixel(x0 , y0 - r);
SSD1306_DrawPixel(x0 + r, y0);
SSD1306_DrawPixel(x0 - r, y0);
while (x < y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
SSD1306_DrawPixel(x0 + x, y0 + y);
SSD1306_DrawPixel(x0 - x, y0 + y);
SSD1306_DrawPixel(x0 + x, y0 - y);
SSD1306_DrawPixel(x0 - x, y0 - y);
SSD1306_DrawPixel(x0 + y, y0 + x);
SSD1306_DrawPixel(x0 - y, y0 + x);
SSD1306_DrawPixel(x0 + y, y0 - x);
SSD1306_DrawPixel(x0 - y, y0 - x);
}
}
void SSD1306_DrawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername) {
int16_t f = 1 - r;
int16_t ddF_x = 1;
int16_t ddF_y = -2 * r;
int16_t x = 0;
int16_t y = r;
while (x < y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
if (cornername & 0x4) {
SSD1306_DrawPixel(x0 + x, y0 + y);
SSD1306_DrawPixel(x0 + y, y0 + x);
}
if (cornername & 0x2) {
SSD1306_DrawPixel(x0 + x, y0 - y);
SSD1306_DrawPixel(x0 + y, y0 - x);
}
if (cornername & 0x8) {
SSD1306_DrawPixel(x0 - y, y0 + x);
SSD1306_DrawPixel(x0 - x, y0 + y);
}
if (cornername & 0x1) {
SSD1306_DrawPixel(x0 - y, y0 - x);
SSD1306_DrawPixel(x0 - x, y0 - y);
}
}
}
void SSD1306_FillCircle(int16_t x0, int16_t y0, int16_t r) {
SSD1306_DrawFastVLine(x0, y0 - r, 2 * r + 1);
SSD1306_FillCircleHelper(x0, y0, r, 3, 0);
}
// Used to do circles and roundrects
void SSD1306_FillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta) {
int16_t f = 1 - r;
int16_t ddF_x = 1;
int16_t ddF_y = -2 * r;
int16_t x = 0;
int16_t y = r;
while (x < y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
if (cornername & 0x01) {
SSD1306_DrawFastVLine(x0 + x, y0 - y, 2 * y + 1 + delta);
SSD1306_DrawFastVLine(x0 + y, y0 - x, 2 * x + 1 + delta);
}
if (cornername & 0x02) {
SSD1306_DrawFastVLine(x0 - x, y0 - y, 2 * y + 1 + delta);
SSD1306_DrawFastVLine(x0 - y, y0 - x, 2 * x + 1 + delta);
}
}
}
// Draw a rectangle
void SSD1306_DrawRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h) {
SSD1306_DrawFastHLine(x, y, w);
SSD1306_DrawFastHLine(x, y + h - 1, w);
SSD1306_DrawFastVLine(x, y, h);
SSD1306_DrawFastVLine(x + w - 1, y, h);
}
// Draw a rounded rectangle
void SSD1306_DrawRoundRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t r) {
// smarter version
SSD1306_DrawFastHLine(x + r, y, w - 2 * r); // Top
SSD1306_DrawFastHLine(x + r, y + h - 1, w - 2 * r); // Bottom
SSD1306_DrawFastVLine(x, y + r, h - 2 * r); // Left
SSD1306_DrawFastVLine(x + w - 1, y + r, h - 2 * r); // Right
// draw four corners
SSD1306_DrawCircleHelper(x + r, y + r, r, 1);
SSD1306_DrawCircleHelper(x + w - r - 1, y + r, r, 2);
SSD1306_DrawCircleHelper(x + w - r - 1, y + h - r - 1, r, 4);
SSD1306_DrawCircleHelper(x + r, y + h - r - 1, r, 8);
}
// Fill a rounded rectangle
void SSD1306_FillRoundRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t r) {
// smarter version
SSD1306_FillRect(x + r, y, w - 2 * r, h);
// draw four corners
SSD1306_FillCircleHelper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1);
SSD1306_FillCircleHelper(x + r , y + r, r, 2, h - 2 * r - 1);
}
// Draw a triangle
void SSD1306_DrawTriangle(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
SSD1306_DrawLine(x0, y0, x1, y1);
SSD1306_DrawLine(x1, y1, x2, y2);
SSD1306_DrawLine(x2, y2, x0, y0);
}
// Fill a triangle
void SSD1306_FillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2) {
int16_t a, b, y, last,
dx01 = x1 - x0,
dy01 = y1 - y0,
dx02 = x2 - x0,
dy02 = y2 - y0,
dx12 = x2 - x1,
dy12 = y2 - y1;
int32_t sa = 0, sb = 0;
// Sort coordinates by Y order (y2 >= y1 >= y0)
if (y0 > y1) {
ssd1306_swap(y0, y1); ssd1306_swap(x0, x1);
}
if (y1 > y2) {
ssd1306_swap(y2, y1); ssd1306_swap(x2, x1);
}
if (y0 > y1) {
ssd1306_swap(y0, y1); ssd1306_swap(x0, x1);
}
if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing
a = b = x0;
if(x1 < a) a = x1;
else if(x1 > b) b = x1;
if(x2 < a) a = x2;
else if(x2 > b) b = x2;
SSD1306_DrawFastHLine(a, y0, b - a + 1);
return;
}
if(y1 == y2) last = y1; // Include y1 scanline
else last = y1 - 1; // Skip it
for(y = y0; y <= last; y++) {
a = x0 + sa / dy01;
b = x0 + sb / dy02;
sa += dx01;
sb += dx02;
/* longhand:
a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
*/
if(a > b) ssd1306_swap(a, b);
SSD1306_DrawFastHLine(a, y, b - a + 1);
}
// For lower part of triangle, find scanline crossings for segments
// 0-2 and 1-2. This loop is skipped if y1=y2.
sa = dx12 * (y - y1);
sb = dx02 * (y - y0);
for(; y <= y2; y++) {
a = x1 + sa / dy12;
b = x0 + sb / dy02;
sa += dx12;
sb += dx02;
/* longhand:
a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
*/
if(a > b) ssd1306_swap(a, b);
SSD1306_DrawFastHLine(a, y, b - a + 1);
}
}
void SSD1306_FillScreen() {
uint16_t i;
for (i = 0; i < (SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT) / 8; i++)
buffer[i] = 0xFF;
}
void SSD1306_SetTextWrap(bool w) {
wrap = w;
}
// invert the display
void SSD1306_InvertDisplay(bool i) {
if (i)
ssd1306_command(SSD1306_INVERTDISPLAY_);
else
ssd1306_command(SSD1306_NORMALDISPLAY);
}
// set text size
void SSD1306_TextSize(uint8_t t_size)
{
if(t_size < 1)
t_size = 1;
text_size = t_size;
}
// move cursor to position (x, y)
void SSD1306_GotoXY(uint8_t x, uint8_t y)
{
if((x >= SSD1306_LCDWIDTH) || (y >= SSD1306_LCDHEIGHT))
return;
x_pos = x;
y_pos = y;
}
/* print single char
\a Set cursor position to upper left (0, 0)
\b Move back one position
\n Go to start of current line
\r Go to line below
*/
void SSD1306_PutC(uint8_t c) {
uint8_t i, j, line;
if(c == '\a') {
x_pos = y_pos = 0;
return;
}
if( (c == '\b') && (x_pos >= text_size * 6) ) {
x_pos -= text_size * 6;
return;
}
if(c == '\r') {
x_pos = 0;
return;
}
if(c == '\n') {
y_pos += text_size * 8;
if((y_pos + text_size * 7) >= SSD1306_LCDHEIGHT)
y_pos = 0;
return;
}
if((c < ' ') || (c > '~'))
c = '?';
for(i = 0; i < 5; i++ ) {
line = font[(c - 32) * 5 + i];
for(j = 0; j < 7; j++, line >>= 1) {
if(line & 0x01)
SSD1306_Color = true;
else
SSD1306_Color = false;
if(text_size == 1) SSD1306_DrawPixel(x_pos + i, y_pos + j);
else SSD1306_FillRect(x_pos + (i * text_size), y_pos + (j * text_size), text_size, text_size);
}
}
SSD1306_Color = false;
SSD1306_FillRect(x_pos + (5 * text_size), y_pos, text_size, 7 * text_size);
x_pos += text_size * 6;
if (wrap && (x_pos + (text_size * 5)) >= SSD1306_LCDWIDTH)
{
x_pos = 0;
y_pos += text_size * 8;
if((y_pos + text_size * 7) >= SSD1306_LCDHEIGHT)
y_pos = 0;
}
}
// print text
void SSD1306_Print(char *s) {
uint8_t i = 0;
while (s[i] != '\0'){
if (s[i] == ' ' && x_pos == 0 && wrap)
i++;
else
SSD1306_PutC(s[i++]);
}
}
// print custom char (dimension: 7x5 pixel)
void SSD1306_PutCustomC(const uint8_t *c) {
uint8_t i, j, line;
for(i = 0; i < 5; i++ ) {
line = c[i];
for(j = 0; j < 7; j++, line >>= 1) {
if(line & 0x01)
SSD1306_Color = 1;
else
SSD1306_Color = 0;
if(text_size == 1) SSD1306_DrawPixel(x_pos + i, y_pos + j);
else SSD1306_FillRect(x_pos + (i * text_size), y_pos + (j * text_size), text_size, text_size);
}
}
x_pos += (text_size * 6);
if (wrap && (x_pos + (text_size * 5)) >= SSD1306_LCDWIDTH)
{
x_pos = 0;
y_pos += text_size * 8;
if((y_pos + text_size * 7) >= SSD1306_LCDHEIGHT)
y_pos = 0;
}
}
// draw BMP stored in ROM
void SSD1306_DrawBMP(uint8_t x, uint8_t y, const uint8_t *bitmap, uint8_t w, uint8_t h)
{
uint16_t j;
uint8_t i, k;
for (j = 0; j < h/8; j++) {
for(i = 0; i < w; i++) {
for(k = 0; k < 8; k++) {
if( bitmap[i + j*w] & 1 << k)
SSD1306_Color = true;
else
SSD1306_Color = false;
SSD1306_DrawPixel(x + i, y + j*8 + k);
}
}
}
}
// end of driver code.