#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// OLED display parameters
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Button pins
#define BUTTON_UP 2
#define BUTTON_DOWN 3
#define BUTTON_LEFT 4
#define BUTTON_RIGHT 5
#define BUTTON_OK 6
// Structures
struct Page
{
char* name;
uint8_t numCounters;
const char** counters;
};
// Global variables
Page* pages;
int** counterValues;
uint8_t numPages;//
uint8_t currentPage = 0;//
uint8_t currentCounter = 0;
bool editingCounters = false; //naviagtion entre les compteurs
bool changingValue = false; //modification de valeurs des compteurs
const uint8_t countersPerPage[] = {2, 3, 4}; // Modify as needed
void _begin()
{
// Initialiser l'afficheur OLED
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}
// Function to print text on OLED
void _print(uint8_t x, uint8_t y, const char* content)
{
display.clearDisplay();
int textWidth = display.width();
int textLength = strlen(content) * 6; // each character is ~6 pixel wide)
if (textLength > textWidth)
{
// Text exceeds screen width, enable scrolling
for (int i = 0; i <= (textLength - textWidth); i++)
{
display.clearDisplay();
display.setCursor( x-i+1, y+1);
display.print(content);
display.display();
delay(100); // Adjust delay for scroll speed
}
}
else
{
// Text fits within screen width, display normally
display.setCursor(x, y);
display.print(content);
display.display();
}
}
void setup()
{
_begin();
// Initialiser les boutons
pinMode(BUTTON_DOWN, INPUT_PULLUP);
pinMode(BUTTON_UP, INPUT_PULLUP);
pinMode(BUTTON_OK, INPUT_PULLUP);
pinMode(BUTTON_LEFT, INPUT_PULLUP);
pinMode(BUTTON_RIGHT, INPUT_PULLUP);
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.clearDisplay();
display.setCursor(0, 10);
_print(SCREEN_WIDTH - 120 ,SCREEN_HEIGHT/3 ,"Hello, World welcome back!");
display.display();
delay(2000);
// Initialiser les pages et compteurs
initializePages(sizeof(countersPerPage), countersPerPage);
updateDisplay();
}
void loop()
{
chechButton();
delay(100);
}
void updateDisplay() {
display.clearDisplay();
if (!editingCounters && !changingValue) // Navigation entre les pages
{
currentPage = currentPage % numPages; // Assure que currentPage ne dépasse pas numPages
uint8_t firstPage = (currentPage / 2) * 2; // Détermine la première page à afficher
uint8_t secondPage = firstPage + 1; // La deuxième page à afficher, si elle existe
// display.clearDisplay();
// Affiche les pages sur les deux lignes
for (uint8_t i = 0; i < 2; ++i)
{
uint8_t pageIndex = (i == 0) ? firstPage : secondPage; // Choisit la page pour chaque ligne
if (pageIndex < numPages)
{
display.setCursor(0, i * 16); // espase en fonction de mon besoin
if (pageIndex == currentPage)
{
display.print(">"); // Affiche une flèche pour la page courante
}
else
{
display.print(" "); // Espace si ce n'est pas la page courante
}
display.print(pages[pageIndex].name); // Affiche le nom de la page
}
}
}
else if (editingCounters && !changingValue) // Navigation entre les compteurs
{
// Informations sur les compteurs de la page courante
const char** currentCounters = pages[currentPage].counters; // noms des compteurs de la page courante
uint8_t numCounters = pages[currentPage].numCounters - 1; // Exclure l'option "Back" des compteurs
// Calculer le premier compteur à afficher
uint8_t firstCounter = (currentCounter / 2) * 2;
// Afficher deux compteurs par page
for (uint8_t i = 0; i < 2; ++i)
{
display.setCursor(0, i * 16); // espacement en fonction de mon besoin
uint8_t counterIndex = firstCounter + i;
if (counterIndex < numCounters)
{
// Afficher les compteurs
if (counterIndex == currentCounter)
{
display.print(">");
}
else
{
display.print(" ");
}
display.print(currentCounters[counterIndex]);
display.print("=");
display.print(counterValues[currentPage][counterIndex]);
}
else if (counterIndex == numCounters)
{
// Afficher l'option "Back"
if (currentCounter == numCounters)
{
display.print(">");
}
else
{
display.print(" ");
}
display.print("BACK");
}
}
}
else if (changingValue) // Modification de compteur
{
for (uint8_t i = 0; i < 2; ++i)
{
uint8_t counterIndex = currentCounter - (currentCounter % 2) + i;
if (counterIndex< pages[currentPage].numCounters)
{
display.setCursor(0, i * 16); // espase en fonction de mon besoin
if (counterIndex== currentCounter)
{
display.print(">");
}
else
{
display.print(" ");
}
display.print(pages[currentPage].counters[counterIndex]);
display.print("=");
display.print(counterValues[currentPage][counterIndex]);
}
}
}
display.display();
}
void chechButton()
{
if (digitalRead(BUTTON_UP) == LOW)
{
if (editingCounters) // Navigation entre les compteurs
{
uint8_t numCounters = pages[currentPage].numCounters; // nombre
currentCounter = (currentCounter - 1 + numCounters) % numCounters; // navigation circulaire de la liste
}
else // Navigation entre les pages
{
currentPage = (currentPage - 1 + numPages) % numPages;
}
updateDisplay();
while (digitalRead(BUTTON_UP) == LOW); // Attendre le relâchement du bouton
}
else if (digitalRead(BUTTON_DOWN) == LOW)
{
if (editingCounters) // Navigation entre les compteurs
{
uint8_t numCounters = pages[currentPage].numCounters; // nombre
currentCounter = (currentCounter + 1 + numCounters) % numCounters; // navigation circulaire de la liste
}
else // Navigation entre les pages
{
currentPage = (currentPage + 1 + numPages) % numPages;
}
updateDisplay();
while (digitalRead(BUTTON_DOWN) == LOW); // Attendre le relâchement du bouton
}
else if (digitalRead(BUTTON_LEFT) == LOW)
{
if (editingCounters) // Navigation entre les compteurs
{
counterValues[currentPage][currentCounter]--;
}
updateDisplay();
while (digitalRead(BUTTON_LEFT) == LOW); // Attendre le relâchement du bouton
}
else if (digitalRead(BUTTON_RIGHT) == LOW)
{
if (editingCounters)
{
counterValues[currentPage][currentCounter]++;
}
updateDisplay();
while (digitalRead(BUTTON_RIGHT) == LOW); // Attendre le relâchement du bouton
}
else if (digitalRead(BUTTON_OK) == LOW)
{
if (editingCounters) // Navigation entre les compteurs
{
if (changingValue) // Modification des compteurs
{
changingValue = false;
}
else
{
if (currentCounter == pages[currentPage].numCounters - 1) // Vérifier l'option "Back"
{
editingCounters = false; // Retour au mode affichage des pages
}
else
{
changingValue = true; // Commencer à modifier la valeur du compteur
}
}
}
else
{
editingCounters = true; // Passer au mode d'édition des compteurs
currentCounter = 0; // Réinitialiser le compteur au premier compteur
}
updateDisplay();
while (digitalRead(BUTTON_OK) == LOW); // Attendre le relâchement du bouton
}
}
// Function to initialize pages and counters
void initializePages(uint8_t numPagesInput, const uint8_t* countersPerPageInput)
{
numPages = numPagesInput;
// Allocate memory for pages and counter values
pages = new Page[numPages];
counterValues = new int*[numPages];
for (uint8_t i = 0; i < numPages; ++i)
{
pages[i].name = new char[7];
sprintf(pages[i].name, "Page%d", i + 1); // Assigning page name dynamically
pages[i].numCounters = countersPerPageInput[i] + 1; // Add 1 for the "Back" option
pages[i].counters = new const char*[pages[i].numCounters];
counterValues[i] = new int[pages[i].numCounters]{0}; // Initialize values to 0
for (uint8_t j = 0; j < pages[i].numCounters - 1; ++j)
{
pages[i].counters[j] = new char[4];
sprintf(const_cast<char*>(pages[i].counters[j]), "c%d", j + 1); // Assigning counter names dynamically
}
pages[i].counters[pages[i].numCounters - 1] = new char[7];
sprintf(const_cast<char*>(pages[i].counters[pages[i].numCounters - 1]), "Back"); // "Back" option
}
}