#include <AccelStepper.h>
#include <EEPROM.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// === OLED ===
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// === Stepper ===
const int stepPin = 4;
const int dirPin = 3;
AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin);
// === Pulsanti ===
const int btnOrario = 5;
const int btnAntiorario = 6;
const int btnSalva = 7;
const int btnVaiA = 8;
// === Costanti meccaniche ===
const float stepPerMM = 50.0; // passi per millimetro
// === Posizioni salvate ===
const int maxPosizioni = 10;
long posizioni[maxPosizioni];
int posSalvate = 0;
int indiceCorrente = 0;
long posizioneAttuale = 0;
int pausa=10;//pausa per moto continuo
// EEPROM
const int eepromStart = 0;
void setup() {
Serial.begin(9600);
Serial.println("init...");
// OLED Init
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 non trovato"));
while (true);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Sistema pronto");
display.display();
delay(1000);
// Stepper setup
stepper.setMaxSpeed(1000);
stepper.setAcceleration(200);
// Pin setup
pinMode(btnOrario, INPUT_PULLUP);
pinMode(btnAntiorario, INPUT_PULLUP);
pinMode(btnSalva, INPUT_PULLUP);
pinMode(btnVaiA, INPUT_PULLUP);
// Carica posizioni da EEPROM
EEPROM.get(eepromStart, posSalvate);
if (posSalvate < 0 || posSalvate > maxPosizioni) posSalvate = 0;
for (int i = 0; i < posSalvate; i++) {
EEPROM.get(eepromStart + sizeof(int) + i * sizeof(long), posizioni[i]);
Serial.println("Sistema pronto");
}
updateDisplay();
}
void loop() {
stepper.run();
bool orarioPressed = digitalRead(btnOrario) == LOW;
bool antiorarioPressed = digitalRead(btnAntiorario) == LOW;
bool salvaPressed = digitalRead(btnSalva) == LOW;
bool vaiPressed = digitalRead(btnVaiA) == LOW;
// Movimento continuo manuale
if (orarioPressed) {
posizioneAttuale += 2;
stepper.moveTo(posizioneAttuale);
delay(pausa);
} else if (antiorarioPressed) {
posizioneAttuale -= 2;
stepper.moveTo(posizioneAttuale);
delay(pausa);
}
// RESET lista se Salva + Vai premuti insieme
if (salvaPressed && vaiPressed) {
resetListaEEPROM();
display.clearDisplay();
display.setCursor(0, 0);
display.println("EEPROM RESET!");
display.display();
delay(1000);
updateDisplay();
Serial.println(" reset");
}
// Salvataggio posizione
static bool salvaPrev = false;
if (salvaPressed && !salvaPrev && !vaiPressed) {
if (posSalvate < maxPosizioni) {
posizioni[posSalvate] = posizioneAttuale;
posSalvate++;
EEPROM.put(eepromStart, posSalvate);
for (int i = 0; i < posSalvate; i++) {
EEPROM.put(eepromStart + sizeof(int) + i * sizeof(long), posizioni[i]);
}
Serial.print("Salvata posizione: ");
Serial.println(posizioneAttuale);
updateDisplay();
} else {
Serial.println("Lista piena!");
}
delay(300);
}
salvaPrev = salvaPressed;
// Vai alla prossima posizione
static bool vaiPrev = false;
if (vaiPressed && !vaiPrev && !salvaPressed && posSalvate > 0) {
posizioneAttuale = posizioni[indiceCorrente];
stepper.moveTo(posizioneAttuale);
Serial.print("vai a ");
Serial.print(indiceCorrente);
Serial.print(" Pos: ");
Serial.println((posizioneAttuale - posizioni[0]) / stepPerMM);
display.clearDisplay();
display.setCursor(0, 0);
display.print("Vai a pos #");
display.print(indiceCorrente);
display.setCursor(0, 16);
display.print("Step: ");
display.print(posizioneAttuale);
display.setCursor(0, 32);
display.print("Pos: ");
display.print((posizioneAttuale - posizioni[0]) / stepPerMM, 2);
display.println(" mm");
display.display();
indiceCorrente = (indiceCorrente + 1) % posSalvate;
delay(300);
}
vaiPrev = vaiPressed;
}
void updateDisplay() {
float posizioneMM = (posizioneAttuale - posizioni[0]) / stepPerMM;
display.clearDisplay();
display.setCursor(0, 0);
display.print("Posizioni: ");
display.println(posSalvate);
display.setCursor(0, 16);
display.print("Step: ");
display.println(posizioneAttuale);
display.setCursor(0, 32);
display.print("Pos: ");
display.print(posizioneMM, 2);
display.println(" mm");
display.display();
Serial.print("Posizioni: ");
Serial.println(posSalvate);
Serial.print("Step: ");
Serial.println(posizioneAttuale);
Serial.print(posizioneMM, 2);
Serial.println(" mm");
}
void resetListaEEPROM() {
posSalvate = 0;
indiceCorrente = 0;
for (int i = 0; i < maxPosizioni; i++) posizioni[i] = 0;
EEPROM.put(eepromStart, posSalvate);
}