From 98882b6cc388d7031af085794bb77a712b1c326d Mon Sep 17 00:00:00 2001 From: wagiminator Date: Sat, 27 Mar 2021 21:50:46 +0100 Subject: [PATCH] Update files --- software/USB_Tester_v1.0.ino | 173 ------------- software/USB_Tester_v1.1.ino | 210 ---------------- software/USB_Tester_v1.2.ino | 459 ----------------------------------- software/font8x16a.h | 60 ----- 4 files changed, 902 deletions(-) delete mode 100644 software/USB_Tester_v1.0.ino delete mode 100644 software/USB_Tester_v1.1.ino delete mode 100644 software/USB_Tester_v1.2.ino delete mode 100644 software/font8x16a.h diff --git a/software/USB_Tester_v1.0.ino b/software/USB_Tester_v1.0.ino deleted file mode 100644 index 4670153..0000000 --- a/software/USB_Tester_v1.0.ino +++ /dev/null @@ -1,173 +0,0 @@ -// USB Power Tester - Basic -// -// This code implements the basic functionality for the USB Power Tester. -// It reads voltage, current and power from the INA219, calculates capacity -// and shows the values on the OLED. It uses a reduced character set in order -// to make it fit on an ATtiny45. The SET button is used to switch between -// the "recent value screen" and the "min/max value screen". -// -// +-\/-+ -// RESET --- A0 (D5) PB5 1| |8 Vcc -// SET ----- A3 (D3) PB3 2| |7 PB2 (D2) A1 ---- OLED/INA (SCK) -// A2 (D4) PB4 3| |6 PB1 (D1) -// GND 4| |5 PB0 (D0) ------- OLED/INA (SDA) -// +----+ -// -// Controller: ATtiny45/85 -// Core: ATTinyCore (https://github.com/SpenceKonde/ATTinyCore) -// Clockspeed: 8 MHz internal -// Millis: enabled -// -// 2020 by Stefan Wagner (https://easyeda.com/wagiminator) -// License: http://creativecommons.org/licenses/by-sa/3.0/ - - -//Libraries -#include // https://github.com/technoblogy/tiny-i2c -#include // https://github.com/datacute/Tiny4kOLED -#include // for using data in program space -#include "font8x16a.h" // reduced character set - -// Pin definitions -#define SETBUTTON 3 - -// INA219 register values -#define INA_ADDR 0b01000000 // I2C address of INA219 -#define INA_CONFIG 0b0000011001100111 // INA config register according to datasheet -#define INA_CALIB 5120 // INA calibration register according to R_SHUNT -#define CONFIG_REG 0x00 // INA configuration register address -#define CALIB_REG 0x05 // INA calibration register address -#define SHUNT_REG 0x01 // INA shunt voltage register address -#define VOLTAGE_REG 0x02 // INA bus voltage register address -#define POWER_REG 0x03 // INA power register address -#define CURRENT_REG 0x04 // INA current register address - -// Conversions for the reduced character set -#define mV ".,*" -#define mA ".+*" -#define mW ".-*" -#define mAh ".+/" -#define SEP "*)*" -#define SPACE "*" - -// Variables (voltage in mV, current in mA, power in mW) -uint16_t voltage, current, power; -uint16_t minvoltage = 65535, maxvoltage = 0; -uint16_t mincurrent = 65535, maxcurrent = 0; -uint32_t lastmillis, nowmillis, interval; -uint32_t capacity = 0; -bool primescreen = true; -bool lastbutton = true; - - -void setup() { - // setup pins - DDRB = 0; // all pins input now - PORTB = bit (SETBUTTON); // pullup for set button - - // start I2C - TinyI2C.init(); - - // start INA219 - initINA(); - - // start OLED - oled.begin(); - oled.setFont(FONT8X16A); - oled.clear(); - oled.on(); - oled.switchRenderFrame(); - - // init some variables - lastmillis = millis(); -} - -void loop() { - // read voltage, current and power from INA219 - updateINA(); - - // update min/max values - if (minvoltage > voltage) minvoltage = voltage; - if (maxvoltage < voltage) maxvoltage = voltage; - if (mincurrent > current) mincurrent = current; - if (maxcurrent < current) maxcurrent = current; - - // calculate power in mW - power = (uint32_t)voltage * current / 1000; - - // calculate capacity in uAh - nowmillis = millis(); - interval = nowmillis - lastmillis; // calculate time interval - lastmillis = nowmillis; - capacity += interval * current / 3600; // calculate uAh - - // check button - if (bitRead(PINB, SETBUTTON)) lastbutton = false; - else if (!lastbutton) { - primescreen = !primescreen; - lastbutton = true; - } - - // display values on the oled - oled.clear(); - oled.setCursor(0, 0); - if (primescreen) { - printValue(voltage); oled.print(F(mV)); - printValue(power); oled.print(F(mW)); - printValue(current); oled.print(F(mA)); - printValue(capacity / 1000); oled.print(F(mAh)); - } else { - printValue(minvoltage); oled.print(F(SEP)); printValue(maxvoltage); oled.print(F(mV)); - printValue(mincurrent); oled.print(F(SEP)); printValue(maxcurrent); oled.print(F(mA)); - } - oled.switchFrame(); - - // a little delay - delay(100); -} - - -// writes a register value to the INA219 -void writeRegister(uint8_t reg, uint16_t value) { - TinyI2C.start(INA_ADDR, 0); - TinyI2C.write(reg); - TinyI2C.write((value >> 8) & 0xff); - TinyI2C.write(value & 0xff); - TinyI2C.stop(); -} - -// reads a register from the INA219 -uint16_t readRegister(uint8_t reg) { - uint16_t result; - TinyI2C.start(INA_ADDR, 0); - TinyI2C.write(reg); - TinyI2C.restart(INA_ADDR, 2); - result = (uint16_t)(TinyI2C.read() << 8) | TinyI2C.read(); - TinyI2C.stop(); - return(result); -} - -// writes inital configuration and calibration values to the INA -void initINA() { - writeRegister(CONFIG_REG, INA_CONFIG); - writeRegister(CALIB_REG, INA_CALIB); -} - -// read sensor values from INA219 -void updateINA() { - voltage = (readRegister(VOLTAGE_REG) >> 1) & 0xfffc; - current = readRegister(CURRENT_REG); - if (current > 32767) current = 0; - //power = readRegister(POWER_REG) * 20; -} - -// prints 5-digit value right aligned -void printValue(uint16_t value) { - uint32_t counter = value; - if (counter == 0) counter = 1; - while (counter < 10000) { - oled.print(SPACE); - counter *= 10; - } - oled.print(value); -} diff --git a/software/USB_Tester_v1.1.ino b/software/USB_Tester_v1.1.ino deleted file mode 100644 index c57ff9b..0000000 --- a/software/USB_Tester_v1.1.ino +++ /dev/null @@ -1,210 +0,0 @@ -// USB Power Tester - Basic -// -// This code implements the basic functionality for the USB Power Tester. -// It reads voltage, current and power from the INA219, calculates capacity -// and shows the values on the OLED. It uses a reduced character set in order -// to make it fit on an ATtiny45. The SET button is used to switch between -// the "recent value screen" and the "min/max value screen". -// -// +-\/-+ -// RESET --- A0 (D5) PB5 1| |8 Vcc -// SET ----- A3 (D3) PB3 2| |7 PB2 (D2) A1 ---- OLED/INA (SCK) -// A2 (D4) PB4 3| |6 PB1 (D1) -// GND 4| |5 PB0 (D0) ------- OLED/INA (SDA) -// +----+ -// -// Controller: ATtiny45/85 -// Core: ATTinyCore (https://github.com/SpenceKonde/ATTinyCore) -// Clockspeed: 8 MHz internal -// Millis: enabled -// -// 2020 by Stefan Wagner (https://easyeda.com/wagiminator) -// License: http://creativecommons.org/licenses/by-sa/3.0/ - - -//Libraries -#include // https://github.com/technoblogy/tiny-i2c -#include // https://github.com/datacute/Tiny4kOLED -#include // for using data in program space -#include "font8x16a.h" // reduced character set - -// Pin definitions -#define SETBUTTON 3 - -// INA219 register values -#define INA_ADDR 0b01000000 // I2C address of INA219 -#define INA_CONFIG 0b0000011001100111 // INA config register according to datasheet -#define INA_CALIB 5120 // INA calibration register according to R_SHUNT -#define CONFIG_REG 0x00 // INA configuration register address -#define CALIB_REG 0x05 // INA calibration register address -#define SHUNT_REG 0x01 // INA shunt voltage register address -#define VOLTAGE_REG 0x02 // INA bus voltage register address -#define POWER_REG 0x03 // INA power register address -#define CURRENT_REG 0x04 // INA current register address - -// Conversions for the reduced character set -#define mV ".,*" -#define mA ".+*" -#define mW ".-*" -#define mAh ".+/" -#define mWh ".-/" -#define SEP "*)*" -#define SPACE '*' -#define ZERO '0' -#define DECIMAL "(" -#define AVERAGE ";*" - -// Variables (voltage in mV, current in mA, power in mW) -uint16_t voltage, current, power; -uint16_t minvoltage = 65535, maxvoltage = 0; -uint16_t mincurrent = 65535, maxcurrent = 0; -uint16_t minpower = 65535, maxpower = 0; -uint32_t startmillis, lastmillis, nowmillis, interval, duration, seconds; -uint32_t capacity = 0, energy = 0; -uint8_t primescreen = 0; -bool lastbutton = true; - - -void setup() { - // setup pins - DDRB = 0; // all pins input now - PORTB = bit (SETBUTTON); // pullup for set button - - // start I2C - TinyI2C.init(); - - // start INA219 - initINA(); - - // start OLED - oled.begin(); - oled.setFont(FONT8X16A); - oled.clear(); - oled.on(); - oled.switchRenderFrame(); - - // init some variables - startmillis = millis(); - lastmillis = startmillis; -} - -void loop() { - // read voltage, current and power from INA219 - updateINA(); - - // calculate power in mW - power = (uint32_t)voltage * current / 1000; - - // calculate capacity in uAh and energy in uWh - nowmillis = millis(); - interval = nowmillis - lastmillis; // calculate time interval - duration = nowmillis - startmillis; // calculate total duration - seconds = duration / 1000; // calculate total seconds - lastmillis = nowmillis; - capacity += interval * current / 3600; // calculate uAh - energy += interval * power / 3600; // calculate uWh - - // update min/max values - if (minvoltage > voltage) minvoltage = voltage; - if (maxvoltage < voltage) maxvoltage = voltage; - if (mincurrent > current) mincurrent = current; - if (maxcurrent < current) maxcurrent = current; - if (minpower > power ) minpower = power; - if (maxpower < power ) maxpower = power; - - // check button - if (bitRead(PINB, SETBUTTON)) lastbutton = false; - else if (!lastbutton) { - if (++primescreen > 4) primescreen = 0; - lastbutton = true; - } - - // display values on the oled - oled.clear(); - oled.setCursor(0, 0); - switch (primescreen) { - case 0: printValue(voltage); oled.print(F(mV)); - printValue(power); oled.print(F(mW)); - printValue(current); oled.print(F(mA)); - printValue(capacity / 1000); oled.print(F(mAh)); - break; - case 1: printValue(minvoltage); oled.print(F(SEP)); - printValue(maxvoltage); oled.print(F(mV)); - printValue(mincurrent); oled.print(F(SEP)); - printValue(maxcurrent); oled.print(F(mA)); - break; - case 2: oled.setCursor(0, 1); - printValue(minpower); oled.print(F(SEP)); - printValue(maxpower); oled.print(F(mW)); - break; - case 3: printDigits(capacity / 1000, 7, SPACE); oled.print(F(DECIMAL)); - printDigits(capacity % 1000, 3, ZERO); oled.print(F(mAh)); - oled.setCursor(0, 2); - printDigits(energy / 1000, 7, SPACE); oled.print(F(DECIMAL)); - printDigits(energy % 1000, 3, ZERO); oled.print(F(mWh)); - break; - case 4: oled.setCursor(32, 1); - printDigits(seconds / 3600, 2, ZERO); oled.print(F(":")); - seconds %= 3600; - printDigits(seconds / 60, 2, ZERO); oled.print(F(":")); - printDigits(seconds % 60, 2, ZERO); - break; - default: break; - } - oled.switchFrame(); - - // a little delay - delay(100); -} - - -// writes a register value to the INA219 -void writeRegister(uint8_t reg, uint16_t value) { - TinyI2C.start(INA_ADDR, 0); - TinyI2C.write(reg); - TinyI2C.write((value >> 8) & 0xff); - TinyI2C.write(value & 0xff); - TinyI2C.stop(); -} - -// reads a register from the INA219 -uint16_t readRegister(uint8_t reg) { - uint16_t result; - TinyI2C.start(INA_ADDR, 0); - TinyI2C.write(reg); - TinyI2C.restart(INA_ADDR, 2); - result = (uint16_t)(TinyI2C.read() << 8) | TinyI2C.read(); - TinyI2C.stop(); - return(result); -} - -// writes inital configuration and calibration values to the INA -void initINA() { - writeRegister(CONFIG_REG, INA_CONFIG); - writeRegister(CALIB_REG, INA_CALIB); -} - -// read sensor values from INA219 -void updateINA() { - voltage = (readRegister(VOLTAGE_REG) >> 1) & 0xfffc; - current = readRegister(CURRENT_REG); - if (current > 32767) current = 0; -} - -// prints 5-digit value right aligned -void printValue(uint16_t value) { - printDigits(value, 5, SPACE); -} - -// prints value right aligned -void printDigits(uint32_t value, uint8_t digits, char filler) { - uint32_t counter = value; - if (counter == 0) counter = 1; - uint32_t limit = 1; - while (--digits) limit *= 10; - while (counter < limit) { - oled.print(filler); - counter *= 10; - } - oled.print(value); -} diff --git a/software/USB_Tester_v1.2.ino b/software/USB_Tester_v1.2.ino deleted file mode 100644 index c5252e2..0000000 --- a/software/USB_Tester_v1.2.ino +++ /dev/null @@ -1,459 +0,0 @@ -// USB Power Tester - Basic -// -// This code implements the basic functionality for the USB Power Tester. -// It reads voltage, current and power from the INA219, calculates -// capacity and shows the values on the OLED. The SET button is used to -// switch between different screens. -// -// +-\/-+ -// RESET --- A0 (D5) PB5 1| |8 Vcc -// SET ----- A3 (D3) PB3 2| |7 PB2 (D2) A1 ---- OLED/INA (SCK) -// A2 (D4) PB4 3| |6 PB1 (D1) -// GND 4| |5 PB0 (D0) ------- OLED/INA (SDA) -// +----+ -// -// Core: ATtinyCore (https://github.com/SpenceKonde/ATTinyCore) -// Board: ATtiny25/45/85 (No bootloader) -// Chip: ATtiny45 or 85 (depending on your chip) -// Clock: 8 MHz (internal) -// Millis: disabled -// B.O.D.: 2.7V -// Leave the rest on default settings. Don't forget to "Burn bootloader" ! -// -// The I²C OLED implementation is based on TinyOLEDdemo -// https://github.com/wagiminator/ATtiny13-TinyOLEDdemo -// -// 2020 by Stefan Wagner -// Project Files (EasyEDA): https://easyeda.com/wagiminator -// Project Files (Github): https://github.com/wagiminator -// License: http://creativecommons.org/licenses/by-sa/3.0/ - - -// Libraries -#include -#include -#include -#include - -// Pin definitions -#define I2C_SDA PB0 // I2C serial data pin -#define I2C_SCL PB2 // I2C serial clock pin -#define SETBUTTON PB3 // SET button - -// ----------------------------------------------------------------------------- -// I2C Implementation -// ----------------------------------------------------------------------------- - -// I2C macros -#define I2C_SDA_HIGH() DDRB &= ~(1< pulled HIGH by resistor -#define I2C_SDA_LOW() DDRB |= (1< pulled LOW by MCU -#define I2C_SCL_HIGH() DDRB &= ~(1< pulled HIGH by resistor -#define I2C_SCL_LOW() DDRB |= (1< pulled LOW by MCU -#define I2C_SDA_READ() (PINB & (1< lines released - PORTB &= ~((1< slave reads the bit - } - I2C_DELAY(); // delay 3 clock cycles - I2C_SDA_HIGH(); // release SDA for ACK bit of slave - I2C_CLOCKOUT(); // 9th clock pulse is for the ignored ACK bit -} - -// I2C start transmission -void I2C_start(uint8_t addr) { - I2C_SDA_LOW(); // start condition: SDA goes LOW first - I2C_SCL_LOW(); // start condition: SCL goes LOW second - I2C_write(addr); // send slave address -} - -// I2C restart transmission -void I2C_restart(uint8_t addr) { - I2C_SDA_HIGH(); // prepare SDA for HIGH to LOW transition - I2C_SCL_HIGH(); // restart condition: clock HIGH - I2C_start(addr); // start again -} - -// I2C stop transmission -void I2C_stop(void) { - I2C_SDA_LOW(); // prepare SDA for LOW to HIGH transition - I2C_SCL_HIGH(); // stop condition: SCL goes HIGH first - I2C_SDA_HIGH(); // stop condition: SDA goes HIGH second -} - -// I2C receive one data byte from the slave (ack=0 for last byte, ack>0 if more bytes to follow) -uint8_t I2C_read(uint8_t ack) { - uint8_t data = 0; // variable for the received byte - I2C_SDA_HIGH(); // release SDA -> will be toggled by slave - for(uint8_t i=8; i; i--) { // receive 8 bits - data<<=1; // bits shifted in right (MSB first) - I2C_DELAY(); // delay 3 clock cycles - I2C_SCL_HIGH(); // clock HIGH - if(I2C_SDA_READ()) data |=1; // read bit - I2C_SCL_LOW(); // clock LOW -> slave prepares next bit - } - if (ack) I2C_SDA_LOW(); // pull SDA LOW to acknowledge (ACK) - I2C_DELAY(); // delay 3 clock cycles - I2C_CLOCKOUT(); // clock out -> slave reads ACK bit - return(data); // return the received byte -} - -// ----------------------------------------------------------------------------- -// OLED Implementation -// ----------------------------------------------------------------------------- - -// OLED definitions -#define OLED_ADDR 0x78 // OLED write address -#define OLED_CMD_MODE 0x00 // set command mode -#define OLED_DAT_MODE 0x40 // set data mode -#define OLED_INIT_LEN 11 // 9: no screen flip, 11: screen flip - -// OLED init settings -const uint8_t OLED_INIT_CMD[] PROGMEM = { - 0xA8, 0x1F, // set multiplex for 128x32 - 0x20, 0x01, // set vertical memory addressing mode - 0xDA, 0x02, // set COM pins hardware configuration to sequential - 0x8D, 0x14, // enable charge pump - 0xAF, // switch on OLED - 0xA1, 0xC8 // flip the screen -}; - -// OLED 6x16 font -const uint8_t OLED_FONT[] PROGMEM = { - 0x7C, 0x1F, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x7C, 0x1F, // 0 0 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x1F, // 1 1 - 0x00, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x00, // 2 2 - 0x00, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, // 3 3 - 0x7C, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x7C, 0x1F, // 4 4 - 0x7C, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x00, 0x1F, // 5 5 - 0x7C, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x00, 0x1F, // 6 6 - 0x7C, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7C, 0x1F, // 7 7 - 0x7C, 0x1F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, // 8 8 - 0x7C, 0x00, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x7C, 0x1F, // 9 9 - 0x00, 0x00, 0xF0, 0x3F, 0x8C, 0x00, 0x82, 0x00, 0x8C, 0x00, 0xF0, 0x3F, // 10 A - 0x00, 0x00, 0xFE, 0x07, 0x00, 0x18, 0x00, 0x20, 0x00, 0x18, 0xFE, 0x07, // 11 V - 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x20, 0x00, 0x1F, 0x00, 0x20, 0xFE, 0x1F, // 12 W - 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x01, 0x80, 0x00, 0x80, 0x00, 0x00, 0x3F, // 13 h - 0x00, 0x00, 0x80, 0x3F, 0x80, 0x00, 0x80, 0x3F, 0x80, 0x00, 0x00, 0x3F, // 14 m - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, // 15 . - 0x00, 0x00, 0x00, 0x00, 0x30, 0x06, 0x30, 0x06, 0x00, 0x00, 0x00, 0x00, // 16 : - 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, // 17 - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 18 SPACE -}; - -// Character definitions -#define DECIMAL 15 -#define COLON 16 -#define SPACE 18 - -// For BCD conversion -const uint16_t divider[5] = {10000, 1000, 100, 10, 1}; - -// OLED init function -void OLED_init(void) { - I2C_start(OLED_ADDR); // start transmission to OLED - I2C_write(OLED_CMD_MODE); // set command mode - for (uint8_t i=0; i> 4)); // set high nibble of start column - I2C_write(0xB0 | (ypos)); // set start page - I2C_stop(); // stop transmission -} - -// OLED clear screen -void OLED_clearScreen(void) { - OLED_setCursor(0, 0); // set cursor at upper half - I2C_start(OLED_ADDR); // start transmission to OLED - I2C_write(OLED_DAT_MODE); // set data mode - uint8_t i = 0; // count variable - do {I2C_write(0x00);} while (--i); // clear upper half - I2C_stop(); // stop transmission - OLED_setCursor(0, 2); // set cursor at lower half - I2C_start(OLED_ADDR); // start transmission to OLED - I2C_write(OLED_DAT_MODE); // set data mode - do {I2C_write(0x00);} while (--i); // clear upper half - I2C_stop(); // stop transmission -} - -// OLED plot a character -void OLED_plotChar(uint8_t ch) { - ch = (ch << 3) + (ch << 2); // calculate position of character in font array - I2C_write(0x00); I2C_write(0x00); // print spacing between characters - for(uint8_t i=12; i; i--) I2C_write(pgm_read_byte(&OLED_FONT[ch++])); // print character - I2C_write(0x00); I2C_write(0x00); // print spacing between characters -} - -// OLED print a character -void OLED_printChar(uint8_t ch) { - I2C_start(OLED_ADDR); // start transmission to OLED - I2C_write(OLED_DAT_MODE); // set data mode - OLED_plotChar(ch); // plot the character - I2C_stop(); // stop transmission -} - -// OLED print a string from program memory; terminator: 255 -void OLED_printPrg(const uint8_t* p) { - I2C_start(OLED_ADDR); // start transmission to OLED - I2C_write(OLED_DAT_MODE); // set data mode - uint8_t ch = pgm_read_byte(p); // read first character from program memory - while (ch < 255) { // repeat until string terminator - OLED_plotChar(ch); // plot character on OLED - ch = pgm_read_byte(++p); // read next character - } - I2C_stop(); // stop transmission -} - -// OLED print 16-bit value as 5-digit decimal (BCD conversion by substraction method) -void OLED_printDec16(uint16_t value) { - uint8_t leadflag = 0; // flag for leading spaces - I2C_start(OLED_ADDR); // start transmission to OLED - I2C_write(OLED_DAT_MODE); // set data mode - for(uint8_t digit = 0; digit < 5; digit++) { // 5 digits - uint8_t digitval = 0; // start with digit value 0 - while (value >= divider[digit]) { // if current divider fits into the value - leadflag = 1; // end of leading spaces - digitval++; // increase digit value - value -= divider[digit]; // decrease value by divider - } - if (leadflag || (digit == 4)) OLED_plotChar(digitval); // print the digit - else OLED_plotChar(SPACE); // or print leading space - } - I2C_stop(); // stop transmission -} - -// OLED print 16-bit value as 3-digit decimal (BCD conversion by substraction method) -void OLED_printDec12(uint16_t value) { - I2C_start(OLED_ADDR); // start transmission to OLED - I2C_write(OLED_DAT_MODE); // set data mode - for(uint8_t digit = 2; digit < 5; digit++) { // 3 digits - uint8_t digitval = 0; // start with digit value 0 - while (value >= divider[digit]) { // if current divider fits into the value - digitval++; // increase digit value - value -= divider[digit]; // decrease value by divider - } - OLED_plotChar(digitval); // print the digit - } - I2C_stop(); // stop transmission -} - -// OLED print 8-bit value as 2-digit decimal (BCD conversion by substraction method) -void OLED_printDec8(uint8_t value) { - I2C_start(OLED_ADDR); // start transmission to OLED - I2C_write(OLED_DAT_MODE); // set data mode - uint8_t digitval = 0; // start with digit value 0 - while (value >= 10) { // if current divider fits into the value - digitval++; // increase digit value - value -= 10; // decrease value by divider - } - OLED_plotChar(digitval); // print first digit - OLED_plotChar(value); // print second digit - I2C_stop(); // stop transmission -} - -// ----------------------------------------------------------------------------- -// INA219 Implementation -// ----------------------------------------------------------------------------- - -// INA219 register values -#define INA_ADDR 0x80 // I2C write address of INA219 -#define INA_CONFIG 0b0000011001100111 // INA config register according to datasheet -#define INA_CALIB 5120 // INA calibration register according to R_SHUNT -#define INA_REG_CONFIG 0x00 // INA configuration register address -#define INA_REG_CALIB 0x05 // INA calibration register address -#define INA_REG_SHUNT 0x01 // INA shunt voltage register address -#define INA_REG_VOLTAGE 0x02 // INA bus voltage register address -#define INA_REG_POWER 0x03 // INA power register address -#define INA_REG_CURRENT 0x04 // INA current register address - -// INA219 write a register value -void INA_write(uint8_t reg, uint16_t value) { - I2C_start(INA_ADDR); // start transmission to INA219 - I2C_write(reg); // write register address - I2C_write(value >> 8); // write register content high byte - I2C_write(value); // write register content low byte - I2C_stop(); // stop transmission -} - -// INA219 read a register -uint16_t INA_read(uint8_t reg) { - uint16_t result; // result variable - I2C_start(INA_ADDR); // start transmission to INA219 - I2C_write(reg); // write register address - I2C_restart(INA_ADDR | 0x01); // restart for reading - result = (uint16_t)(I2C_read(1) << 8) | I2C_read(0); // read register content - I2C_stop(); // stop transmission - return(result); // return result -} - -// INA219 write inital configuration and calibration values -void INA_init(void) { - INA_write(INA_REG_CONFIG, INA_CONFIG); // write INA219 configuration - INA_write(INA_REG_CALIB, INA_CALIB); // write INA219 calibration -} - -// INA219 read voltage -uint16_t INA_readVoltage(void) { - return((INA_read(INA_REG_VOLTAGE) >> 1) & 0xFFFC); -} - -// INA219 read sensor values -uint16_t INA_readCurrent(void) { - uint16_t result = INA_read(INA_REG_CURRENT); - if (result > 32767) result = 0; - return(result); -} - -// ----------------------------------------------------------------------------- -// Millis Counter Implementation for Timer0 -// ----------------------------------------------------------------------------- - -volatile uint32_t MIL_counter = 0; // millis counter variable - -// Init millis counter -void MIL_init(void) { - OCR0A = 124; // TOP: 124 = 8000kHz / (64 * 1kHz) - 1 - TCCR0A = (1< voltage) minvoltage = voltage; - if (maxvoltage < voltage) maxvoltage = voltage; - if (mincurrent > current) mincurrent = current; - if (maxcurrent < current) maxcurrent = current; - if (minpower > power ) minpower = power; - if (maxpower < power ) maxpower = power; - - // Check SET button and set screen flag accordingly - if (PINB & (1< 4) primescreen = 0; - OLED_clearScreen(); - lastbutton = 1; - } - - // Display values on the OLED - switch (primescreen) { - case 0: OLED_setCursor(0,0); - OLED_printDec16(voltage); OLED_printPrg(mV); - OLED_printDec16(power); OLED_printPrg(mW); - OLED_setCursor(0,2); - OLED_printDec16(current); OLED_printPrg(mA); - OLED_printDec16(capacity / 1000); OLED_printPrg(mAh); - break; - case 1: OLED_setCursor(0,0); - OLED_printDec16(minvoltage); OLED_printPrg(SEP); - OLED_printDec16(maxvoltage); OLED_printPrg(mV); - OLED_setCursor(0,2); - OLED_printDec16(mincurrent); OLED_printPrg(SEP); - OLED_printDec16(maxcurrent); OLED_printPrg(mA); - break; - case 2: OLED_setCursor(0,1); - OLED_printDec16(minpower); OLED_printPrg(SEP); - OLED_printDec16(maxpower); OLED_printPrg(mW); - break; - case 3: OLED_setCursor(16,0); - OLED_printDec16(capacity / 1000); OLED_printChar(DECIMAL); - OLED_printDec12(capacity % 1000); OLED_printPrg(mAh); - OLED_setCursor(16,2); - OLED_printDec16(energy / 1000); OLED_printChar(DECIMAL); - OLED_printDec12(energy % 1000); OLED_printPrg(mWh); - break; - case 4: OLED_setCursor(32,1); - OLED_printDec8(seconds / 3600); OLED_printChar(COLON); - seconds %= 3600; - OLED_printDec8(seconds / 60 ); OLED_printChar(COLON); - OLED_printDec8(seconds % 60 ); - break; - default: break; - } - _delay_ms(100); - } -} diff --git a/software/font8x16a.h b/software/font8x16a.h deleted file mode 100644 index d0f4884..0000000 --- a/software/font8x16a.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays - * - * Based on ssd1306xled, re-written and extended by Stephen Denne - * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED - * - */ -/* - * SSD1306xLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x64 displays - * - * @created: 2014-08-12 - * @author: Neven Boyanov - * - * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled - * - * Reduced to the characters needed for the USB Tester 2020 by Stefan Wagner - * https://easyeda.com/wagiminator - */ - -// ---------------------------------------------------------------------------- - -#include - -// ---------------------------------------------------------------------------- - -/* Standard ASCII 8x16 font */ -const uint8_t ssd1306xled_font8x16a [] PROGMEM = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00, // ( 40 = . - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01, // ) 41 = - - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // * 42 = SPACE - 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20, // + 43 = A - 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00, // , 44 = V - 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00, // - 45 = W - 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F, // . 46 = m - 0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20, // / 47 = h - 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00, // 0 48 - 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, // 1 49 - 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00, // 2 50 - 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00, // 3 51 - 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00, // 4 52 - 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00, // 5 53 - 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00, // 6 54 - 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00, // 7 55 - 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00, // 8 56 - 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00, // 9 57 - 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, // : 58 - 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00, // ; 59 = AVG -}; - -// ---------------------------------------------------------------------------- - -const DCfont TinyOLED4kfont8x16a = { - (uint8_t *)ssd1306xled_font8x16a, - 8, // character width in pixels - 2, // character height in pages (8 pixels) - 40,59 // ASCII extents - }; - -// for backwards compatibility -#define FONT8X16A (&TinyOLED4kfont8x16a)