Modificato come indicato da maubarzi ma purtroppo il comportamento non cambia assolutamente.
A livello di seriale vedo il refresh continuo dell'ultimo valore ma non interagisce ne display ne pulsanti.
Dovrei provare a sostituire a parte dei pulsanti su I2C con pulsanti collegati ai pin digitali ma quando avevo fatto la prova collegando la tastiera dello shield configurata sulla porta a0 (essendo una tastiera che funziona a partitori di tensione) si bloccava comunque.
Questo progetto non vedrà mail la luce temo! ![:confused: :confused:](https://emoji.discourse-cdn.com/twitter/confused.png?v=12)
#include <Wire.h>
#include <TimerOne.h>
#include <LiquidCrystal_I2C.h>
#include "Arduino.h"
#include "PCF8574.h"
// Set i2c address
PCF8574 pcf8574(0x3C);
// buttons code
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
// directions
#define FORWARD HIGH
#define BACKWARD LOW
// debounce time (milliseconds)
#define DEBOUNCE_TIME 200
// PINs for Pololu controller
#define PIN_STEP 2
#define PIN_DIR 3
// lookup table speed - ticks (interrupts)
//const int speed_ticks[] = {-1, 600, 300, 200, 150, 120, 100, 86, 75, 67, 60, 55, 50, 46, 43};
//const int speed_ticks[] = {-1, 300, 150, 100, 75, 60, 50, 43, 37, 33, 30, 27, 25, 23, 10};
const int speed_ticks[] = {-1, 100, 90, 80, 70, 60, 50, 40, 35, 30, 25, 20, 15, 10, 8};//questa è l'array migliore per la mia situazione
// global variables
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
int actual_speed;
int actual_direction;
int actual_speed_old = -1000;
int actual_direction_old = -2;
int ticks;
int tick_count;
int button;
boolean debounce;
int previous_time;
// custom LCD square symbol for progress bar
byte square_symbol[8] = {
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
};
// string constants
char forward_arrow[] = "-->";
char backward_arrow[] = "<--";
void setup() {
for(int i=0;i<8;i++) {
pcf8574.pinMode(i, INPUT);
}
pcf8574.begin();
lcd.begin(16,2);
lcd.setCursor(0,0);
lcd.backlight();
Serial.begin(9600);
//Il Timer1 viene programmato per generare un interrupt ogni 0.1 msec, quindi 10 interrupt ogni msec
//Timer1.initialize(20); 1 step / 2ms cioè (per un motore da 200 passi / giro) un giro ogni 0,4 secondi = 150 giri / min
Timer1.initialize(100);
Timer1.attachInterrupt(timerIsr);
// init LCD and custom symbol
//lcd.init();
//lcd.begin(16, 2);
//lcd.setCursor(0,0);
//lcd.createChar(0, square_symbol);
// pins direction
pinMode(PIN_STEP, OUTPUT);
pinMode(PIN_DIR, OUTPUT);
// initial values
actual_speed = 0;
actual_direction = FORWARD;
tick_count = 0;
ticks = -1;
debounce = false;
digitalWrite(PIN_DIR, actual_direction);
updateLCD();
}
void loop() {
// check if debounce active
if(debounce) {
button = btnNONE;
if(millis() > previous_time + DEBOUNCE_TIME) debounce = false;
} else button = read_buttons();
// if a button is pressed, start debounce time
if(button != btnNONE) {
previous_time = millis();
debounce = true;
}
// check which button was pressed
switch(button) {
case btnUP:
increase_speed();
break;
case btnDOWN:
decrease_speed();
break;
case btnLEFT:
change_direction(BACKWARD);
break;
case btnRIGHT:
change_direction(FORWARD);
break;
case btnSELECT:
emergency_stop();
break;
}
// finally update the LCD
updateLCD();
}
// increase speed if it's below the max (70)
void increase_speed() {
if(actual_speed < 70) {
actual_speed += 5;
tick_count = 0;
ticks = speed_ticks[actual_speed / 5];
}
}
// decrease speed if it's above the min (0)
void decrease_speed() {
if(actual_speed > 0) {
actual_speed -= 5;
tick_count = 0;
ticks = speed_ticks[actual_speed / 5];
}
}
// change direction if needed
void change_direction(int new_direction) {
if(actual_direction != new_direction) {
actual_direction = new_direction;
digitalWrite(PIN_DIR, actual_direction);
}
}
// emergency stop: speed 0
void emergency_stop() {
actual_speed = 60;
tick_count = 0;
ticks = speed_ticks[actual_speed / 5];
}
void updateLCD() {
if(actual_speed_old !=actual_speed || actual_direction_old != actual_direction)
{
// print first line:
// Speed: % --> (or <--)
lcd.setCursor(0,0);
lcd.print("Speed: ");
lcd.print(actual_speed);
lcd.print("% ");
actual_speed_old = actual_speed;
actual_direction_old = actual_direction;
}
Serial.print("mia var:");
Serial.println(actual_speed);
lcd.setCursor(13,0);
if(actual_direction == FORWARD) lcd.print(forward_arrow);
else lcd.print(backward_arrow);
// print second line:
// progress bar [##### ]
// 15 speed steps: 0 - 5 - 10 - ... - 70
lcd.setCursor(0,1);
lcd.print("[");
for(int i = 1; i <= 14; i++) {
if(actual_speed > (5 * i) - 1) lcd.write(byte(0));
else lcd.print(" ");
}
lcd.print("]");
}
// timer1 interrupt function
void timerIsr() {
if(actual_speed == 0) return;
tick_count++;
if(tick_count == ticks) {
// make a step
digitalWrite(PIN_STEP, HIGH);
digitalWrite(PIN_STEP, LOW);
tick_count = 0;
}
}
// read buttons connected to a single analog pin
int read_buttons() {
PCF8574::DigitalInput val = pcf8574.digitalReadAll();
if (val.p0==HIGH) return btnNONE;
if (val.p1==HIGH) return btnRIGHT;
if (val.p2==HIGH) return btnUP;
if (val.p3==HIGH) return btnDOWN;
if (val.p4==HIGH) return btnLEFT;
if (val.p5==HIGH) return btnSELECT;
delay (50);
}