Facebook
From Violet Mockingjay, 1 Year ago, written in C++.
This paste is a reply to Untitled from Doctoredo - go back
Embed
Viewing differences between Untitled and Re: Untitled
/**
 * 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);
}