#include <Wire.h>
#include <Encoder.h>
#include <Adafruit_SSD1306.h>
#include <OneButton.h>
#include "images.h"
//Definizioni per l'encoder
const int CLK_PIN = 2;
const int DT_PIN = 3;
const int BUTTON_PIN = 4;
// Definizioni per il display OLED
const int OLED_I2C_ADDRESS = 0x3C;
const int OLED_WIDTH = 128;
const int OLED_HEIGHT = 64;
//Definizioni Modulo BTS7960
const int R_PWM = 5; // Controlla velocità verso destra (PWM)
const int L_PWM = 6; // Controlla velocità verso sinistra (PWM)
const int R_EN = 8; // Abilita direzione destra
const int L_EN = 7; // Abilita direzione sinistra
// inizializzazione Encoder
Encoder encoder(DT_PIN, CLK_PIN);
// Inizializzazione display OLED
Adafruit_SSD1306 oled(OLED_WIDTH, OLED_HEIGHT);
// Inizializzazione OneButton
OneButton button(BUTTON_PIN, true);
int lastEncoderValue = 0;
int lastButtonState = LOW;
bool direction = false;
// Coefficiente per il calcolo degli RPM
const float coefficienteRPM = 40.14; // calibrato con tachimetro
void setup() {
// Inizializza il display OLED
if (!oled.begin(SSD1306_SWITCHCAPVCC, OLED_I2C_ADDRESS)) {
while (true);
}
pinMode(BUTTON_PIN, INPUT_PULLUP);
button.setPressMs(300); // Imposta il tempo per la pressione lunga a 500 ms
encoder.write(0);
showHome();
showValue(0);
button.attachClick(singleClick);
button.attachLongPressStart(longPressStart);
// Impostazione pin Modulo BTS7960
pinMode(R_EN, OUTPUT);
pinMode(L_EN, OUTPUT);
pinMode(R_PWM, OUTPUT);
pinMode(L_PWM, OUTPUT);
digitalWrite(R_EN, HIGH);
digitalWrite(L_EN, HIGH);
}
void loop() {
button.tick(); // Importante per rilevare eventi del pulsante
int encoderValue = encoder.read() / 4;
// Limita il valore tra 0 e 255
if (encoderValue < 0) {
encoder.write(0);
encoderValue = 0;
}
else if (encoderValue > 255) {
encoder.write(255 * 4);
encoderValue = 255;
}
if (encoderValue != lastEncoderValue) {
showValue(encoderValue);
}
lastEncoderValue = encoderValue;
// Calcola gli RPM
float RPM = encoderValue * coefficienteRPM; // Calcola gli RPM in base al valore PWM
// Approssimazione degli RPM all'intero
int RPM_int = round(RPM); // Arrotonda a intero
// Controllo direzione e velocità
if (direction) {
analogWrite(R_PWM, 0); // Assicuriamoci che RPWM sia spento
analogWrite(L_PWM, encoderValue);
}
else {
analogWrite(L_PWM, 0); // Assicuriamoci che LPWM sia spento
analogWrite(R_PWM, encoderValue);
}
}
void singleClick() {
encoder.write(0); // Azzera il valore dell'encoder
delay(10);
showValue(0); // Mostra il valore aggiornato sul display
analogWrite(R_PWM, 0);
analogWrite(L_PWM, 0);
}
void longPressStart() {
direction = !direction; // Inverti la direzione
showValue(lastEncoderValue); // Aggiorna il display con la nuova freccia
}
void showHome() {
oled.clearDisplay();
oled.setTextSize(2);
oled.setTextColor(WHITE);
String title = "MOTOR";
String subtitle1 = "Brushed";
String subtitle2 = "Test";
// Ogni carattere è circa 12 px con size 2
int titleX = (OLED_WIDTH - (title.length() * 12)) / 2;
int subtitle1X = (OLED_WIDTH - (subtitle1.length() * 12)) / 2;
int subtitle2X = (OLED_WIDTH - (subtitle2.length() * 12)) / 2;
oled.setCursor(titleX, 0);
oled.println(title);
oled.setCursor(subtitle1X, 25);
oled.println(subtitle1);
oled.setCursor(subtitle2X, 46);
oled.println(subtitle2);
oled.display();
delay(3000);
oled.clearDisplay();
oled.display();
}
void showValue(int encVal) {
int rpm = encVal * 40.14;
String valenc = String(encVal);
String etcrpm = String("RPM");
String valrpm = String(rpm);
oled.clearDisplay();
oled.setTextSize(2);
oled.setTextColor(WHITE);
oled.setCursor(0, 0);
oled.print("Encode:");
oled.println(valenc);
int etcrpmX = (OLED_WIDTH - (etcrpm.length() * 12)) / 2;
int valrpmX = (OLED_WIDTH - (valrpm.length() * 24)) / 2;
oled.setCursor(etcrpmX, 18);
oled.println(etcrpm);
if (direction) {
oled.drawBitmap(8, 16, frecciaSx, 24, 16, WHITE); // Mostra la freccia sinistra
} else {
oled.drawBitmap(96, 16, frecciaDx, 24, 16, WHITE); // Mostra la freccia destra
}
oled.setCursor(valrpmX, 36);
oled.setTextSize(4);
oled.println(rpm);
oled.display();
} |