#include <EEPROM.h>
//-----------------------------------------------
// Définition des Entrée Sorties
//-----------------------------------------------
#define iPinEncClk 2
#define iPinEncDt 3
#define iPinEncSw 7
#define iPinBtnH 6
#define iPinBtnB 8
#define iPinNtcChauffe A0
#define iPinNtcProduit A1
#define oPinChauffe 5
//-----------------------------------------------
// Bibliothèque
//-----------------------------------------------
#include <Encoder.h> //--------------------------
Encoder myEnc(iPinEncClk, iPinEncDt);
//-----------------------------------------------
#include <SmoothThermistor.h> //-----------------
SmoothThermistor smoothThermistorChauffe(A0,ADC_SIZE_10_BIT, 20000, 22000, 3950, 25, 1);
SmoothThermistor smoothThermistorProduit(A1,ADC_SIZE_10_BIT, 100000, 100000, 3950, 25, 1);
//-----------------------------------------------
#include <PID_v1.h> //--------------------------
double Setpoint, Input, Output;
double Kp=0.1, Ki=0.1, Kd=0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
//----------------------------------------------
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
#define i2c_Address 0x3c //initialize with the I2C addr 0x3C Typically eBay OLED's
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // QT-PY / XIAO
Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Valeurs en EEPROM
// 0-1 = int 19369 si initialisé
// 2-3 = int Température de chauffe High
// 4-5 = int Temperature produit High
// 6-7 = int Température de chauffe Low
// 8-9 = int temperature produit Low
// 10 = shortint deltaTempLow;
// 11 = shortint deltaTempHigh;
// 12 = temperature selectionnee 0 ==> Low / 1 ==> High
// 13 = int Pid
// 15 = int pId
// 17 = int piD
int consTempChauffeLow, consTempProduitLow;
int consTempChauffeHigh, consTempProduitHigh;
int valTempChauffe, valTempProduit;
byte deltaTempLow;
byte deltaTempHigh;
int mesTempChauffe;
int mesTempProduit;
int temp;
int isInit;
bool tempSelec;
unsigned long dimmerTime,oldDimmerTime;
#define tempsAppuiCourt 50
#define tempsAppuiLong 500
#define tempsAppuiTresLong 2000
unsigned long currentTime,timeBtnH,timeBtnB,timeBtnSw;
bool flagBtnH, flagHcourt, flagHlong;
bool flagBtnB, flagBcourt, flagBlong;
bool flagBtnSw, flagSwcourt, flagSwlong, flagSwtreslong;
bool flagReglageChauffe, flagReglageProduit, flagReglagePid;
bool etatBtnB, etatBtnH, etatBtnSw;
long oldPosition;
byte reglageKpid;
int nbMesure;
int inputChauffe, inputProduit, moyenneChauffe;
int Pid, pId, piD;
//--------------------------------------------------
// Setup
//--------------------------------------------------
void setup(){
//Serial.begin(115200);
//Serial.println("debut");
smoothThermistorChauffe.useAREF(true);
smoothThermistorProduit.useAREF(true);
EEPROM.get(0, isInit); // Chargement des dernieres valeurs utilisées
if (isInit == 19369) {
EEPROM.get(2, consTempChauffeHigh);
EEPROM.get(4, consTempProduitHigh);
EEPROM.get(6, consTempChauffeLow);
EEPROM.get(8, consTempProduitLow);
EEPROM.get(10,deltaTempLow);
EEPROM.get(11,deltaTempHigh);
EEPROM.get(12,tempSelec);
EEPROM.get(13,Pid);
Kp=Pid/100;
EEPROM.get(15,pId);
Ki = pId/100;
EEPROM.get(17,piD);
Kd = piD/100;
}
else { // Séquence d'initialisation pour la premiere mise en route
for (int i = 0 ; i < EEPROM.length() ; i++) { // RAZ EEPROM
EEPROM.write(i, 255);
}
consTempChauffeLow = 510;
consTempProduitLow = 320;
EEPROM.put(6, consTempChauffeLow);
EEPROM.put(8, consTempProduitLow);
EEPROM.put(10,deltaTempLow);
EEPROM.put(11,deltaTempHigh);
consTempChauffeHigh = 750;
consTempProduitHigh = 550;
EEPROM.put(2, consTempChauffeHigh);
EEPROM.put(4, consTempProduitHigh);
tempSelec = true;
EEPROM.put(12,tempSelec);
Pid = 10;
Kp=Pid/100;
EEPROM.put(13,Pid);
pId = 10;
Ki = pId/100;
EEPROM.put(13,pId);
piD = 0;
Kd = piD/100;
EEPROM.put(13,piD);
isInit = 19369; // Validation de l'initialisation
EEPROM.put(0, isInit);
//Serial.println("initialisation");
}
if (tempSelec){
valTempChauffe = consTempChauffeHigh;
valTempProduit = consTempProduitHigh;
}
else {
valTempChauffe = consTempChauffeLow;
valTempProduit = consTempProduitLow;
}
display.begin(i2c_Address, true); // Address 0x3C default
display.setrotation(2);
display.clearDisplay();
delay(200);
Input = smoothThermistorProduit.temperature() * 10;
Setpoint = valTempProduit;
myPID.SetMode(AUTOMATIC);
//TriacDimmer::begin();
pinMode(oPinChauffe, OUTPUT);
flagBtnH = false;
flagBtnB = false;
flagBtnSw = false;
inputChauffe = 0;
inputProduit = 0;
nbMesure = 0;
reglageKpid = 0;
}
long newPosition = 0;
unsigned long oldTime300 = 0, oldTime100 = 0, oldTime1000 = 0;
//-----------------------------------------------------
// Loop
//-----------------------------------------------------
void loop() {
if (millis() > (oldTime1000 + 1000)){
oldTime1000 = millis();
inputProduit = inputProduit/nbMesure;
inputChauffe = inputChauffe/nbMesure;
nbMesure = 0;
Input = inputProduit;
moyenneChauffe = inputChauffe;
myPID.Compute();
if (!flagReglagePid) afficheTemp(inputProduit, inputChauffe);
inputProduit = 0;
inputChauffe = 0;
}
if (millis() > (oldTime100 + 100)){
oldTime100 = millis();
inputProduit = inputProduit + (smoothThermistorProduit.temperature() * 10);
inputChauffe = inputChauffe + (smoothThermistorChauffe.temperature() * 10);
nbMesure =nbMesure+1;
if (!flagReglagePid) afficheConsigne(valTempChauffe, valTempProduit);
else affichePid();
}
dimmerTherm();
gestionBouton();
gestionEncodeur();
}
//-------------------------------------------------------
// Sous Programmes
//-------------------------------------------------------
void afficheDebug(byte val){
display.setTextSize(1);
display.setTextColor(SH110X_WHITE,SH110X_BLACK);
display.setCursor(64, 55);
display.print(val);
display.print(" ");
display.display();
}
void gestionEncodeur(){
if (flagReglageProduit){
newPosition = myEnc.read();
valTempProduit = valTempProduit + ((newPosition - oldPosition)/2);
oldPosition = newPosition;
}
if (flagReglageChauffe){
newPosition = myEnc.read();
valTempChauffe = valTempChauffe + ((newPosition - oldPosition)/2);
oldPosition = newPosition;
}
if (flagReglagePid){
newPosition = myEnc.read();
if (reglageKpid ==0){
Pid = Pid + ((newPosition - oldPosition)/2);
if (Pid < 0) Pid=0;
Kp = Pid;
}
if (reglageKpid ==1){
pId = pId + ((newPosition - oldPosition)/2);
if (pId < 0) pId=0;
Ki = pId;
}
if (reglageKpid ==2){
piD = piD + ((newPosition - oldPosition)/2);
if (piD < 0) piD=0;
Kd = piD;
}
oldPosition = newPosition;
}
}
void dimmerTherm() {
dimmerTime=millis();
display.setTextSize(1);
if ((dimmerTime-oldDimmerTime)>=2550) oldDimmerTime=dimmerTime;
display.setCursor(0, 57);
if ((dimmerTime-oldDimmerTime) >= (Output*10)){
digitalWrite(oPinChauffe,false);
display.print(" ");
}
else{
if (moyenneChauffe < valTempChauffe){
digitalWrite(oPinChauffe,true);
display.setTextColor(SH110X_WHITE,SH110X_BLACK);
display.print("* ");
}
else{
display.setTextColor(SH110X_BLACK,SH110X_WHITE);
display.print("* ");
}
}
int temporaire = Output/2.55;
if (temporaire < 10) display.print(" ");
else if (temporaire < 100) display.print(" ");
display.print(temporaire);
display.print("%");
display.display();
}
void afficheTemp (double tempProduit, double tempChauffe) {
int inputEnt;
int inputVir;
//display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SH110X_WHITE,SH110X_BLACK);
display.setCursor(0, 0);
inputEnt = (tempProduit)/10;
inputVir = (tempProduit)-(inputEnt*10);
display.print(inputEnt);
display.print(".");
display.print(inputVir);
display.setCursor(0, 32);
inputEnt = tempChauffe/10;
inputVir = (tempChauffe)-(inputEnt*10);
display.print(inputEnt);
display.print(".");
display.print(inputVir);
display.display();
}
void afficheConsigne(double valTempChauffe, double valTempProduit) {// bool adjChauffe,bool adjProduit) {
int inputEnt;
int inputVir;
//display.clearDisplay();
display.setTextSize(2);
if (!flagReglageProduit) display.setTextColor(SH110X_WHITE,SH110X_BLACK);
else display.setTextColor(SH110X_BLACK,SH110X_WHITE);
display.setCursor(64, 0);
inputEnt = (valTempProduit+0.5)/10; //
inputVir = (valTempProduit+.5)-(inputEnt*10);
display.print(inputEnt);
display.print(".");
display.print(inputVir);
display.setCursor(64, 32);
if (!flagReglageChauffe) display.setTextColor(SH110X_WHITE,SH110X_BLACK);
else display.setTextColor(SH110X_BLACK,SH110X_WHITE);
inputEnt = (valTempChauffe+.5)/10;
inputVir = (valTempChauffe+.5)-(inputEnt*10);
display.print(inputEnt);
display.print(".");
display.print(inputVir);
display.display();
}
void affichePid(){
display.setTextSize(2);
if (reglageKpid == 0) display.setTextColor(SH110X_BLACK,SH110X_WHITE);
else display.setTextColor(SH110X_WHITE,SH110X_BLACK);
display.setCursor(0, 0);
display.print("Kp = ");
display.print(Pid);
display.print(" ");
if (reglageKpid == 1) display.setTextColor(SH110X_BLACK,SH110X_WHITE);
else display.setTextColor(SH110X_WHITE,SH110X_BLACK);
display.setCursor(0, 20);
display.print("Ki = ");
display.print(pId);
display.print(" ");
if (reglageKpid == 2) display.setTextColor(SH110X_BLACK,SH110X_WHITE);
else display.setTextColor(SH110X_WHITE,SH110X_BLACK);
display.setCursor(0, 40);
display.print("Kd = ");
display.print(piD);
display.print(" ");
display.display();
}
void gestionBouton() {
currentTime = millis();
etatBtnH = digitalRead(iPinBtnH);
etatBtnB = digitalRead(iPinBtnB);
etatBtnSw = digitalRead(iPinEncSw);
if (!etatBtnSw) { //Appui bouton Encodeur
if (flagBtnSw) {
if ((currentTime - timeBtnSw > tempsAppuiCourt) and !flagSwcourt){
flagSwcourt = true;
}
if ((currentTime - timeBtnSw > tempsAppuiLong) and !flagSwlong){
flagSwcourt = false;
flagSwlong = true;
}
if ((currentTime - timeBtnSw > tempsAppuiTresLong) and !flagSwtreslong){
flagSwlong = false;
flagSwtreslong = true;
}
}
else{
flagBtnSw = true;
timeBtnSw = currentTime;
}
} else {
flagBtnSw = false;
if (flagSwcourt and !flagSwlong) {
flagSwcourt = false;
flagSwlong = false;
boutonSwcourt();
}
if (flagSwlong) {
flagSwlong = false;
flagSwcourt = false;
boutonSwlong();
}
if (flagSwtreslong) {
flagSwlong = false;
flagSwcourt = false;
flagSwtreslong = false;
boutonSwtreslong();
}
}
if (!etatBtnH) { //Appui bouton Haut
if (flagBtnH) {
if ((currentTime - timeBtnH > tempsAppuiCourt) and !flagHcourt) {
flagHcourt = true;
}
if ((currentTime - timeBtnH > tempsAppuiLong) and !flagHlong) {
flagHcourt = false;
flagHlong = true;
}
} else {
flagBtnH = true;
timeBtnH = currentTime;
}
} else {
flagBtnH = false;
if (flagHcourt and !flagHlong) {
flagHcourt = false;
flagHlong = false;
boutonHcourt();
}
if (flagHlong) {
flagHlong = false;
flagHcourt = false;
boutonHlong();
}
}
if (!etatBtnB) { //Appui bouton Bas
if (flagBtnB) {
if ((currentTime - timeBtnB > tempsAppuiCourt) and !flagBcourt) {
flagBcourt = true;
}
if ((currentTime - timeBtnB > tempsAppuiLong) and !flagBlong) {
flagBcourt = false;
flagBlong = true;
}
} else {
flagBtnB = true;
timeBtnB = currentTime;
}
} else {
flagBtnB = false;
if (flagBcourt and !flagBlong) {
flagBcourt = false;
flagBlong = false;
boutonBcourt();
}
if (flagBlong) {
flagBlong = false;
flagBcourt = false;
boutonBlong();
}
}
}
void boutonHcourt() {
afficheDebug(1);
if (!flagReglagePid){
valTempChauffe = consTempChauffeHigh;
valTempProduit = consTempProduitHigh;
Setpoint = valTempProduit;
}
else{
reglageKpid = reglageKpid + 1;
if (reglageKpid > 2) reglageKpid = 0;
}
}
void boutonHlong() {
afficheDebug(2);
if (!flagReglageProduit and !flagReglageChauffe){
flagReglageProduit= true;
oldPosition = myEnc.read();
}
}
void boutonBcourt() {
afficheDebug(3);
valTempChauffe = consTempChauffeLow;
valTempProduit = consTempProduitLow;
Setpoint = valTempProduit;
}
void boutonBlong() {
afficheDebug(4);
if (!flagReglageProduit and !flagReglageChauffe){
flagReglageChauffe = true;
oldPosition = myEnc.read();
}
}
void boutonSwcourt() {
afficheDebug(5);
if (flagReglageProduit){
if (tempSelec){
EEPROM.put(4, valTempProduit);
Setpoint = valTempProduit;
consTempProduitHigh = valTempProduit;
}
else{
EEPROM.put(8, valTempProduit);
Setpoint = valTempProduit;
consTempProduitLow = valTempProduit;
}
}
if (flagReglageChauffe){
if (tempSelec) EEPROM.put(2, valTempChauffe);
else EEPROM.put(6, valTempChauffe);
}
flagReglageChauffe = false;
flagReglageProduit = false;
if (flagReglagePid){
flagReglagePid = false;
display.clearDisplay();
EEPROM.put(13,Pid);
EEPROM.put(13,pId);
EEPROM.put(13,piD);
}
}
void boutonSwlong() {
afficheDebug(6);
boutonSwcourt();
}
void boutonSwtreslong() {
afficheDebug(7);
flagReglagePid = true;
display.clearDisplay();
}