// KY-040 Rotary Encoder Example
// Taken from: https://docs.wokwi.com/parts/wokwi-ky-040
// Copyright (C) 2021, Uri Shaked
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO: A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO: 2(SDA), 3(SCL), ...
// #define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define ENCODER_CLK 2
#define ENCODER_DT 3
const int Button_Select_Start = 13; // Button Select_Start su GPIO13
const int Button_Set = 12; // Button Set su GPI12
int k_Current; // Indice per costruzione vettore corrente
int l_Time; // Indice per riferimento TimeStamp parziale
int Flag_Start; // Flag Antirimbalzo per pulsante
int Flag_Delay; // Flag Antirimbalzo per Delay
int Flag_Start_Button; // Flag Antirimbalzo per Pulsanti CW CCW
int Flag_text; // Flag per TextMode Blink Cerchio Stato
int Current, Voltage, Pressione, Portata;
int StateId = 0; // Indice di Stato : 0 : Stato di Attesa ; 1 : Stato di Attivazione ; 2 : Analisi Dati ; 3 : Pubblicazione ; 4 : Acquisizione continua ; 6 : Impostazione Parametri
const int BufferSize = 120; // Dimensione Buffer Acquisizione Corrente in Transitorio
// Definizione Variabili Temporali
int Periodo_Acquisizione = 100; // Periodo di Acquisizione // PARAMETRO
int Tempo_Innesco = 1000; // Tempo Innesco // PARAMETRO
int Tempo_Test = 5000; // Tempo Test // PARAMETRO
int Tempo_Svuotamento = 2000; // Tempo Svuotamento // PARAMETRO
unsigned long myTime_Start; // Inizializzazione contatore del tempo per acquisizione corrente
unsigned long DeltaTime; // Contatore del tempo trascorso per acquisizione corrente
unsigned long myTime_Start_Wait;// Inizializzazione contatore del tempo per gestione wait
unsigned long DeltaTime_Wait; // Contatore del tempo trascorso per gestione wait
unsigned long myTime_Start_Button; // Inizializzazione contatore per T_ON
unsigned long DeltaTime_Button; // Contatore del tempo trascorso per T_ON
// Definizione Vettori
int CurrentArray[BufferSize]; // Array Corrente
int TimeArray[BufferSize]; // Array TimeStamp
int PressioneArray[BufferSize]; // Array Pressione
int PortataArray[BufferSize]; // Array Pressione
void setup() {
Serial.begin(115200);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
// Imposta Pulsante di Button_Select_Start e Button_Set come Input
pinMode( Button_Select_Start, INPUT);
pinMode( Button_Set, INPUT);
// Impostazione Pin Encoder come Input
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
// Clear the buffer
display.clearDisplay();
display_Setup_Mode();
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
display.display();
}
int lastClk = HIGH;
void loop() {
int newClk = digitalRead(ENCODER_CLK);
if (newClk != lastClk) {
// There was a change on the CLK pin
lastClk = newClk;
int dtValue = digitalRead(ENCODER_DT);
if (newClk == LOW && dtValue == HIGH) {
Serial.println("Rotated clockwise ⏩");
}
if (newClk == LOW && dtValue == LOW) {
Serial.println("Rotated counterclockwise ⏪");
}
}
}
// #########################################################################
// Draw Display for Text Mode su SSD1306
// #########################################################################
void display_Setup_Mode()
{
// Funzione per Gestione Paremetri su Display SSD1306
// LISTA VARIABILI GLOBALI
// int Periodo_Acquisizione = 100; // Periodo di Acquisizione // PARAMETRO
// int Tempo_Innesco = 1000; // Tempo Innesco // PARAMETRO
// int Tempo_Test = 5000; // Tempo Test // PARAMETRO
// int Tempo_Svuotamento = 2000; // Tempo Svuotamento // PARAMETRO
int X_Text_Loc; // Coordinata Multiplo X
int Y_Text_Loc; // Coordinata Multiplo Y
int X_loc, Y_loc;
unsigned long myTime_Start_Setup; // Inizializzazione contatore per SETUP
unsigned long DeltaTime_Setup; // Contatore del tempo trascorso per SETUP
unsigned long l_time_Setup; // Contatore del tempo parziale per SETUP - BLINKING
unsigned long MaxTime_Setup = 30000; // Tempo Massimo visualizzazione Setup
unsigned long Prev_Time = 0;
int Index_Param = 2; // Indice Parametro : Valore ammesso da 2 a 7
int Flag_Start_Setup = 0; // Flag Lettura stato Pulsanti
int Flag_blink = 0;
int ID_tmp_0_loc, ID_tmp_1_loc, ID_tmp_2_loc;
X_Text_Loc = (SCREEN_WIDTH * 1) / 13; // Coordinate X per TextMode
Y_Text_Loc = (SCREEN_HEIGHT * 1) / 8; // Coordinate Y per TextMode
// Clear the buffer
display.clearDisplay();
// Scrive le Intestazioni
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
X_loc = 2 * X_Text_Loc;
Y_loc = 1 * Y_Text_Loc-2;
display.setCursor(X_loc, Y_loc);
display.print("SETUP PARAMETERS");
// SCRITTURA RIGA 2 - Periodo_Acquisizione
X_loc = 1 * X_Text_Loc;
Y_loc = 2 * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
display.print("T_Acq [ms]");
X_loc = 10 * X_Text_Loc;
Y_loc = 2 * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
display.print( Periodo_Acquisizione);
// SCRITTURA RIGA 3 - Tempo_Innesco
X_loc = 1 * X_Text_Loc;
Y_loc = 3 * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
display.print("T_Inn [ms]");
X_loc = 10 * X_Text_Loc;
Y_loc = 3 * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
display.print(Tempo_Innesco);
// SCRITTURA RIGA 4 - Tempo_Test
X_loc = 1 * X_Text_Loc;
Y_loc = 4 * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
display.print("T_Tst [ms]");
X_loc = 10 * X_Text_Loc;
Y_loc = 4 * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
display.print(Tempo_Test);
// SCRITTURA RIGA 5 - Tempo_Svuotamento
X_loc = 1 * X_Text_Loc;
Y_loc = 5 * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
display.print("T_Svt [ms]");
X_loc = 10 * X_Text_Loc;
Y_loc = 5 * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
display.print(Tempo_Svuotamento);
/*
// Riga 6 e 7 Non utilizzate, sono a disposizione
// SCRITTURA RIGA 6 - BLANK_TIME_ATT
X_loc = 1 * X_Text_Loc;
Y_loc = 6 * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
display.print("BLANK TIME ATT");
// X_loc = 7 * X_Text_Loc;
// Y_loc = 6 * Y_Text_Loc;
// display.setCursor(X_loc, Y_loc);
// display.print("100 - 500 ; 50 ");
X_loc = 10 * X_Text_Loc;
Y_loc = 6 * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
display.print(Blank_Time_Attuazioni);
// SCRITTURA RIGA 7 - CICLI RODAGGIO
X_loc = 1 * X_Text_Loc;
Y_loc = 7 * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
display.print("CICLI RODAGGIO");
// X_loc = 7 * X_Text_Loc;
// Y_loc = 7 * Y_Text_Loc;
// display.setCursor(X_loc, Y_loc);
// display.print("1 - 14 ; 1 ");
X_loc = 10 * X_Text_Loc;
Y_loc = 7 * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
display.print(CICLI_RODAGGI_ATTESI);
*/
display.display(); // Show the display buffer on the screen
// Editor Valori
myTime_Start_Setup = millis();
DeltaTime_Setup = millis() - myTime_Start_Setup;
l_time_Setup = DeltaTime_Setup;
// Lettura Stato pulsanti
Flag_Start_Setup = ( (digitalRead(Button_Select_Start) == false) ) + 10 * ( (digitalRead(Button_Set) == false) );
Flag_blink = 0;
// Il Setup è visualizato per MaxTime_Setup oppure fino alla pressione contemporanea dei pulsanti
while ( (DeltaTime_Setup < MaxTime_Setup) && (Flag_Start_Setup != 11) ) {
if ( (DeltaTime_Setup - l_time_Setup > 500) ) {
if (Flag_blink == 0) {
display.setTextColor(SSD1306_WHITE); // Draw white text
Flag_blink = 1;
}else{
display.setTextColor(SSD1306_BLACK); // Draw white text
Flag_blink = 0;
}
if ( (Flag_Start_Setup == 1) && ( Flag_blink == 0) ) { // Pulsante LOCK Premuto - SELECT Seleziona Parametro
Index_Param ++;
if (Index_Param >= 6) {
Index_Param = 2;
}
}
X_loc = 10 * X_Text_Loc;
Y_loc = Index_Param * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
if (Flag_Start_Setup == 10) {
// Se premuto il pulsante di VALUE, cancello il valore precendente
display.fillRect(X_loc, Y_loc, 20, 8, SSD1306_BLACK);
display.setTextColor(SSD1306_WHITE); // Draw white text
display.display();
delay(1);
}
switch (Index_Param) {
case 2 :
if (Flag_Start_Setup == 10) { // Pulsante UNLOCK Premuto - VALUE Imposta Valore Parametro
Periodo_Acquisizione = Periodo_Acquisizione + 10;
if ( Periodo_Acquisizione >= 111) {
Periodo_Acquisizione = 10;
}
} // if (Flag_Start_Setup == 10) {
display.print(Periodo_Acquisizione);
break;
case 3 :
if (Flag_Start_Setup == 10) { // Pulsante UNLOCK Premuto - VALUE Imposta Valore Parametro
Tempo_Innesco = Tempo_Innesco + 5 * Periodo_Acquisizione ;
if ( Tempo_Innesco >= 25 * Periodo_Acquisizione) {
Tempo_Innesco = 10 * Periodo_Acquisizione;
}
} // if (Flag_Start_Setup == 10) {
display.print(Tempo_Innesco);
break;
case 4 :
if (Flag_Start_Setup == 10) { // Pulsante UNLOCK Premuto - VALUE Imposta Valore Parametro
Tempo_Test = Tempo_Test + 5 * Periodo_Acquisizione ;
if ( Tempo_Test >= 25 * Periodo_Acquisizione) {
Tempo_Test = 10 * Periodo_Acquisizione;
}
} // if (Flag_Start_Setup == 10) {
display.print(Tempo_Test);
break;
case 5 :
if (Flag_Start_Setup == 10) { // Pulsante UNLOCK Premuto - VALUE Imposta Valore Parametro
Tempo_Svuotamento = Tempo_Svuotamento + 5 * Periodo_Acquisizione ;
if ( Tempo_Svuotamento >= 25 * Periodo_Acquisizione) {
Tempo_Svuotamento = 10 * Periodo_Acquisizione;
}
} // if (Flag_Start_Setup == 10) {
display.print(Tempo_Svuotamento);
break;
/*
// I casi 6 e 7 non sono utilizzati, sono disponibili
case 6 :
if (Flag_Start_Setup == 10) { // Pulsante UNLOCK Premuto - VALUE Imposta Valore Parametro
Blank_Time_Attuazioni = Blank_Time_Attuazioni + 50;
if ( Blank_Time_Attuazioni >= 550) {
Blank_Time_Attuazioni= 100;
}
} // if (Flag_Start_Setup == 10) {
display.print(Blank_Time_Attuazioni);
break;
case 7 :
if (Flag_Start_Setup == 10) { // Pulsante UNLOCK Premuto - VALUE Imposta Valore Parametro
CICLI_RODAGGI_ATTESI = CICLI_RODAGGI_ATTESI + 1;
if ( CICLI_RODAGGI_ATTESI >= 15) {
CICLI_RODAGGI_ATTESI= 1;
}
} // if (Flag_Start_Setup == 10) {
display.print(CICLI_RODAGGI_ATTESI);
break;
*/
default :
X_loc = 10 * X_Text_Loc;
Y_loc = 7 * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
display.print("ERRORE INDICI");
break;
} // switch (Index_Param) {
} // if ( (DeltaTime_Setup - l_time_Setup > 500) {
display.display();
DeltaTime_Setup = millis() - myTime_Start_Setup;
Flag_Start_Setup = ( (digitalRead(Button_Select_Start) == false) ) + 10 * ( (digitalRead(Button_Set) == false) );
X_loc = 1 * X_Text_Loc;
Y_loc = 7 * Y_Text_Loc;
display.setCursor(X_loc, Y_loc);
if ( Prev_Time != ((MaxTime_Setup - DeltaTime_Setup) /1000) ) {
// Se il tempo trascorso viene aggiornato, cancello il valore precedente e scrivo il nuovo
display.fillRect(X_loc, Y_loc, 20, 8, SSD1306_BLACK);
display.setTextColor(SSD1306_WHITE); // Draw white text
display.display();
display.print( (MaxTime_Setup - DeltaTime_Setup) /1000 );
Prev_Time = ((MaxTime_Setup - DeltaTime_Setup) /1000);
}
} // while ( (DeltaTime_Setup < 300000) || (Flag_Start_Setup != 11) ) {
StateId = 0;
} // void display_Setup_Mode()Loading
ssd1306
ssd1306