/** * Please, don't change this Text, because most of Code is not mine! * ================================================================== * Modification of GreatScottLab's * DIY Adjustable Constant Load (Current & Power) * https://www.instructables.com/id/DIY-Adjustable-Constant-Load-Current-Power/ * * I had some 5110 LCD's laying arround, so I adjusted original code for it * added CPU Cooler with fan and thermo resistor for Temperature sensing */ #include #include #include #include #include #include #define clk 3 #define dt 2 #define sw 4 #define pwm 9 #define pwm_fan 10 // fan speed #define fan 5 // fan power on/off #define currentsense A3 #define voltagesense A1 #define tempsense A2 // thermo resistor (8kOhm, salvaged from Old Laptop Battery pack) Adafruit_PCD8544 display = Adafruit_PCD8544(13, 12, 11, 8, 7); #define LCDLight 6 // LCD background light connected to digital pin 6 on Arduino const unsigned char PROGMEM splash[] ={0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x10, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x00, 0x10, 0x80, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x10, 0x80, 0x00, 0x01, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00, 0x00, 0x10, 0x80, 0x00, 0x7f, 0x00, 0x00, 0x18, 0x00, 0x03, 0xfc, 0x00, 0x10, 0x80, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x02, 0x00, 0x00, 0x10, 0x80, 0x00, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x02, 0x00, 0x00, 0x10, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x80, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x80, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0}; const unsigned char PROGMEM highV[] ={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xe7, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xc7, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe3, 0xc3, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe3, 0x83, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc3, 0x81, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc7, 0x81, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x07, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x06, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0e, 0x10, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0x70, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x0c, 0xe0, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x0f, 0xe0, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1f, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1e, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x18, 0xc0, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x10, 0xc0, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0xc0, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x01, 0xc0, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x01, 0xc0, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x01, 0x80, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x07, 0xe0, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x03, 0xc0, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x80, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x01, 0x80, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; const unsigned char PROGMEM low_bat[] ={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x04, 0x00, 0x00, 0x18, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x38, 0x00, 0x00, 0x18, 0x30, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x78, 0x00, 0x00, 0x18, 0x30, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x18, 0x30, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x18, 0x30, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x03, 0xfe, 0x00, 0x00, 0x18, 0x30, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x18, 0x30, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x18, 0x30, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x18, 0x30, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x18, 0x30, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x18, 0x30, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x18, 0x30, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x18, 0x30, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x00, 0x18, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x00, 0x18, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; const unsigned char PROGMEM hot[] ={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x03, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x79, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x78, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x78, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xfc, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xfe, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xff, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xcf, 0xff, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8f, 0xff, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8f, 0xff, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8f, 0xff, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8f, 0xff, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8f, 0xff, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc7, 0xff, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xff, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xfe, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0xfc, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x8f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; const unsigned char PROGMEM arrow[] = {0x80, 0xc0, 0xe0, 0xf0, 0xe0, 0xc0, 0x80}; int screen = -1; int arrowpos = 0; int line = 7; int tens = 0; int ones = 0; int dec1 = 0; int dec2 = 0; float power = 0; float current = 0; float curcurrent = 0; float curpower = 0; float curvoltage = 0; float curcurrentraw = 0; float zerocurrent; float curvoltraw = 0; int counter = 0; float max_power=199.99; float max_current=15.0; float min_voltage = 3.0; float max_voltage = 27.0; unsigned long refStart; int zerotmp=250; int maxTemp=750; int tempraw; volatile boolean fan_state = false; // fan switched Off int contrast = 60; // LCD contrast /** * Sensitivity of Current sensor * 5A = 185.00 * 20A = 100.00 * 30A = 66.00; */ float cursense = 100.00; // at built Time I had only 5A Current Sensor volatile boolean currentmode = false; volatile boolean powermode = false; volatile boolean TurnDetected = false; volatile boolean up = false; volatile boolean button = false; float refV; int timer = 1000; // mSec to refresh LCD float tolerance = 1.0; // Tolerance for measure voltage against calibrated Multimeter // Voltage divider schema // try to use precision 1% tolerance resistors // // // -> | Input Voltage // [ ] // [ ] RxUpper Resistor // | // |-- > to Arduino Analog // | // [ ] RxLower Resistor // [ ] // | // GND // all Values are in Ohm // Input Voltage float R1Upper = 10000.0; // resistance of upper resistor - see above Graphics float R1Lower = 2000.0; // resistance of lower resistor - see above Graphics float ratio1= R1Lower/(R1Upper+R1Lower); const unsigned char PS_128 = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); float test=0; ISR(PCINT2_vect) { if (digitalRead(sw) == LOW) { button = true; } } void isr0 () { TurnDetected = true; up = (digitalRead(clk) == digitalRead(dt)); delay(20); } void setup() { //Serial.begin(115200); screen = -1; pinMode(sw, INPUT_PULLUP); pinMode(clk, INPUT); pinMode(dt, INPUT); pinMode(pwm, OUTPUT); pinMode(currentsense, INPUT); pinMode(LCDLight,OUTPUT); pinMode(pwm_fan, OUTPUT); // fan speed pinMode(tempsense, INPUT);// temperature sensor pinMode(fan, OUTPUT); // fan switch analogReference(DEFAULT); digitalWrite(LCDLight,LOW); digitalWrite(pwm, LOW); ADCSRA &= ~PS_128; ADCSRA |= (1 << ADPS1) | (1 << ADPS0); PCICR |= 0b00000100; PCMSK2 |= 0b00010000; // turn o PCINT20(D4) attachInterrupt(0, isr0, RISING); TCCR1A = 0; TCCR1A = (1 << COM1A1) | (1 << WGM11); TCCR1B = 0; TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS10); ICR1 = 2047; OCR1A = 0; refV = readVcc(); //refV=1.1; curvoltage = ((analogRead(voltagesense) * refV) / 1024.0)/ratio1/1000; /** show splash screen */ display.begin(); display.setContrast(50); display.clearDisplay(); display.drawBitmap(0,0,splash,84,48,1); display.setTextSize(1); display.setCursor(4,4); display.print("ELECTRONIC"); display.setCursor(15,13); display.print("LOAD"); display.setFont(&Org_01); display.setCursor(30,41); display.print("by MICKEY"); display.setTextSize(1); display.display(); delay(3000); // show splash for 3 sec display.clearDisplay(); zerocurrent=calibrate_sensor(); refStart = millis(); curvoltage = ((analogRead(voltagesense) * refV) / 1024.0)/ratio1/1000; if(curvoltage > max_voltage) high_input(); } void loop() { /*int tempraw=analogRead(tempsense); if(tempraw > 900){ //Serial.println(tempraw); if(currentmode) currentmode=false; if(powermode)powermode=false; OCR1A = 0; display.clearDisplay(); display.drawBitmap(0,0,hot,84,48,1); display.display(); // stop(); } */ readTemp(); // read temperature /*read Vcc Voltage each 5 sec*/ if (millis()-refStart > 5000){ refV=readVcc(); delay(20); refStart=millis(); } if (currentmode) { // take 20 readings of Current curcurrentraw=0; for (int i = 0; i < 20; i++) { curcurrentraw += analogRead(currentsense); } curcurrent = abs((((curcurrentraw/20) - zerocurrent) * (refV / 1023.00) / cursense)); if(curcurrent > max_current) { stepDown(); } if(curcurrent<0) curcurrent=0; if (counter == timer) { screen6(); counter = 0; } if (curcurrent < current) { OCR1A++; } else { if(OCR1A>0){ OCR1A = OCR1A - 1; } else { OCR1A=0; } } OCR1A=constrain(OCR1A,0,2047); counter++; delayMicroseconds(100); } if (powermode) { // take 20 readings of Current curcurrentraw=0; for (int i = 0; i < 20; i++) { curcurrentraw += analogRead(currentsense); } curcurrent = abs((((curcurrentraw/20) - zerocurrent) * (refV / 1023.00) / cursense)); if(curcurrent > max_current){ stepDown(); } curvoltage = ((analogRead(voltagesense) * refV) / 1023.0)/ratio1/1000; curpower = curvoltage * curcurrent; if (counter == timer) { screen3(); counter = 0; } if (curpower < power) { OCR1A++; } else { if(OCR1A>0){ OCR1A = OCR1A - 1; } else { OCR1A=0; } } OCR1A=constrain(OCR1A,0,2048); counter++; delayMicroseconds(100); } if (TurnDetected) { delay(20); switch (screen) { case -1: screen=0; screen0(); break; case 0: switch (arrowpos) { case 0: screen0(); arrowpos=1; break; case 1: screen0(); arrowpos =0; break; } print_arrow(); break; case 1: switch (arrowpos) { case 0: if(!up){ screen1(); arrowpos=1; } else { screen1(); arrowpos=2; } break; case 1: if (!up) { screen1(); arrowpos = 2; } else { screen1(); arrowpos = 0; } break; case 2: if (!up) { screen1(); arrowpos = 0; } else { screen1(); arrowpos = 1; } break; } print_arrow(); break; case 2: if (!up) { power = power + 0.25; if(power > max_power) power = max_power; screen2(); } else { power = power - 0.25; if (power < 0) { power = 0; } screen2(); } display.display(); break; case 3: if (arrowpos==3) { arrowpos = 2; screen=1; screen1(); } break; case 4: switch (arrowpos) { case 0: if(!up){ screen4(); arrowpos=1; } else { screen4(); arrowpos=2; } break; case 1: if (!up) { screen4(); arrowpos = 2; } else { screen4(); arrowpos = 0; } break; case 2: if (!up) { screen4(); arrowpos = 0; } else { screen4(); arrowpos = 1; } break; } print_arrow(); break; case 5: if (!up) { current = current + 0.25; if (current > max_current) current=max_current; screen5(); } else { current = current - 0.25; if (current < 0) { current = 0; } screen5(); } display.display(); break; } TurnDetected = false; } if (button) { button = false; delay(200); switch (screen) { case -1: screen=0; screen0(); break; case 0: if (arrowpos == 0) { screen = 1; arrowpos=2; screen1(); } else { arrowpos=2; screen = 4; screen4(); } break; case 1: switch (arrowpos) { case 0: screen = 2; screen2(); if(power <10.0){ display.setCursor(20, 25); } else { display.setCursor(6, 25); } break; case 1: if(power > 0){ powermode = true; screen = 3; screen3(); } break; case 2: arrowpos = 0; screen = 0; screen0(); break; } break; case 2: screen = 1; arrowpos=1; screen1(); break; case 3: powermode = false; OCR1A = 0; counter = 0; screen = 1; screen1(); break; case 4: switch (arrowpos) { case 0: screen = 5; screen5(); if(current <10.0){ display.setCursor(20, 25); } else { display.setCursor(6, 25); } break; case 1: if(current > 0){ currentmode = true; screen = 6; screen6(); } break; case 2: arrowpos = 1; screen = 0; screen0(); break; } break; case 5: arrowpos=1; screen = 4; screen4(); break; case 6: currentmode = false; OCR1A = 0; screen = 4; screen4(); break; } print_arrow(); button = false; display.display(); } } void screen0() { display.setFont(); display.clearDisplay(); display.setCursor(10, 10); display.print("Power Mode"); display.setCursor(10, 30); display.print("Current Mode"); display.display(); } void screen1() { display.clearDisplay(); display.setCursor(20, 5); display.print("Power (W)"); if(power <10.0){ display.setCursor(20, 25); } else { display.setCursor(6, 25); } display.setFont(&FreeMonoBold12pt7b); display.print(power); display.setFont(); display.setCursor(10, 40); display.print("Start"); display.setCursor(55, 40); display.print("Back"); display.display(); } void screen2() { display.clearDisplay(); display.setCursor(20, 5); display.print("Power (W)"); if(power <10.0){ display.setCursor(20, 25); } else { display.setCursor(6, 25); } display.setFont(&FreeMonoBold12pt7b); display.print(power); display.setFont(); display.setCursor(10, 40); display.print("Button = SET"); display.display(); } void screen3() { display.clearDisplay(); display.print("Set PWR:"); display.print(power); display.print("W"); display.setFont(&FreeMonoBold12pt7b); if(curpower <10.0){ display.setCursor(20, 25); } else { display.setCursor(6, 25); } display.print(curpower); display.setFont(); display.setCursor(30, 40); //display.write((uint8_t)0); display.print("STOP"); display.display(); } void screen4() { display.clearDisplay(); display.setCursor(10, 5); display.print("Current (A)"); if(current <10.0){ display.setCursor(20, 25); } else { display.setCursor(6, 25); } display.setFont(&FreeMonoBold12pt7b); display.print(current); display.setFont(); display.setCursor(10, 40); display.print("Start"); display.setCursor(55, 40); display.print("Back"); display.display(); } void screen5() { display.clearDisplay(); display.setCursor(10, 5); display.print("Current (A)"); if(current <10.0){ display.setCursor(20, 25); } else { display.setCursor(6, 25); } display.setFont(&FreeMonoBold12pt7b); display.print(current); display.setFont(); display.setCursor(10, 40); display.print("Button = SET"); display.display(); } void screen6() { display.clearDisplay(); display.print("Set CUR:"); display.print(current); display.print("A"); display.setFont(&FreeMonoBold12pt7b); if(curcurrent <10.0){ display.setCursor(20, 25); } else { display.setCursor(6, 25); } display.print(curcurrent); display.setFont(); display.setCursor(30, 40); display.print("STOP"); display.display(); } void print_arrow(){ switch (screen){ case 0: switch (arrowpos){ case 0: display.drawBitmap(0,10,arrow,5,7,1); break; case 1: display.drawBitmap(0,30,arrow,5,7,1); break; } break; case 1: switch (arrowpos){ case 0: display.drawBitmap(0,20,arrow,5,7,1); break; case 1: display.drawBitmap(0,40,arrow,5,7,1); break; case 2: display.drawBitmap(50,40,arrow,5,7,1); break; } break; case 4: switch (arrowpos){ case 0: display.drawBitmap(0,20,arrow,5,7,1); break; case 1: display.drawBitmap(0,40,arrow,5,7,1); break; case 2: display.drawBitmap(50,40,arrow,5,7,1); break; } break; } display.display(); } long readVcc() { long result; // Read 1.1V reference against AVcc ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); delay(20); // Wait for Vref to settle ADCSRA |= _BV(ADSC); // Convert while (bit_is_set(ADCSRA,ADSC)); result = ADCL; result |= ADCH<<8; result = 1125300L / result; // Back-calculate AVcc in mV return result; } int calibrate_sensor(){ uint16_t acc = 0; for (int i = 0; i < 20; i++) { acc += analogRead(currentsense); } int zero = acc / 20; return zero; } void low_input(){ /* if input voltage is below defined value (minInV) show the picture, * and stop the code */ OCR1A = 0; analogWrite(pwm_fan,0); display.clearDisplay(); display.drawBitmap(0,0,low_bat,84,48,1); display.display(); stop(); } void high_input(){ /* if input voltage is above defined value (maxInV) show the picture, * and stop the code */ OCR1A = 0; analogWrite(pwm_fan,0); display.clearDisplay(); display.drawBitmap(0,0,highV,84,48,1); display.display(); stop(); } /** read temperature from sensor */ void readTemp(){ tempraw = analogRead(tempsense); if(tempraw>maxTemp) tempraw=maxTemp; Serial.println(tempraw); if(tempraw > zerotmp && tempraw < maxTemp){ if(!fan_state) fan_on(); int temp=map(tempraw,zerotmp,maxTemp,0,640); Serial.println(temp); analogWrite(fan,temp); } else if(tempraw < zerotmp){ if(fan_state){ analogWrite(fan,0); // set fan speed to 0 fan_off(); // switch fan power off } } else if (tempraw > maxTemp){ if (currentmode) currentmode=false; if (powermode) powermode = false; OCR1A = 0; //fan_off(); display.clearDisplay(); display.drawBitmap(0,0,hot,84,48,1); display.display(); stop(); } } /** switch Fan on */ void fan_on(){ digitalWrite(fan,HIGH); fan_state = true; } /** switch Fan off */ void fan_off(){ digitalWrite(fan,LOW); fan_state = false; } /** stop the execution */ void stop() { Serial.println(tempraw); while(1); } void stepDown(){ OCR1A=OCR1A-5; constrain(OCR1A,0,2047); }