/* Three-Channel Chart Plotter - see http://www.technoblogy.com/show?3XEI David Johnson-Davies - www.technoblogy.com - 14th June 2022 ATtiny402/412 @ 20 MHz (internal oscillator; BOD disabled) CC BY 4.0 Licensed under a Creative Commons Attribution 4.0 International license: http://creativecommons.org/licenses/by/4.0/ */ #include //#define SSD1306 // Constants #if defined(SSD1306) int const address = 61; int const offset = 0; #else int const address = 60; int const offset = 2; #endif int const commands = 0x00; int const onecommand = 0x80; int const data = 0x40; int const onedata = 0xC0; // OLED display ********************************************** // Initialisation sequence for OLED module int const InitLen = 8; const uint8_t Init[InitLen] PROGMEM = { 0x8D, // Charge pump 0x14, 0xA1, // Flip horizontally 0x81, // Set contrast 0xCF, // brighter 0xDB, // Set vcom detect 0x40, // brighter 0xAF // Display on }; void InitDisplay () { TinyI2C.start(address, 0); TinyI2C.write(commands); for (uint8_t i=0; i>4); // Column start high TinyI2C.write(0xB0 | (page & 0x07)); // Page start TinyI2C.restart(address, 0); TinyI2C.write(data); TinyI2C.write(byte); TinyI2C.stop(); } void ClearDisplay () { for (int page=0; page<8; page++) { TinyI2C.start(address, 0); TinyI2C.write(onecommand); TinyI2C.write(0xB0 | (page & 0x07)); // Page start TinyI2C.stop(); TinyI2C.start(address, 0); TinyI2C.write(data); for (int i=0; i<132; i++) TinyI2C.write(0); // SH1106 is 132 columns TinyI2C.stop(); } } void SetStartLine (uint8_t line) { TinyI2C.start(address, 0); TinyI2C.write(onecommand); TinyI2C.write(0x40 | line); TinyI2C.stop(); } // Chart Plotter ********************************************** /* // Take a reading between 0 and 41 int Reading (uint8_t chart) { uint8_t pin = chart; if (chart == 2) pin = 4; return (analogRead(pin)+12)/25; } */ // Demo plots three waveforms int Reading (uint8_t chart) { static int x = 0, y = 18<<8, j = 20, i = 2, u = 0, v = 18<<8; if (chart == 0) { x = x + y/5; y = y - x/5; return (x>>8)+20; } else if (chart == 1) { j = j + i; if (j >= 36 || j <= 4) i = -i; return j; } else { u = u + v/10; v = v - u/10; return (u>>9)+(x>>9)+21; } } void DrawDividers () { for (int p = 0; p<8; p++) { PlotByte (0xFF, p, 42); PlotByte (0xFF, p, 85); } } uint8_t Position[3][8][8]; void Plot (uint8_t newvalue, uint8_t row, uint8_t chart) { newvalue = newvalue + 1; uint8_t page = row>>3, bit = row & 0x07; // Only change column corresponding to old and new values uint8_t oldvalue = Position[chart][page][bit]; Position[chart][page][bit] = newvalue; uint8_t oldbyte = 0, newbyte = 0; for (int b=0; b<8; b++) { uint8_t pos = Position[chart][page][b]; if (pos == oldvalue) oldbyte = oldbyte | 1<