#include <SoftwareSerial.h>
#include <Nextion.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <EEPROM.h>
#include "button.h"
//#include <SoftwareReset.hpp>
Button1 btn1;
Button2 btn2;
Button3 btn3;
Button4 btn4;
int i = 0;
SoftwareSerial nextion(9, 5);// Nextion TX to pin 2 and RX to pin 3 of Arduino
Nextion myNextion(nextion, 9600); //create a Nextion object named myNextion using the nextion serial port @ 9600bps
// 0x3F I2C 주소를 가지고 있는 16x2 LCD객체를 생성합니다.(I2C 주소는 LCD에 맞게 수정해야 합니다.)
LiquidCrystal_I2C lcd(0x27, 16, 2);
int charge = 8;
int discharge = 10; // MCU port11 -> relay pin
//int analogPin = A0; // Micro
int analogPin = A5; // PCB
unsigned long start_timer = 0;
unsigned long stop_timer = 0;
unsigned long duration = 0;
uint16_t value = 0;
int valuechangeflag = 0;
int lcdchange = 0;
String message;
char data;
////////////////////////////////
float voltage = 3;
float answer = 0.0;
float answercopy = 0.0;
int answercopyflag = 0;
int measure (void);
int capvalue = 0;
int caperror = 0;
int caperrorlimit = 0;
int caperrorlimitflag = 0;
int menunum = 0;
int change = 0; //
int change2 = 0; //
int change3 = 0; //
int change4 = 0; //
int changeflag = 0;
int counter = 0;
char str[40]; // PC로 데이터 전송용 배열
int sendflag = 0;
boolean button1State;
boolean button2State;
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won't change:
const long interval = 300; // interval at which to blink (milliseconds)
void setup()
{
// I2C LCD를 초기화 합니다..
lcd.init();
//myNextion.init();
// I2C LCD의 백라이트를 켜줍니다.
lcd.backlight();
Serial.begin(9600);
pinMode(discharge, INPUT);
pinMode(charge, OUTPUT);
digitalWrite(charge, HIGH); // 기존
//digitalWrite(charge, LOW); // 테스트
btn1.begin(4); // Micro
btn2.begin(A0); // 5
btn3.begin(12);
btn4.begin(6);
changeflag = 1;
caperrorlimit = EEPROM.read(13);
if (caperrorlimit == 255) caperrorlimit = 50;
delay(100);
EEPROM.get(10, value);
if (value == 65535)
{
value = 4700;
}
myNextion.setComponentText("t0", String(value));
delay(100);
}
//void(* resetFunc) (void) = 0;
void resetFunc()
{
asm volatile(" jmp 0");
}
void loop() {
message = myNextion.listen(); //check for message
if (message == "65 0 9 0 ffff ffff ffff") {
resetFunc();
}
if (message == "65 0 7 0 ffff ffff ffff") {
Serial.println("#");
change = 11;
change3 = 1;
changeflag = 1;
sendflag = 0;
}
if (message == "65 0 1 0 ffff ffff ffff") {
if (menunum == 1)
{
change = 1;
changeflag = 1;
}
if (menunum == 2)
{
change = 1;
changeflag = 1;
if (caperrorlimit >= 15)
caperrorlimit = caperrorlimit - 5;
}
}
if (message == "65 0 6 0 ffff ffff ffff") {
if (menunum == 1)
{
change = 2;
changeflag = 1;
}
if (menunum == 2)
{
change = 2;
changeflag = 1;
if (caperrorlimit <= 45)
caperrorlimit = caperrorlimit + 5;
}
}
if (message == "65 0 8 0 ffff ffff ffff")
{
menunum++;
if (menunum == 1)
{
change = 1;
changeflag = 1;
}
if (menunum == 2)
{
change = 1;
changeflag = 1;
lcd.clear();
}
if (menunum >= 3)
{
EEPROM.put(10, value); // 인덱스 3, 4에 저장
EEPROM.write(13, caperrorlimit); // write(주소, 값)
delay(100);
change = 11;
change3 = 1;
changeflag = 1;
sendflag = 0;
}
}
//Serial.begin(9600);
if (Serial.available()) { // 만약 시리얼 통신이 온다면
//softwareReset::simple();
data = Serial.read(); // 시리얼 통신 값을 문자형변수 data에 저장
//Serial.println(data); // 그 값을 출력
if (data == '1')
{
Serial.println("#");
change = 11;
change3 = 1;
changeflag = 1;
sendflag = 0;
}
}
if (btn1.debounce())
{ //softwareReset::simple();
if (menunum == 1)
{
change = 1;
changeflag = 1;
}
if (menunum == 2)
{
change = 1;
changeflag = 1;
if (caperrorlimit >= 15)
caperrorlimit = caperrorlimit - 5;
}
}
if (btn2.debounce())
{ //softwareReset::standard();
if (menunum == 1)
{
change = 2;
changeflag = 1;
}
if (menunum == 2)
{
change = 2;
changeflag = 1;
if (caperrorlimit <= 45)
caperrorlimit = caperrorlimit + 5;
}
}
if (btn3.debounce())
{
Serial.println("#");
change = 11;
change3 = 1;
changeflag = 1;
sendflag = 0;
}
if (btn4.debounce())
{
menunum++;
if (menunum == 1)
{
change = 1;
changeflag = 1;
}
if (menunum == 2)
{
change = 1;
changeflag = 1;
lcd.clear();
}
if (menunum >= 3)
{
EEPROM.put(10, value); // 인덱스 3, 4에 저장
EEPROM.write(13, caperrorlimit); // write(주소, 값)
delay(100);
change = 11;
change3 = 1;
changeflag = 1;
sendflag = 0;
}
}
/*
myNextion.setComponentText("t0", "Hello");
delay(1000);
int value = 1234;
myNextion.setComponentText("t0", String(value));
delay(1000);
*/
if (change == 0 && changeflag == 1)
{
lcd.setCursor(0, 0);
lcd.print("measure button3");
lcd.setCursor(0, 1);
lcd.print("setup button4");
changeflag = 0;
}
switch (change) {
case 1:
if (menunum == 1) // case 1
{
if (value >= 4650 || value >= 150)
{
if (valuechangeflag == 0)
{
value = value;
valuechangeflag = 1;
}
else
{
value = value - 50;
}
}
if (change == 1 && changeflag == 1)
{
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("measure value");
if (value >= 150)
{
lcd.setCursor(0, 1);
lcd.print("<<<< ");
}
else
{
lcd.setCursor(0, 1);
lcd.print(" ");
}
lcd.setCursor(5, 1);
lcd.print(value);
lcd.setCursor(9, 1);
lcd.print("uF");
if (value <= 4650)
{
lcd.setCursor(11, 1);
lcd.print(" >>>>");
}
else
{
lcd.setCursor(11, 1);
lcd.print(" ");
}
changeflag = 0;
}
}
if (menunum == 2) // case 1
{
if (change == 1 && changeflag == 1)
{
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("capacity limit");
lcd.setCursor(0, 1);
lcd.print(" ");
if (caperrorlimit == 50)
{
lcd.setCursor(0, 1);
lcd.print("<<<< ");
}
else if (caperrorlimit >= 15)
{
lcd.setCursor(0, 1);
lcd.print("<<<< >>>>");
}
else
{
lcd.setCursor(0, 1);
lcd.print(" >>>>");
}
lcd.setCursor(6, 1);
lcd.print(caperrorlimit);
lcd.setCursor(9, 1);
lcd.print("%");
changeflag = 0;
}
}
change = 11;
break;
case 2:
if (menunum == 1) // case 2
{
if (value <= 4650)
value = value + 50;
if (change == 2 && changeflag == 1)
{
lcd.setCursor(1, 0);
lcd.print("measure value");
lcd.setCursor(0, 1);
lcd.print("<<<< ");
lcd.setCursor(5, 1);
lcd.print(value);
lcd.setCursor(9, 1);
lcd.print("uF");
if (value <= 4650)
{
lcd.setCursor(11, 1);
lcd.print(" >>>>");
}
else
{
lcd.setCursor(11, 1);
lcd.print(" ");
}
changeflag = 0;
}
}
if (menunum == 2) // case 2
{
if (change == 2 && changeflag == 1)
{
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("capacity limit");
lcd.setCursor(0, 1);
lcd.print(" ");
if (caperrorlimit <= 45)
{
lcd.setCursor(0, 1);
lcd.print("<<<< >>>>");
}
else
{
lcd.setCursor(0, 1);
lcd.print("<<<< ");
}
lcd.setCursor(6, 1);
lcd.print(caperrorlimit);
lcd.setCursor(9, 1);
lcd.print("%");
changeflag = 0;
}
}
change = 11;
break;
}
if (change3 == 1 && changeflag == 1)
{
lcd.clear();
//while (measure() >= 1010 && measure() <= 1030)
while (measure() >= 100 && measure() <= 1030)
{
lcd.setCursor(0, 0);
lcd.print(" RANGE ");
lcd.print(value);
lcd.print(" uF");
lcd.setCursor(0, 1);
lcd.print("place capacitor ");
delay(200);
lcd.setCursor(0, 1);
lcd.print(" ");
delay(200);
//voltage = measure();
counter++;
if (counter >= 4)
{
change3 = 2;
pinMode(discharge, OUTPUT);
digitalWrite(discharge, LOW);
}
}
//delay(1000);
lcd.setCursor(0, 1);
lcd.print(" ");
while (change3 == 2)
{
counter = 0;
//////////////////////////////////////////////discharging
pinMode(charge, INPUT);
pinMode(discharge, OUTPUT);
digitalWrite(discharge, LOW);
lcd.setCursor(0, 1);
lcd.print("Discharging-");//12
while (voltage > 2.0) // 2.0
{
voltage = measure();
delay(100);
lcd.setCursor(12, 1);
answer = voltage * (99.0 / 1023.0);
lcd.print((99 - answer), 0);
lcd.setCursor(14, 1);
lcd.print("%");
}
lcd.setCursor(0, 1);
lcd.print(" ");
delay(1000);
lcd.setCursor(0, 1);
lcd.print("charging-");//9
lcd.setCursor(13, 1);
lcd.print("%");
//////////////////////////////////////////////charging
pinMode(discharge, INPUT);
pinMode(charge, OUTPUT);
digitalWrite(charge, HIGH);
start_timer = micros();
if ( answercopyflag == 0)
{
while (measure() < 648)
{
lcd.setCursor(9, 1);
lcd.print(measure() * (100.0 / 1023.0), 1);
}
}
answercopyflag = 1;
stop_timer = micros();
duration = stop_timer - start_timer;
answer = duration / 10000;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("value = ");
lcd.print(answer);
lcd.print("uF");
if (answercopyflag == 1)
{
answercopy = answer;
answercopyflag = 0;
}
//delay(3000);
while (change3 == 2)
{
unsigned long currentMillis = millis();
caperror = round((answer / value) * 100);
if (caperror < caperrorlimit)
{
Serial.println("test1");
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (lcdchange == 0) {
lcd.setCursor(0, 0);
lcd.print("value = ");
lcd.print(answercopy);
//lcd.print(answer);
//Serial.println(answercopy);
lcd.print("uF");
lcd.setCursor(0, 1);
lcd.print("capacity-> ");
lcd.setCursor(11, 1);
lcd.print(" ");
lcd.setCursor(14, 1);
lcd.print(" ");
lcdchange = 1;
}
else
{
lcd.setCursor(0, 1);
lcd.print("capacity-> ");
lcd.setCursor(11, 1);
lcd.print(caperror);
if (caperror < 10)
{
lcd.setCursor(12, 1);
lcd.print("%");
}
if (caperror > 100)
{
lcd.setCursor(14, 1);
lcd.print("%");
}
if (caperror >= 10)
{
lcd.setCursor(13, 1);
lcd.print("%");
}
lcdchange = 0;
}
}
message = myNextion.listen(); //check for message
if (message == "65 0 9 0 ffff ffff ffff")
{
resetFunc();
}
if (Serial.available()) // 만약 시리얼 통신이 온다면
{
data = Serial.read(); // 시리얼 통신 값을 문자형변수 data에 저장
if (data == '1')
{
resetFunc();
}
}
if (sendflag == 0)
{
//sprintf(str, "/%d/%d/%f/\r\n", value, caperrorlimit, answercopy); //str에 숫자count저장
sprintf(str, "/%d/%d/%d/\r\n", value, caperrorlimit, (int)answercopy); //str에 숫자count저장
Serial.println(str);
sendflag = 1;
}
}
else
{
if (sendflag == 0)
{
lcd.setCursor(0, 1);
lcd.print("capacity-> ");
lcd.setCursor(11, 1);
lcd.print(caperror);
if (caperror < 10)
{
lcd.setCursor(12, 1);
lcd.print("%");
}
if (caperror > 100)
{
lcd.setCursor(14, 1);
lcd.print("%");
}
if (caperror >= 10)
{
lcd.setCursor(13, 1);
lcd.print("%");
}
//sprintf(str, "/%d/%d/%.1f/\r\n", value, caperrorlimit, answercopy); //str에 숫자count저장
sprintf(str, "/%d/%d/%d/\r\n", value, caperrorlimit, (int)answercopy); //str에 숫자count저장
Serial.println(str);
delay(2000);
lcd.setCursor(0, 0);
lcd.print(" Again Reset ");
sendflag = 1;
}
else
{
message = myNextion.listen(); //check for message
if (message == "65 0 9 0 ffff ffff ffff")
{
resetFunc();
}
if (Serial.available()) // 만약 시리얼 통신이 온다면
{
data = Serial.read(); // 시리얼 통신 값을 문자형변수 data에 저장
if (data == '1')
{
resetFunc();
}
}
}
//digitalWrite(charge, LOW);
}
}
}
}
}
int measure (void)
{
int value;
value = analogRead(analogPin);
return value;
}