#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>
#include <Wire.h>
#include <Adafruit_INA219.h>
#define ENCODER_CLK 3
#define ENCODER_DT 4
#define ENCODER_SW 5
#define MOSFET 6
#define val_c A0
#define codeVersion "0.1"
int menu = 0, menu_sous = 0, tmp = 0, tmp_tps = 0, decal = 0, pwm = 100;
int *val1;
boolean menuB=false;
float rev=0; int rpm; int oldtime=0; int time;
float volt, current; int value;
Adafruit_SSD1306 display(128, 32, &Wire, -1);
Adafruit_INA219 ina219;
int prog_rap[] = {8,4,10,20,30,40,50,60,80,100};
int prog_lon[] = {14,40,10,15,20,25,30,35,40,45,50,55,60,70,85,100};
int prog_per[22];
int prog_tra[22];
int perso_deb=10, perso_pal=4, perso_tps=10;
int prog_av[3]; // step tps-s tps-m
int cur_read() {
// ACS712 5A
float AcsValue=0.0,Samples=0.0,AvgAcs=0.0,AcsValueF=0.0;
for (int x = 0; x < 5; x++){ //Get 150 samples
AcsValue = analogRead(val_c); //Read current sensor values
Samples = Samples + AcsValue; //Add samples together
delay (2); // let ADC settle before next sample 3ms
}
AvgAcs=Samples/150.0;//Taking Average of Samples
//((AvgAcs * (5.0 / 1024.0)) is converitng the read voltage in 0-5 volts
//2.5 is offset(I assumed that arduino is working on 5v so the viout at no current comes
//out to be 2.5 which is out offset. If your arduino is working on different voltage than
//you must change the offset according to the input voltage)
//0.066v(66mV) is rise in output voltage when 1A current flows at input
AcsValueF = (2.5 - (AvgAcs * (5.0 / 1024.0)) )/0.185;
return AcsValueF;
}
void aff_com() {
val1 = &tmp;
if(prog_av[0] == 0) {
prog_av[0] = 1;
prog_av[1] = 60;
prog_av[2] = prog_tra[1]-1;
}
if(prog_av[1] == 0) { prog_av[1] = 60; prog_av[2]--; }
if(prog_av[2] == 0) { prog_av[2] = prog_tra[1]; prog_av[0]++; }
// aff fin
if(prog_av[0] > prog_tra[1]) {
display.setCursor(30,20);
display.println("Fini");
}
// aff step
else {
display.setCursor(40,0);
display.print(prog_av[0]);
display.print(F(" / "));
display.print(prog_tra[0]);
display.setCursor(0,8*2);
display.print(F("Tps "));
display.print(prog_av[2]);
display.print(F(":"));
display.print(prog_av[1]);
display.setCursor(60,8*3);
display.print(F("RPM "));
display.print(rpm);
display.setCursor(66,8*2);
display.print(F("mA "));
display.print(current);
display.setCursor(88,0);
display.print(prog_tra[1+prog_av[0]]);
display.print(F(" %"));
analogWrite(MOSFET, prog_tra[1+prog_av[0]]);
}
}
void updateDisplay() {
display.clearDisplay();
display.setFont();
display.setTextColor(1);
display.setCursor(0,0);
tmp_tps = 1;
switch(menu) {
// choix
case 1:
case 2:
case 3:
case 4:
menu_sous = 0; menuB = 0; pwm = 100;
display.println(F(" T E S T"));
display.println(F(" Rapide 32min"));
display.println(F(" Long 6H"));
display.println(F(" Perso"));
display.setCursor(0,8*(menu-1));
display.print(F(">"));
break;
case 14:
if(menuB) switch(menu_sous) {
case 0: val1 = &perso_pal; break;
case 1: val1 = &perso_tps; break;
case 2: val1 = &perso_deb; break;
}
else val1 = &menu_sous;
display.print(F(" Nb palier ")); display.println(perso_pal);
display.print(F(" Tps palier ")); display.print(perso_tps); display.println(F(" min"));
display.print(F(" Point depart ")); display.println(perso_deb);
display.println(F(" Start "));
display.setCursor(0,8*menu_sous);
display.print(menuB ? F("*") : F(">"));
break;
// action
case 11:
val1 = &pwm;
analogWrite(MOSFET, pwm);
display.setCursor(20,0);
display.print(F("RPM"));
display.setTextSize(2);
display.setCursor(40,10);
display.print(rpm);
display.setTextSize(1);
display.setCursor(0,8*2);
display.println(F("mA "));
display.println(current);
display.setCursor(90,0);
display.print(pwm);
display.print(F("%"));
break;
case 12: display.print(F("Rapide")); memcpy(prog_tra, prog_rap, sizeof(prog_rap)); aff_com(); break;
case 13: display.print(F("Long")); memcpy(prog_tra, prog_lon, sizeof(prog_lon)); aff_com(); break;
case 24: display.print(F("Perso")); memcpy(prog_tra, prog_per, sizeof(prog_per)); aff_com(); break;
//
case 21:
case 22:
case 23:
case 34:
analogWrite(MOSFET, 0);
val1 = &menu;
menu = menu%10;
prog_av[0] = 0;
display.setCursor(40,10);
display.print(F("Abandon"));
tmp_tps = 1000;
break;
// accueil
default :
display.println(F("Penn Ar Slot"));
display.println(F(" Rodage"));
display.println(codeVersion);
display.println(F(" by TIPOUIC / LOOPYS"));
break;
}
display.drawLine(0, display.height()-1, display.width()-1, display.height()-1, SSD1306_WHITE);
display.display();
delay(tmp_tps);
}
void isr() { rev++; }
void setup() {
Serial.begin(9600);
perso_pal = EEPROM.read(0);
perso_tps = EEPROM.read(1);
perso_deb = EEPROM.read(2);
if(perso_pal<2 || perso_pal>20 || perso_deb<10 || perso_deb>100) {
perso_deb=10;
perso_pal=4;
perso_tps=10;
}
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_SW, INPUT_PULLUP);
pinMode(MOSFET, OUTPUT);
digitalWrite(MOSFET, LOW);
attachInterrupt(0,isr,RISING); //attaching the interrupt
updateDisplay();
delay(3000);
menu++;
val1 = &menu;
prog_av[0] = 0;
if (! ina219.begin()) {
Serial.println("Failed to find INA219 chip");
while (1) { delay(10); }
}
updateDisplay();
}
long int modeLastChanged = 0;
int prevClk = HIGH;
void loop() {
// encodeur
int clk = digitalRead(ENCODER_CLK);
if (clk != prevClk && clk == LOW) {
decal = (menu == 11)? 5 : 1;
if(digitalRead(ENCODER_DT) == HIGH) { *val1-=decal; }
else { *val1+=decal; }
if(menu == 0) menu=4;
else if(menu == 5) menu=1;
if(menu_sous<0) menu_sous=3;
if(menu_sous>3) menu_sous=0;
if(pwm<5) pwm=5;
if(pwm>100) pwm=100;
if(perso_pal < 2) perso_pal = 2;
if(perso_pal > 20) perso_pal = 20;
if(perso_tps < 1) perso_tps = 1;
if(perso_deb < 10) perso_deb = 10;
updateDisplay();
}
prevClk = clk;
if (digitalRead(ENCODER_SW) == LOW && millis() - modeLastChanged > 300) {
modeLastChanged = millis();
if(menu == 14) {
menuB = !menuB;
if(menuB && menu_sous==3) {
menu += 10;
val1 = &tmp;
prog_per[0] = perso_pal;
prog_per[1] = perso_tps;
tmp = (100 - perso_deb) / (perso_pal - 1);
int j = 2;
for(int i = perso_deb; i <= 100; i+= tmp) {
prog_per[j] = i;
j++;
}
EEPROM.update(0, perso_pal);
EEPROM.update(1, perso_tps);
EEPROM.update(2, perso_deb);
}
}
else menu += 10;
updateDisplay();
}
time=millis()-oldtime;
if(time > 1000) {
detachInterrupt(0); //detaches the interrupt
rpm=(rev/time)*60000; //calculates rpm
// current = cur_read();
current = ina219.getCurrent_mA();
volt = ina219.getShuntVoltage_mV();
Serial.print("% mV MA: "); Serial.print(pwm); Serial.print("%");
Serial.print(" "); Serial.print(volt); Serial.print(" mV");
Serial.print(" "); Serial.print(current); Serial.println(" mA");
oldtime=millis(); //saves the current time
rev=0;
prog_av[1]--;
updateDisplay();
attachInterrupt(0,isr,RISING);
}
}