#include <Wire.h>
#include <EncButton.h>
#include <EEPROMVar.h>
#include <EEPROMex.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Tiny4kOLED.h>
#include <Adafruit_MCP4725.h>
#include <Adafruit_ADS1X15.h>
#include <GyverButton.h>
// ENCODER
EncButton Enc1(2, 3, 4); //data, clk, sw.
// BUTTON
#define btn1 8
#define btn2 7
GButton buttonMenu(btn1);
GButton buttonSel(btn2);
#define FAN 13
#define ENABLE 12
#define ERROR 5
#define OverTemp 70
#define BUZZ 11
Adafruit_ADS1115 ads;
Adafruit_MCP4725 mcpV, mcpA;
OneWire oneWire (6);
DallasTemperature ds18b20 (& oneWire) ;
// ANALOG READ & AVERAGE CALC.
int numReadings;
float volts, ampere, setCurr;
float GAIN = 0.015625; //mV
float ampReadings[5];
float ampTotal = 0;
float ampAverage = 0;
float voltReadings[5];
float voltTotal = 0;
float voltAverage = 0;
//TIMING
unsigned long timeTemp, refreshTime = 300, errorTime = 500, comTime = 300;
// DIGITAL TEMP SENSOR
float ds18b20Temp, ds18b20TempPrev;
int fanSpeed = 0;
int tempThreshold = 45;
int tempMax = 80;
// PAGE COUNTER
int page = 0;
bool FIRST = true;
int warnings, errorType;
// BUTTON COUNTER
bool btnMenuCount = false;
bool btnSelCount = false;
// GENERIC
float voltSet = 0.00;
float ampereSet = 0.00;
float voltRead = 0.00;
float ampereRead = 0.00;
float voltSetMax = 20.00;
float ampereSetMax = 3.00;
float calibV = 1;
float calibA = 1;
int w1 = 0;
//-----------------------
void isr() {
Enc1.tickISR();
}
//--------------------------
void setup(){
Wire.begin();
Serial.begin(9600);
ds18b20.begin();
ds18b20.setResolution(9);
//-----------------------------------
attachInterrupt(0, isr, CHANGE);
attachInterrupt(1, isr, CHANGE);
Enc1.setEncISR(true);
//-----------------------------------
pinMode(ENABLE, OUTPUT);
pinMode(FAN, OUTPUT);
pinMode(ERROR, OUTPUT);
//MCP4725_1 INDEX / CONNECTION CHECK.
mcpV.begin(0x62);
if (mcpV.begin()) {
while (!mcpV.begin()){
errorType = 0;
errors();
}
}
mcpA.begin(0x63);
//MCP4725_2 INDEX / CONNECTION CHECK.
if (mcpA.begin()) {
while (!mcpA.begin()){
errorType = 1;
errors();
}
}
//ADS1115 INDEX / CONNECTION CHECK.
ads.begin(); // 0x48, 0x49, 0x4A, 0x4B
if (ads.begin()) {
while (!ads.begin()){
errorType = 2;
errors();
}
}
ads.setGain(GAIN_EIGHT);
// BUTTON A
buttonMenu.setDebounce(50);
buttonMenu.setTimeout(300);
buttonMenu.setClickTimeout(600);
buttonMenu.setType(HIGH_PULL);
buttonMenu.setDirection(NORM_OPEN);
// BUTTON B
buttonSel.setDebounce(50);
buttonSel.setTimeout(300);
buttonSel.setClickTimeout(600);
buttonSel.setType(HIGH_PULL);
buttonSel.setDirection(NORM_OPEN);
// DISPLAY INIT
oled.begin(128, 32, sizeof(tiny4koled_init_128x32br), tiny4koled_init_128x32br);
oled.setFont(FONT8X16);
oled.on();
bootDisplay();
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
ampReadings[thisReading] = 0;
voltReadings[thisReading] = 0;}
}
bool V_I = true; // select mode X / Y
void loop() {
//Serial.print("System ON, Initialize PASS...");
buttonMenu.tick();
buttonSel.tick();
Enc1.tick();
if(buttonMenu.isClick()){} // BTN_MENU END
if(buttonMenu.isHolded()){}
if(buttonSel.isClick()){
if(page == 0){
if(V_I){
V_I = false;
oled.setFont(FONT6X8);
oled.setCursor(0, 2);
oled.print(" ");
oled.setCursor(70, 2);
oled.print(">");
}else {
V_I = true;
oled.setFont(FONT6X8);
oled.setCursor(0, 2);
oled.print(">");
oled.setCursor(70, 2);
oled.print(" ");
}
}
} // BTN_SELECTION END
if(buttonSel.isHolded()){
if(btnMenuCount){digitalWrite(ENABLE, HIGH); btnMenuCount = false;}else{digitalWrite(ENABLE, LOW); btnMenuCount = true;}
}
if(Enc1.right()){
if(page == 0){
if(V_I){
if(voltSet < voltSetMax){
voltSet = voltSet + 0.1;
//mcpV.setVoltage(voltSet, false);
}
} else {
if(ampereSet < ampereSetMax){
ampereSet = ampereSet + 0.1;
//mcpA.setVoltage(ampereSet, false);
}
}
oled.setFont(FONT6X8);
oled.setCursor(8, 2);
oled.print(" ");
oled.setCursor(8, 2);
oled.print(voltSet);
oled.setCursor(80, 2);
oled.print(" ");
oled.setCursor(80, 2);
oled.print(ampereSet);
}
} // ENC RIGHT END
if(Enc1.left()){
if(page == 0){
if(V_I){
if(voltSet > 0){
voltSet = voltSet - 0.1;
//mcpV.setVoltage(voltSet, false);
}
}else{
if(ampereSet > 0){
ampereSet = ampereSet - 0.1;
//mcpA.setVoltage(ampereSet, false);
}
}
oled.setFont(FONT6X8);
oled.setCursor(8, 2);
oled.print(" ");
oled.setCursor(8, 2);
oled.print(voltSet, 2);
oled.setCursor(80, 2);
oled.print(" ");
oled.setCursor(80, 2);
oled.print(ampereSet, 2);
}
} // ENC LEFT END
ReadAnalogValue(); //verificare velocità esecuzione
HeatSink();
drawMenu();
sCom();
//serialDataRead();
//serialDataSend();
} // LOOP END
void bootDisplay(){
oled.clear();
oled.setCursor(5, 0);
oled.print("PPS v1");
oled.setCursor(5, 2);
oled.print("SerTech");
delay(2000);
//tone(BUZZ,1000, 200);
}
void drawMenu(){
if(page == 0){
if(FIRST){
//tone(BUZZ,1000, 200);
FIRST = false;
oled.clear();
oled.setFont(FONT8X16);
oled.setCursor(50, 0);
oled.print("V");
oled.setCursor(119, 0);
oled.print("A");
oled.setFont(FONT6X8);
oled.setCursor(50, 2);
oled.print("V");
oled.setCursor(119, 2);
oled.print("A");
if(V_I){
oled.setFont(FONT6X8);
oled.setCursor(0, 2);
oled.print(">");
oled.setCursor(70, 2);
oled.print(" ");
} else {
oled.setCursor(0, 2);
oled.print(" ");
oled.setCursor(70, 2);
oled.print(">");
}
oled.setFont(FONT8X16);
oled.setCursor(8, 0);
oled.print(voltRead);
oled.setCursor(80, 0);
oled.print(ampereRead);
// print set value
oled.setFont(FONT6X8);
oled.setCursor(8, 2);
oled.print(voltSet);
oled.setCursor(80, 2);
oled.print(ampereSet);
oled.setFont(FONT6X8);
oled.setCursor(32, 3);
oled.print(" C");
}
// refresh analog read
if(millis() - refreshTime > 300){
refreshTime = millis();
oled.setFont(FONT8X16);
oled.setCursor(8, 0);
oled.print(" ");
oled.setCursor(8, 0);
oled.print(voltRead);
oled.setCursor(80, 0);
oled.print(" ");
oled.setCursor(80, 0);
oled.print(ampereRead);
}
} // END PAGE 0
}
void ReadAnalogValue(){
volts = 0;
ampere = 0;
for(numReadings = 0; numReadings < 6; numReadings++){
//ampere += ads.readADC_Differential_0_1();
//volts += ads.readADC_SingleEnded(1);
volts += analogRead(A0);
}
ampAverage = ampere / numReadings;
if(ampAverage < 0){ampAverage = 0;}
voltAverage = volts / numReadings;
if(voltAverage < 0){voltAverage = 0;}
voltRead = voltAverage * GAIN;
ampereRead = ampAverage * GAIN * calibA * 100;
}
void HeatSink(){
if (millis() - timeTemp > 3000){
ds18b20.requestTemperatures();
ds18b20Temp = ds18b20.getTempCByIndex(0);
timeTemp = millis();
oled.setFont(FONT6X8);
oled.setCursor(8, 3);
oled.print(" ");
oled.setCursor(8, 3);
oled.print(ds18b20Temp, 1);
}
if ((ds18b20Temp > tempThreshold) & (ds18b20Temp != ds18b20TempPrev)){
ds18b20TempPrev = ds18b20Temp;
fanSpeed = map(constrain (ds18b20Temp, tempThreshold, tempMax), tempThreshold, tempMax, 50, 255);
analogWrite(FAN, fanSpeed);
//Serial.print(fanSpeed);
w1 = 1;
} else{
if((w1 == 1) & (ds18b20Temp != ds18b20TempPrev)){
ds18b20TempPrev = ds18b20Temp;
fanSpeed = 0;
analogWrite(FAN, fanSpeed);
//Serial.print(fanSpeed);
w1 = 0;}
}
}
void errors(){
switch (errorType){
case(0):
Serial.println("Failed to initialize MCP.");
Serial.print("\n");
digitalWrite(ERROR, LOW);
tone(BUZZ, 500, 100);
delay(errorTime);
digitalWrite(ERROR, HIGH);
tone(BUZZ, 500, 100);
Serial.print("Check MCP4725 Connection!");
Serial.print("\n");
break;
case(1):
Serial.println("Failed to initialize MCP.");
Serial.print("\n");
digitalWrite(ERROR, LOW);
tone(BUZZ, 800, 100);
delay(errorTime);
digitalWrite(ERROR, HIGH);
tone(BUZZ, 800, 100);
Serial.print("Check MCP4725 Connection!");
Serial.print("\n");
break;
case(2):
Serial.println("Failed to initialize ADS.");
Serial.print("\n");
digitalWrite(ERROR, LOW);
tone(BUZZ, 1000, 100);
delay(errorTime);
digitalWrite(ERROR, HIGH);
tone(BUZZ, 1000, 100);
Serial.print("Check ADS1115 Connection!");
Serial.print("\n");
break;
case(3):
break;
}
}
void beeper(){}
void sCom(){} //verificare connessione seriale e visualizzare stato su lcd
void serialDataRead(){ //modificare dati in arrivo tensione e corrente
String readDataString;
int n = 0;
while(Serial.available()){
char incomingData = Serial.read();
readDataString += incomingData;}
Serial.print(readDataString);
if (readDataString.length() > 0){n = readDataString.toInt();
if (n >= 0 && n <= 2000){voltSet = n/10;Serial.print(voltSet);n = 0;}}
else if (n > 2000 && n <= 2500) {ampereSet = (n - 2000)/100;n = 0;}
else if (n == 9000) {if(btnMenuCount){digitalWrite(ENABLE, HIGH); btnMenuCount = false;}else{digitalWrite(ENABLE, LOW); btnMenuCount = true;}}
readDataString = "";
}
void serialDataSend(){
Serial.print(ENABLE, DEC);
Serial.print(",");
Serial.print(voltRead, DEC);
Serial.print(",");
Serial.print(ampereRead, DEC);
Serial.print(",");
Serial.print(voltSet, DEC);
Serial.print(",");
Serial.print(ampereSet, DEC);
Serial.print(",");
Serial.print(ds18b20Temp, DEC);
Serial.print(",");
Serial.print(ERROR, DEC);
Serial.print(",");
Serial.println();
}