/* Written by Thesas (c) 2016 This code is intended as an example to show how the author (Thesas) thinks a voltage control, power control and temperature control for heating a resistive wire might work. This code is provided on a "as is" basis and any warranties or conditions of any kind, either express or implied, including, but not limited to, implied warranties of merchantability, of satisfactory quality or safety, non-infringement of third party rights, and fitness for a particular purpose or use are disclaimed in respect of this code and this code in combination with any hardware. The author (Thesas) makes no representation that the code or the code in combination with any hardware or any product does or will not infringe any patent, copyright, trade secret or other proprietary right. The entire risk as to the use, quality, and performance of a product using this code shall be with the user of the code. The author shall have no liability for direct, indirect, special, incidental, consequential, exemplary, punitive or other damages of any character. The user shall hold the author free and harmless from any liability, costs, damages, fees and expenses, including claims by third parties. Accepting this disclaimer of warranty is an obliging condition for using this code or parts of it. With other words: no warranties at all, you alone are responsible of any consequences if you use the code and if you don’t agree, you are not allowed to use this code or parts of it. */ #include "ClickButton.h" // library for multi function button #include "Snooze.h" // library for sleep mode #include #include #include u8g_t u8g; // configure the library to work with the SSD1306 and i2c use u8g_dev_ssd1306_128x32.c and u8g_dev_ssd1306_128x32_adafruit3_init_seq SnoozeBlock config; const int buttons = 3; const int buttonPin1 = 11; // Connected fire button from pin to ground const int buttonPin2 = 9; // Connected to up button const int buttonPin3 = 10; // Connected to down button ClickButton button[3] = { ClickButton (buttonPin1, LOW, CLICKBTN_PULLUP), ClickButton (buttonPin2, LOW, CLICKBTN_PULLUP), ClickButton (buttonPin3, LOW, CLICKBTN_PULLUP), }; // ClickButton array ADC *adc = new ADC(); // adc object const int OLED_RESET = 23; // reset of Oled Display const int DcDc5V = 22; // high enable 5V DC DC converter const int DcDcEn = 5; // high enable main DC DC converter const int Buck = 4; // PWM Out for Buck const int Boost = 6; // PWM Out for Boost const int BattChrgPin = A0; // half battery voltage to analog pin A1 const int VBattPin = A1; // half battery voltage to analog pin A1 const int VAttyPin = A2; // half (or third depending if buck or buck boost converter is used) of atomiser voltage const int IAttyPin = A3; // for current measurement const int ChrgCurrentPin = A0; // for chargeing current measurement IBAT = (VPROG/RPROG)*1000 or 1V for const programmed current //const int VOutPin = A14; // DAC output used for power steering // Variables float VBatt = 0; // battery voltage float ChrgCurrent = 0; // battery voltage float OldVBatt = 0; // old battery voltage, needed to overwrite display float VAtty = 0; // voltage on atomizer float OldVAtty = 0; // old voltage on atomizer, needed to overwrite display float MaxUSet = 240; // max limit of USet float MinUSet = 0; // min imit of USet float Amps = 0; // Amps output to atomizer float OldAmps = 0; // old Amps output to atomizer, needed to overwrite display float Watts = 0; // Watts output to atomizer float OldWatts = -10; // old Watts output to atomizer, needed to overwrite display float MaxWattsSet = 240; // max limit of WattsSet float MinWattsSet = 0; // min imit of WattsSet float Temp = 220; // Temp°C of coil float OldTemp = -10; // old Watts output to atomizer, needed to overwrite display float OldTemp0 = -10; const float MaxTempSet = 255; // max limit of WattsSet const float MinTempSet = 0; // min imit of WattsSet float R = 0.11; // resistence of atomizer float OldR = 0; // old R, needed to overwrite display float OldR0 = 0; int BattPercent = 0; // remaining battery percent int OldBattPercent = 0; // old remaining battery percent needed to overwrite display boolean lowBattWarning = false; // for trackign the low Batt Warning on Display int ButtonMultiplePressed = 0; // to detect and handle multiple pressed int MultipleButtonsPressed = 0; // to detect and handle multiple buttons pressed int OldButtonMultiplePressed = 0; // to detect and handle multiple pressed boolean buttonLastState = false; // for trackign when button is pressed and held int SleepTimeCounter = 0; // counter for sleep activation int OldSleepTimeCounter = -100; // counter for Display update delta int UpdateDisplayLoops = 60; // Loops to wait for updating display const int UpdateDisplayNotFire = 400; // Loops to wait for updating display const int UpdateDisplayFire = 200; // Loops to wait for updating display int PuffTimeCounter = 0; // counter to limit fire time int OldPuffTimeCounter = -100; // counter to limit fire time boolean StealthMode = false; float UpDownDelay = 150; // start delay in ms to increase or decrease values during longpress float MinUpDownDelay = 50; // minimum delay in ms to increase or decrease values during longpress uint16_t foreColor = 0; // Display fore color uint16_t backColor = 0; // Display back color float VOut0 = 2.0 ; // DA Out for 0 Volt float IncreaseOutput=0; // output steering variable float VOut =1; float OldVOut =1; float TempControll =1; double TempCoeff[] = {0,0,4.00e-03,6.20e-03,3.50e-03,1.05e-03,1.00e-03}; char TempCoeffNames[7][3]; int eepromAddr =0; // start address to write to eeprom const int eepromAddrIncrement=8; // increment of start address when EepromWriteCounter has reached its limit (and gets resett) char outStr[32] = "99.W"; char cToStr[2]; boolean BoostMode = true; boolean SleepMode = true; boolean ClickSleepMode = false; const int SleepTimeCount = 40000; const int Wait4EepromUpdate = 5000; int i = 0; int testvar = 0; int testvar2 = 0; int testvar3 = 1; bool testvar4 = true; // variables also stored in nvm byte EepromWriteCounterLB = 0; // EepromWriteCounter low byte counts the number of eeprom write cycles byte EepromWriteCounterHB = 0; // EepromWriteCounter high byte counts the number of eeprom write cycles byte EepromWriteCounterRestets = 0; // store the number of EepromWriteCounter resets and increase eeprom write addres, 8 bytes are stored so 256 counter resets use all 2048 bytes of eeprom byte WattsSet = 60; // set to Watts * 2 to be storable in one byte with reasonnable resolution byte TempSet = 160; // set to Temp - 60 to be storable in one byte with reasonnable resolution byte USet = 70; // set to Volt/30 to be storable in one byte with reasonnable resolution byte RSet = 255; // set to Ohms * 100 to be storable in one byte with reasonnable resolution byte DisplaySelect = 0; // DisplaySelect 0:Watts, DisplaySelect 1:Temp ,DisplaySelect 2:TempControllOff and Watts, 3:TempControllOff and Volts // up to now only 2 bits are used other display options might be stored in other bits byte selectedWire = 4; // wire material with given temperature coefficient // also here some bits are unused // display colors //#define BLACK 0x0000 /* 0, 0, 0 */ #define NAVY 0x000F /* 0, 0, 128 */ #define DARKGREEN 0x03E0 /* 0, 128, 0 */ #define DARKCYAN 0x03EF /* 0, 128, 128 */ #define MAROON 0x7800 /* 128, 0, 0 */ #define PURPLE 0x780F /* 128, 0, 128 */ #define OLIVE 0x7BE0 /* 128, 128, 0 */ #define LIGHTGREY 0xC618 /* 192, 192, 192 */ #define DARKGREY 0x7BEF /* 128, 128, 128 */ #define BLUE 0x001F /* 0, 0, 255 */ #define GREEN 0x07E0 /* 0, 255, 0 */ #define CYAN 0x07FF /* 0, 255, 255 */ #define RED 0xF800 /* 255, 0, 0 */ #define MAGENTA 0xF81F /* 255, 0, 255 */ #define YELLOW 0xFFE0 /* 255, 255, 0 */ //#define WHITE 0xFFFF /* 255, 255, 255 */ #define ORANGE 0xFD20 /* 255, 165, 0 */ #define GREENYELLOW 0xAFE5 /* 173, 255, 47 */ #define PINK 0xF81F void setup() { strcpy(TempCoeffNames[0], "R "); // measure and store resistance strcpy(TempCoeffNames[1], "NC"); // no temp controll wire strcpy(TempCoeffNames[2], "NF"); // NiFe strcpy(TempCoeffNames[3], "Ni"); // Ni strcpy(TempCoeffNames[4], "Ti"); // Ti strcpy(TempCoeffNames[5], "V2"); // V2A strcpy(TempCoeffNames[6], "V4"); // V4A config.pinMode(buttonPin1, INPUT_PULLUP, FALLING); pinMode(IAttyPin, INPUT); pinMode(VAttyPin, INPUT); pinMode(ChrgCurrent, INPUT); adc->setAveraging(16, ADC_0); // ADC0 set number of averages adc->setResolution(16, ADC_0); // ADC0 set bits of resolution adc->setConversionSpeed(ADC_VERY_LOW_SPEED, ADC_0); //ADC0 adc->setSamplingSpeed(ADC_VERY_LOW_SPEED, ADC_0); //ADC0 adc->setAveraging(16, ADC_1); // set number of averages adc->setResolution(16, ADC_1); // set bits of resolution adc->setConversionSpeed(ADC_VERY_LOW_SPEED, ADC_1); // change the conversion speed adc->setSamplingSpeed(ADC_VERY_LOW_SPEED, ADC_1); for (int i=0; igetMaxValue(ADC_0)); //+0.16; // check battery, + 0.?? to compensate for diode BattPercent = min(100,(100*((VBatt + 9 * OldVBatt)/10 - 3.15) ) ); // raw (linear & LP filtered) percent estimation ChrgCurrent = (4.03/1.2)*analogRead(ChrgCurrentPin)* (3.3 / adc->getMaxValue(ADC_0)); // IBAT = (VPROG/RPROG)*1000 or 1V for const programmed current if ((button[0].depressed == false) || button[1].depressed || button[2].depressed || (MultipleButtonsPressed > 0)) { // if not firing do not fire, reset puff timer ecc. digitalWrite(DcDcEn, LOW); analogWrite(Buck, 0); analogWrite(Boost, 0); PuffTimeCounter = 0; Amps = 0; VAtty = (float)USet/30; Watts = (float)WattsSet/2; Temp=TempSet+60; R=(float)RSet/100; if (VBatt < 3.2) LowBatt(); if (SleepTimeCounter == Wait4EepromUpdate) ChkAndUpdateEeprom(); // if nothing was done for some time, check values against eeprom and update eeprom } else { Fire(); if (VBatt < 2.3) LowBatt(); } if ((((SleepTimeCounter > (OldSleepTimeCounter + UpdateDisplayLoops) && (PuffTimeCounter == 0))) || (PuffTimeCounter > (OldPuffTimeCounter + UpdateDisplayLoops))) && !lowBattWarning) { // if UpdateDisplayLoops and Battery is OK, display Watts, Temp, ecc. if ((ChrgCurrent < 0.02) || (SleepTimeCounter < 15000)) PrintModDisplay(); else PrintChrgDisplay(); OldWatts = Watts; OldTemp=Temp; OldAmps=Amps; OldVAtty=VAtty; OldR=R; OldVBatt=VBatt; OldTemp=Temp; OldSleepTimeCounter = SleepTimeCounter; OldPuffTimeCounter = PuffTimeCounter; } SleepTimeCounter++; if (SleepTimeCounter >=SleepTimeCount) { //sets the module to sleep SleepTimeCounter = 0; OldSleepTimeCounter = -100; digitalWrite(DcDcEn, LOW); analogWrite(Buck, 0); analogWrite(Boost, 0); button[0].Update(); // if put to sleep by 5 clicks, the 5 Clicks are resettet here digitalWrite(DcDc5V, LOW); SerialPrintEepromVariables(); // Serial.println("sleep"); u8g_SleepOn(&u8g); SleepMode =true; Snooze.hibernate( config ); delay(50); } } else { button[0].Update(); // Update button state if(button[0].clicks == 4){ // wake up if 4 click ClickSleepMode = false; } else SleepTimeCounter++ ; if (SleepTimeCounter==100) { // go to sleep if not 4 click SleepTimeCounter = 0; SleepMode =true; ClickSleepMode = true; Snooze.hibernate( config ); } delay(50); } } void Fire() { float OldR1 = R; float OldWatts1 = Watts; float OldTemp1 = Temp; SleepTimeCounter = (Wait4EepromUpdate - 2); // so a RSet change is stored after release if (selectedWire == 1) { // no temperature controll if (DisplaySelect==0) { // Watts are set readPower(); if (Amps > 1) { R = min(9.99, max(0.01, VAtty/Amps)); } if (((VAtty*Amps) > 5) && (R < (float(RSet)/100.0)) && (PuffTimeCounter > 4)&& (PuffTimeCounter < 50)) { RSet = byte(int(R*100)); } if (PuffTimeCounter > 1) { IncreaseOutput = IncreaseOutput + (sqrt(R*float(WattsSet)/2) - sqrt(R*Watts))/2; } else { IncreaseOutput=0; } VOut = sqrt(R*float(WattsSet)/2); writeDCDC(); } else { // Volts are Set VOut= float(USet)/30; writeDCDC(); delay(1); readPower(); R =min(9.99, max(0.01, VAtty/Amps)); if (PuffTimeCounter > 2) { IncreaseOutput = IncreaseOutput + (VOut - VAtty); } } } else { //temperature controll float Tambient = 20.0; readPower(); if (Amps > 1.5) { R = min(2.99, max(0.01, VAtty/Amps)); } if (((VAtty*Amps) > 7) && (R < (float(RSet)/100.0)) && (PuffTimeCounter > 4)&& (PuffTimeCounter < 50)) { RSet = byte(int(R*100)); } if (PuffTimeCounter < 3) { VOut = sqrt((float(RSet)/100.0)*float(WattsSet)/2.0); IncreaseOutput =0; Temp = Tambient+max( 0.0,((R/((float)RSet/100.0))-1.0)/TempCoeff[selectedWire]); } else { if (Amps < 1.5 ) { R=max(OldR0 *0.995, float(RSet)/100.0); } Temp = Tambient+max( 0.0,((R/((float)RSet/100.0))-1.0)/TempCoeff[selectedWire]); Temp = max(OldTemp0-(0.1+(Amps/10.0)), min(OldTemp0+(Amps/10.0),Temp)); float TempControl = max(0.0,min(1.0,(float (TempSet) + 60.0 + 10.0 - Temp)/20.0))* sqrt(R*float(WattsSet)/2.0); VOut = max( 1.6*sqrt(R), min(7.0,(min(VOut + (sqrt(R*float(WattsSet)/2.0) - sqrt(R*Watts))/4.0, TempControl)))) ; //1.6*sqrt(R) -> minimum power is 2.56W and a current of 1.6A (above 1.5A needed for TC) results for 1 Ohm if less power is needed or higher resistant coils are used, use a higher shunt resistance } writeDCDC(); } OldR0=R; OldTemp0 =Temp; printVars(); if (PuffTimeCounter > 2) { // some LP filtering for display R = ( R + 69.0 * OldR1)/70.0; Watts = (Watts + 69.0 * OldWatts1)/70.0; Temp = (Temp + 69.0 * OldTemp1)/70.0; // VOut = (OldVOut1 + VOut)/2.0; // some LP filtering for closed loop controll } PuffTimeCounter++; UpdateDisplayLoops = UpdateDisplayFire; //slow Display update } void printVars() { if (PuffTimeCounter == 0) { Serial.print("A:"); Serial.print("\t"); Serial.print("VAtty:"); Serial.print("\t"); Serial.print(" R"); Serial.print("\t"); Serial.print(" VOut:"); Serial.print("\t"); Serial.print(" Watts"); Serial.print("\t"); Serial.print(" Temp"); Serial.print("\t"); Serial.print(" VBatt"); Serial.print("\t"); Serial.print(" IncreaseOutput"); Serial.println(""); } Serial.print(Amps); Serial.print("\t"); Serial.print(VAtty); Serial.print("\t"); Serial.print(R); Serial.print("\t"); Serial.print(VOut); Serial.print("\t"); Serial.print(Watts); Serial.print("\t"); Serial.print(Temp); Serial.print("\t"); Serial.print(VBatt); Serial.print("\t"); Serial.print(IncreaseOutput); Serial.print("\t"); Serial.print(BoostMode); Serial.print("\t"); Serial.print(testvar); Serial.println(""); } void readPower() { result = adc->analogSynchronizedRead(IAttyPin, VAttyPin); result.result_adc1 = (uint16_t)result.result_adc1; result.result_adc0 = (uint16_t)result.result_adc0; VAtty = 4.03*(result.result_adc1*3.3/adc->getMaxValue(ADC_1)); Amps = 10.2 * (result.result_adc0*3.3/adc->getMaxValue(ADC_0)); // Amps = 8.2 * (result.result_adc0*3.3/adc->getMaxValue(ADC_0)); // Amps = 13.43 * (result.result_adc0*3.3/adc->getMaxValue(ADC_0)); // VAtty = 4.03 * analogRead(VAttyPin)* (3.3 / adc->getMaxValue(ADC_1)); // convert to atomizer voltage be sure to stay below 3.3V for a boost converter 1:4.03 (3.3k/10k) devider is assumed // Amps = 10 * analogRead(IAttyPin)* (3.3 / adc->getMaxValue(ADC_0)); // convert to the atomizer current 1.0 mOhm shunt resistance 100 * preamp is asumed Watts = VAtty * Amps; if (Watts > 80) Overload() ; } void getR() { VOut = 2; writeDCDC(); delay (2); readPower(); if ((VAtty*Amps) > 6.0) { R = min(9.99, max(0.01, VAtty/Amps)); RSet = byte(int(R*100)); } else { VOut = 3.3; writeDCDC(); delay (2); readPower(); R = min(9.99, max(0.01, VAtty/Amps)); RSet = byte(int(R*100)); } ChkAndUpdateEeprom(); } void writeDCDC() { digitalWrite(DcDcEn, HIGH); IncreaseOutput = min(max(IncreaseOutput,-3.0),3.0); if ((! BoostMode) && ((255.0*(VOut + 0.5 * IncreaseOutput)/VBatt)>255)) { BoostMode =true; IncreaseOutput=0; } if (BoostMode && (VOut < VBatt )) { BoostMode =false; IncreaseOutput=0; } if (! BoostMode) { analogWrite(Boost, 0); delay (1); testvar=max(0,min(255, int(255.0*(VOut + 0.5 * IncreaseOutput)/VBatt))); analogWrite(Buck, max(0,min(255, int(255.0*(VOut + 0.5 * IncreaseOutput)/VBatt)))); } else { testvar=max(1,min(150, int(20 * IncreaseOutput- 6.5*pow(VOut * 4.1/VBatt ,2) + 110*(VOut * 4.1/VBatt )-345))); analogWrite(Boost, max(1,min(150, int(20 * IncreaseOutput- 6.5*pow(VOut * 4.1/VBatt ,2) + 110*(VOut * 4.1/VBatt )-345)))); analogWrite(Buck, 255); } } void LowBatt() { digitalWrite(DcDcEn, LOW); analogWrite(Buck, 0); analogWrite(Boost, 0); lowBattWarning=true; u8g_SetContrast(&u8g, int(254*(1.0-float(SleepTimeCounter)/float(SleepTimeCount)))); u8g_FirstPage(&u8g); do { u8g_SetFont(&u8g, u8g_font_profont10); u8g_DrawStr(&u8g, 0, 23," Low Battery"); u8g_DrawStr(&u8g, 0, 32," recharge"); } while(u8g_NextPage(&u8g)); delay (2000); // SleepTimeCounter=SleepTimeCount; // if battery is low go to sleep } void Overload() { digitalWrite(DcDcEn, LOW); analogWrite(Buck, 0); analogWrite(Boost, 0); u8g_SetContrast(&u8g, int(254*(1.0-float(SleepTimeCounter)/float(SleepTimeCount)))); u8g_FirstPage(&u8g); do { u8g_SetFont(&u8g, u8g_font_profont10); u8g_DrawStr(&u8g, 0, 23," Overload"); u8g_DrawStr(&u8g, 0, 32,"decrease power"); } while(u8g_NextPage(&u8g)); R = min(9.99, max(0.01, VAtty/Amps)); RSet = byte(int(R*100)); ChkAndUpdateEeprom(); delay (3000); SleepTimeCounter=SleepTimeCount; } void WireSelectionMenue(){ byte OldSelectedWire = -1; selectedWire=0; u8g_SetContrast(&u8g, int(254*(1.0-float(SleepTimeCounter)/float(SleepTimeCount)))); while (!(button[0].depressed)) { button[0].Update(); // Update button state button[1].Update(); // Update button state button[2].Update(); // Update button state selectedWire =selectedWire % 7; if (OldSelectedWire != selectedWire) { u8g_FirstPage(&u8g); if (selectedWire != 0) { do { u8g_SetFont(&u8g, u8g_font_profont10); u8g_DrawStr(&u8g, 0, 23,"Up/Down:select"); u8g_DrawStr(&u8g, 0, 32,"fire: store"); u8g_SetFont(&u8g, u8g_font_profont15); u8g_DrawStr(&u8g, 74, 29,TempCoeffNames[selectedWire]); } while(u8g_NextPage(&u8g)); OldSelectedWire = selectedWire; } else { do { u8g_SetFont(&u8g, u8g_font_profont10); u8g_DrawStr(&u8g, 0, 23,"Up/Down:select"); u8g_DrawStr(&u8g, 0, 32,"fire: get new R"); u8g_SetFont(&u8g, u8g_font_profont15); u8g_DrawStr(&u8g, 74, 29," "); } while(u8g_NextPage(&u8g)); OldSelectedWire = selectedWire; } } if (button[1].clicks != 0) { if (selectedWire > 0) selectedWire--; else selectedWire = selectedWire + 7 -1; } if (button[2].clicks != 0) selectedWire++; button[1].clicks = 0; button[2].clicks = 0; } if (selectedWire == 0) { int eepromBasisAddr = EEPROM.read(0)* eepromAddrIncrement; selectedWire = EEPROM.read(eepromBasisAddr + 8 ); getR(); } MultipleButtonsPressed=1; // do not fire for the store click OldWatts=-100; // force display update OldTemp=-100; // force display update OldR=-100; // force display update SleepTimeCounter = 0; OldSleepTimeCounter = -100; } void PrintModDisplay() { int x1 = 16; int y1 = 23; int x2 = 59; int y2 = 32; u8g_SetContrast(&u8g, int(254*(1.0-float(SleepTimeCounter)/float(SleepTimeCount)))); u8g_FirstPage(&u8g); do { itoa((int)floor(Watts),outStr,10); if (floor(Watts+0.5) <= Watts) strcat(outStr, " W"); else strcat(outStr, ".W"); if (DisplaySelect==0) { u8g_SetFont(&u8g, u8g_font_profont15); u8g_DrawStr(&u8g, x2, y2-3,outStr); //(int)floor(Watts) } else { u8g_SetFont(&u8g, u8g_font_profont10); u8g_DrawStr(&u8g, x1, y2,outStr); //(int)floor(Watts) } if ((selectedWire != 1)) { // Wire = NC disables temperature controll Voltage is displayes instead of temperature itoa((int)Temp,outStr,10); cToStr[1] = '\0'; cToStr[0] = char(0xb0); strcat(outStr, cToStr); strcat(outStr, "C"); } else { dtostrf(VAtty, 4, 2, outStr); strcat(outStr, "V"); } if (DisplaySelect==0) { u8g_SetFont(&u8g, u8g_font_profont10); u8g_DrawStr(&u8g, x1, y2,outStr); } else { u8g_SetFont(&u8g, u8g_font_profont15); u8g_DrawStr(&u8g, x2, (int)y2-3,outStr); } dtostrf(R, -4, 2, outStr); u8g_SetFont(&u8g, u8g_font_profont10); u8g_DrawStr(&u8g, x1, y1,outStr); //(int)floor(Watts) u8g_DrawStr(&u8g, x1+25, y1,TempCoeffNames[selectedWire]); int x0 = 0; int y0 = 17; u8g_DrawFrame(&u8g,x0, y0, 9, 15); u8g_DrawFrame(&u8g,x0 + 3, y0-1, 3, 1); if ( (int)((11 * BattPercent)/100)>0) u8g_DrawBox(&u8g,x0+2,30-(int)((11 * BattPercent)/100), 5, (int)((11 * BattPercent)/100)); if (BoostMode) u8g_DrawBox(&u8g, 56,17, 2, 2); } while(u8g_NextPage(&u8g)); } void PrintChrgDisplay() { int x1 = 16; int y1 = 29; int x2 = 59; u8g_SetContrast(&u8g, int(254*(1.0-float(SleepTimeCounter)/float(SleepTimeCount)))); u8g_FirstPage(&u8g); do { dtostrf(VBatt, 4, 2, outStr); strcat(outStr, "V"); u8g_SetFont(&u8g, u8g_font_profont15); u8g_DrawStr(&u8g, x1, y1,outStr); dtostrf(ChrgCurrent, -4, 2, outStr); strcat(outStr, "A"); u8g_SetFont(&u8g, u8g_font_profont15); u8g_DrawStr(&u8g, x2, y1,outStr); int x0 = 0; int y0 = 17; u8g_DrawFrame(&u8g,x0, y0, 9, 15); u8g_DrawFrame(&u8g,x0 + 3, y0-1, 3, 1); if ( (int)((11 * BattPercent)/100)>0) u8g_DrawBox(&u8g,x0+2,30-(int)((11 * BattPercent)/100), 5, (int)((11 * BattPercent)/100)); } while(u8g_NextPage(&u8g)); } void ThesasMods() { u8g_FirstPage(&u8g); do { u8g_SetFont(&u8g, u8g_font_profont15); u8g_DrawStr(&u8g, 3, 29,"Thesas Mods"); } while(u8g_NextPage(&u8g)); delay(3000); } void ChkAndUpdateEeprom() { boolean somethingWasUpdatet = false; int eepromBasisAddr = EEPROM.read(0)* eepromAddrIncrement; // start address to write to eeprom // initialize eeprom with 0 at least the first 3 Bytes if (WattsSet != EEPROM.read(eepromBasisAddr + 3 )) { EEPROM.write(eepromBasisAddr + 3 , WattsSet); somethingWasUpdatet = true; } if (TempSet != EEPROM.read(eepromBasisAddr + 4 )) { EEPROM.write(eepromBasisAddr + 4 , TempSet); somethingWasUpdatet = true; } if (RSet != EEPROM.read(eepromBasisAddr + 5 )) { EEPROM.write(eepromBasisAddr + 5 , RSet); somethingWasUpdatet = true; } if (USet != EEPROM.read(eepromBasisAddr + 6 )) { EEPROM.write(eepromBasisAddr + 6 , USet); somethingWasUpdatet = true; } if (DisplaySelect != EEPROM.read(eepromBasisAddr + 7 )) { EEPROM.write(eepromBasisAddr + 7 , DisplaySelect); somethingWasUpdatet = true; } if (selectedWire != EEPROM.read(eepromBasisAddr + 8 )) { EEPROM.write(eepromBasisAddr + 8 , selectedWire); somethingWasUpdatet = true; } if (somethingWasUpdatet) { EepromWriteCounterLB=EEPROM.read(eepromBasisAddr + 1); EepromWriteCounterHB=EEPROM.read(eepromBasisAddr + 2); if (EepromWriteCounterLB < 255) { EEPROM.write(eepromBasisAddr + 1 , EepromWriteCounterLB + 1 ); } else { if (EepromWriteCounterHB < 255) { EEPROM.write(eepromBasisAddr + 2 , EepromWriteCounterHB + 1 ); EEPROM.write(eepromBasisAddr + 1 , 0 ); } else { if (EEPROM.read(0) < 255) { EEPROM.write(0 , (EEPROM.read(0) +1)); eepromBasisAddr = EEPROM.read(0)* eepromAddrIncrement; EEPROM.write(eepromBasisAddr + 2 , 0 ); EEPROM.write(eepromBasisAddr + 1 , 0 ); } else { EEPROM.write(0 , 0); eepromBasisAddr = EEPROM.read(0)* eepromAddrIncrement; EEPROM.write(eepromBasisAddr + 2 , 0 ); EEPROM.write(eepromBasisAddr + 1 , 0 ); } } } } } void SerialPrintEepromVariables() { int eepromBasisAddr = EEPROM.read(0)* eepromAddrIncrement; Serial.print("STCount ");Serial.println(SleepTimeCounter); Serial.print("STCount ");Serial.println(SleepTimeCounter); Serial.print("baseAddr "); Serial.println(EEPROM.read(0)); Serial.print("EepromWriteCounterLB "); Serial.println(EEPROM.read(eepromBasisAddr + 1 )); Serial.print("EepromWriteCounterHB "); Serial.println(EEPROM.read(eepromBasisAddr + 2 )); Serial.print("WattsSet "); Serial.println(EEPROM.read(eepromBasisAddr + 3 )); Serial.print("TempSet "); Serial.println(EEPROM.read(eepromBasisAddr + 4 )); Serial.print("RSet "); Serial.println(EEPROM.read(eepromBasisAddr + 5 )); Serial.print("USet "); Serial.println(EEPROM.read(eepromBasisAddr + 6 )); Serial.print("DisplaySelect "); Serial.println(EEPROM.read(eepromBasisAddr + 7 )); Serial.print("selectedWire "); Serial.println(EEPROM.read(eepromBasisAddr + 8 )); delay(100); }