Linearizzare rotazione motore DC

Ciao a tutti. A titolo sperimentale, ho realizzato un circuito per l'azionamento di un piccolo motore DC con riduzione, tramite un telecomando a infrarossi e due pulsanti utilizzando l'integrato L293D. Finchè tengo premuti i pulsanti, il motore gira sia a destra che a sinistra in maniera fluida. Con il telecomando infrarossi invece la rotazione procede a scatti. C'è un modo per ottenere un andamento più fluido oppure dipende dal funzionamento a impulsi del telecomando?

Dipende sicuramente dalla parte software della lettura del telecomando infrarossi, ma senza vedere il codice è difficile suggerire qualcosa per risolvere

Lo sketch è incompleto, oltre che formattato malissimo...

Premi CTRL+ T sull'IDE per sistemare la formattazione e poi posta lo sketch completo, altrimenti è difficile capire cosa fa veramente.

Hai ragione, scusa provvedo subito.



#include <Wire.h>
#include "U8glib.h"
#include <OneButton.h>
#include <EEPROM.h>
#include <IRremote.h>  //versione libreria 3.5.0
#include <i2cdetect.h>
#include <Arduino.h>
#include <U8x8lib.h>
#include "RTClib.h"
RTC_DS3231 rtc;

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif

U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/U8X8_PIN_NONE);
//U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/U8X8_PIN_NONE);
//Celle utilizzate per memorizzare ore, minuti e l'ingresso
#define cellaLed 0
#define cellaore 1
#define cellaminuti 2

//Definizione dei pin pulsanti volume più e meno
//e dei led corrispondenti
#define led_up 15
#define led_down 3
#define puls_volume_up 17
#define puls_volume_down 16

//const int RECV_PIN = 9;

#define IR_RECEIVE_PIN 9  //pin dove è collegato il ricevitore IR

#define buttonset1 0  // Button B1 is connected to Arduino pin 0
#define buttonset2 1  // Button B2 is connected to Arduino pin 1

OneButton button1(2, false);  //false = pulldown resistenza da 10k verso massa
OneButton button2(7, false);  //true = pullup resistenza 10k verso positivo
int buttonUp = 6;
int buttonDown = 5;
//int led = 1;
//Led ingressi
const byte led1 = 13;
const byte led2 = 12;
const byte led3 = 11;
const byte led4 = 10;
byte ledIngressi = 0;
int ledOnOff = 0;
int ledMute = 0;

static void click1();
static void click2();
static void cancMem(void *offButton1);

int valore_up = 0;
int valore_down = 0;

int secondi = 0;

//variabili globali per calcolare i tempi di funzionamento
unsigned long tempoAvvio;
unsigned long tempoAcceso;
unsigned long tempoArresto;
unsigned long tempoTotale;
uint8_t min = 0;
uint16_t ore = 0;
//********** aggiunte nuovo orologio **********************
//char Time[] = "  :  :  ";
char Time[] = "  :  ";  //:  ";
char Calendar[] = "  /  /20  ";
char temperature[] = " 00.00";
char temperature_msb;
byte i, second, minute, hour, day, date, month, year, temperature_lsb;

void display_day() {
  switch (day) {
    case 1: draw_text(1, 0, "DOM"); break;
    case 2: draw_text(1, 0, "LUN"); break;
    case 3: draw_text(1, 0, "MAR"); break;
    case 4: draw_text(1, 0, "MER"); break;
    case 5: draw_text(1, 0, "GIO"); break;
    case 6: draw_text(1, 0, "VEN"); break;
    default: draw_text(1, 0, "SAB");
  }
}

void DS3231_display() {
  // Conversione da BCD a decimale
  second = (second >> 4) * 10 + (second & 0x0F);
  minute = (minute >> 4) * 10 + (minute & 0x0F);
  hour = (hour >> 4) * 10 + (hour & 0x0F);
  date = (date >> 4) * 10 + (date & 0x0F);
  month = (month >> 4) * 10 + (month & 0x0F);
  year = (year >> 4) * 10 + (year & 0x0F);
  // Fne conversione

  Time[7] = second % 10 + 48;
  Time[6] = second / 10 + 48;
  Time[4] = minute % 10 + 48;
  Time[3] = minute / 10 + 48;
  Time[1] = hour % 10 + 48;
  Time[0] = hour / 10 + 48;
  Calendar[9] = year % 10 + 48;
  Calendar[8] = year / 10 + 48;
  Calendar[4] = month % 10 + 48;
  Calendar[3] = month / 10 + 48;
  Calendar[1] = date % 10 + 48;
  Calendar[0] = date / 10 + 48;
  if (temperature_msb < 0) {
    temperature_msb = abs(temperature_msb);
    temperature[0] = '-';
  } else
    temperature[0] = ' ';
  temperature_lsb >>= 6;
  temperature[2] = temperature_msb % 10 + 48;
  temperature[1] = temperature_msb / 10 + 48;
  if (temperature_lsb == 0 || temperature_lsb == 2) {
    temperature[5] = '0';
    if (temperature_lsb == 0) temperature[4] = '0';
    else temperature[4] = '5';
  }
  if (temperature_lsb == 1 || temperature_lsb == 3) {
    temperature[5] = '5';
    if (temperature_lsb == 1) temperature[4] = '2';
    else temperature[4] = '7';
  }
}

void DS3231_display_notemp() {
  // Convert BCD to decimal
  second = (second >> 4) * 10 + (second & 0x0F);
  minute = (minute >> 4) * 10 + (minute & 0x0F);
  hour = (hour >> 4) * 10 + (hour & 0x0F);
  date = (date >> 4) * 10 + (date & 0x0F);
  month = (month >> 4) * 10 + (month & 0x0F);
  year = (year >> 4) * 10 + (year & 0x0F);
  // End conversion

  Time[7] = second % 10 + 48;
  Time[6] = second / 10 + 48;
  Time[4] = minute % 10 + 48;
  Time[3] = minute / 10 + 48;
  Time[1] = hour % 10 + 48;
  Time[0] = hour / 10 + 48;
  Calendar[9] = year % 10 + 48;
  Calendar[8] = year / 10 + 48;
  Calendar[4] = month % 10 + 48;
  Calendar[3] = month / 10 + 48;
  Calendar[1] = date % 10 + 48;
  Calendar[0] = date / 10 + 48;
  if (temperature_msb < 0) {
    temperature_msb = abs(temperature_msb);
    temperature[0] = '-';
  } else
    temperature[0] = ' ';
  temperature_lsb >>= 6;
  temperature[2] = temperature_msb % 10 + 48;
  temperature[1] = temperature_msb / 10 + 48;
  if (temperature_lsb == 0 || temperature_lsb == 2) {
    temperature[5] = '0';
    if (temperature_lsb == 0) temperature[4] = '0';
    else temperature[4] = '5';
  }
  if (temperature_lsb == 1 || temperature_lsb == 3) {
    temperature[5] = '5';
    if (temperature_lsb == 1) temperature[4] = '2';
    else temperature[4] = '7';
  }

  draw_text1(3, 2, Time);  // Display the time
}

void blink_parameter() {
  byte j = 0;
  while (j < 10 && digitalRead(buttonset1) && digitalRead(buttonset2)) {
    j++;
    delay(25);
  }
}
byte edit(byte x_pos, byte y_pos, byte parameter) {
  char text[3];
  sprintf(text, "%02u", parameter);
  while (!digitalRead(buttonset1))
    ;  // Wait until button B1 released
  while (true) {
    while (!digitalRead(buttonset2)) {  // If button B2 is pressed
      parameter++;
      if (i == 0 && parameter > 31)  // If date > 31 ==> date = 1
        parameter = 1;
      if (i == 1 && parameter > 12)  // If month > 12 ==> month = 1
        parameter = 1;
      if (i == 2 && parameter > 99)  // If year > 99 ==> year = 0
        parameter = 0;
      if (i == 3 && parameter > 23)  // If hours > 23 ==> hours = 0
        parameter = 0;
      if (i == 4 && parameter > 59)  // If minutes > 59 ==> minutes = 0
        parameter = 0;
      sprintf(text, "%02u", parameter);
      draw_text(x_pos, y_pos, text);
      delay(200);  // Wait 200ms
    }

    draw_text(x_pos, y_pos, "  ");
    blink_parameter();
    draw_text(x_pos, y_pos, text);
    blink_parameter();
    if (!digitalRead(buttonset1)) {  // If button B1 is pressed
      i++;                           // Increament 'i' for the next parameter
      return parameter;              // Return parameter value and exit
    }
  }
}
byte edit1(byte x_pos, byte y_pos, byte parameter) {
  char text[3];
  sprintf(text, "%02u", parameter);
  while (!digitalRead(buttonset1))
    ;  // Wait until button B1 released
  while (true) {
    while (!digitalRead(buttonset2)) {  // If button B2 is pressed
      parameter++;
      //if (i == 0 && parameter > 31)  // If date > 31 ==> date = 1
      //  parameter = 1;
      //if (i == 1 && parameter > 12)  // If month > 12 ==> month = 1
      //  parameter = 1;
      //if (i == 2 && parameter > 99)  // If year > 99 ==> year = 0
      //  parameter = 0;
      if (i == 0 && parameter > 23)  // If hours > 23 ==> hours = 0
        parameter = 0;
      if (i == 1 && parameter > 59)  // If minutes > 59 ==> minutes = 0
        parameter = 0;
      sprintf(text, "%02u", parameter);
      draw_text1(x_pos, y_pos, text);
      delay(200);  // Wait 200ms
    }

    draw_text1(x_pos, y_pos, "   ");
    blink_parameter();
    draw_text1(x_pos, y_pos, text);
    blink_parameter();
    if (!digitalRead(buttonset1)) {  // If button B1 is pressed
      i++;                           // Increament 'i' for the next parameter
      return parameter;              // Return parameter value and exit
    }
  }
}


void draw_text(byte x_pos, byte y_pos, char *text) {
  //void draw_text(byte x_pos, byte y_pos, char *text, byte text_size) {
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.setCursor(x_pos, y_pos);

  u8x8.print(text);
  u8x8.display();
}

void draw_text1(byte x_pos, byte y_pos, char *text) {
  u8x8.setFont(u8x8_font_courB18_2x3_n);
  u8x8.setCursor(x_pos, y_pos);

  u8x8.print(text);
  u8x8.display();
}

void setup() {

  pinMode(buttonset1, INPUT_PULLUP);
  pinMode(buttonset2, INPUT_PULLUP);
  delay(1000);

  // Serial.begin(9600);  //Inizializza il monitor seriale
  rtc.begin();

  Wire.begin();
  IrReceiver.begin(IR_RECEIVE_PIN);
  //IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);//lampeggia il led sul pin 13
  pinMode(16, INPUT);  // volume +
  pinMode(17, INPUT);  // volume -
  pinMode(8, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(15, OUTPUT);

  button1.setPressMs(3000);
  button1.setDebounceMs(20);
  button1.attachClick(click1);
  button1.attachLongPressStop(cancMem, &button1);

  button2.setDebounceMs(20);
  button2.attachClick(click2);

  //Doppio click sul pulsante mute
  //apre schermata del tempo totale di utilizzo
  button2.attachDoubleClick(
    []() {
      if (ledOnOff == HIGH) {
        //inizio codice schermata tempo trascorso
        u8x8.clearDisplay();
        tempoTrascorsoMom();
        delay(5000);
        //DateTime now = rtc.now();
        //printDateTimeMom(now);

        u8x8.clearDisplay();

        int ledMute = digitalRead(8);
        if (ledMute == HIGH) {

          u8x8.setFont(u8x8_font_8x13_1x2_r);
          u8x8.draw2x2String(2, 4, " MUTE  ");

        } else if (ledMute == LOW) {

          StampaIngressi();
        }
      }
    });
  //fine codice schermata tempo trascorso

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(buttonUp, INPUT);
  pinMode(buttonDown, INPUT);
  digitalWrite(buttonUp, HIGH);    //abilitazione resistenze interne di pullup
  digitalWrite(buttonDown, HIGH);  //Pulsanti avanti e indietro canali ingresso

  u8x8.begin();
  u8x8.setPowerSave(0);
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.clearDisplay();
  u8x8.setCursor(0, 4);
  u8x8.print(" <<<   ON   >>>  ");
  delay(2000);

  u8x8.clearDisplay();

  ledIngressi = EEPROM.read(cellaLed);
  EEPROM.get(0, ledIngressi);
  EEPROM.get(1, min);
  EEPROM.get(2, ore);
  tempoTotale = ore * 3600UL + min * 60UL;
}
unsigned long t1, dt;  //variabili tempo accensione mute
bool RUN = false;      //quando premo MUTE diventa true
int menu = 0;


void loop() {
  dt = millis() - t1;
  if ((dt >= 1800000) && RUN) {  //Spegne dopo un certo tempo che il Mute è acceso
                                 // if ((dt >= 60000) && RUN) {
    click1();
    RUN = false;
  }
  button1.tick();
  button2.tick();
  DateTime now = rtc.now();
  ledOnOff = digitalRead(4);

  //DateTime now = rtc.now();
  standby();

  //Alza volume pulsante pannello

  valore_up = digitalRead(puls_volume_up);

  if ((valore_up == HIGH) && (ledOnOff == HIGH)) {
    digitalWrite(led_up, HIGH);
    digitalWrite(8, LOW);  //Spegne mute
    StampaIngressi();
    //digitalWrite(led_up, LOW);
  } else {
    standby();
    digitalWrite(led_up, LOW);
  }

  //Abbassa volume pulsante pannello
  valore_down = digitalRead(puls_volume_down);

  //int vol_down = digitalRead(16);
  if ((valore_down == HIGH) && (ledOnOff == HIGH)) {
    digitalWrite(led_down, HIGH);
    digitalWrite(8, LOW);  //Spegne il mute
    StampaIngressi();
  } else {
    standby();
    digitalWrite(led_down, LOW);
  }

  //Accende in sequenza, avanti e indietro
  // i 4 led degli ingressi
  //if ((valore_up == HIGH) && (ledOnOff == HIGH)) {
  if ((digitalRead(buttonUp) == 0) && (ledOnOff == HIGH)) {
    digitalWrite(8, LOW);
    ledIngressi++;
    delay(250);
    StampaIngressi();
    //delay(250);
    if (ledIngressi > 4) {
      ledIngressi = 1;
      StampaIngressi();
    } else {
      standby();
    }
  }
  //if (digitalRead(buttonDown) == 0) {
  if ((digitalRead(buttonDown) == 0) && (ledOnOff == HIGH)) {
    digitalWrite(8, LOW);
    ledIngressi--;
    delay(250);
    StampaIngressi();
    //delay(250);
    if (ledIngressi < 1) {
      ledIngressi = 4;
      StampaIngressi();
    } else {
      standby();
    }
  }
  if (ledIngressi == 1) {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
  }
  if (ledIngressi == 2) {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
  }
  if (ledIngressi == 3) {
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, LOW);
  }
  if (ledIngressi == 4) {
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, HIGH);
  }



  //************ Telecomando infrarossi ************
  //if (irrecv.decode(&results)) {  //Decodifica i dati ricevuti e salva i dati in results
  // IrReceiver.resume();

  // if (results.bits > 0) {
  //Serial.println(F("======== COMANDO RICEVUTO ======="));
  //Serial.print("Valore: 0x");
  //Serial.println(results.value, HEX);

  if (IrReceiver.decode()) {
    unsigned long keycode = IrReceiver.decodedIRData.command;
    Serial.print("Valore: ");
    Serial.println(keycode);

    switch (keycode) {
      //***********************
      case 22:  //visualizzazione orario
        /*
        Questa if impedisce di ricevere comandi ripetuti
        if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
        IrReceiver.resume();
        return;
        }
         */

        if (ledOnOff == LOW) {
          //  u8x8.clearDisplay();
          standby();
        } else {
          u8x8.clearDisplay();
          printDateTimeMom(now);
          //  tempoTrascorsoMom();

          delay(5000);
          u8x8.clearDisplay();
          StampaIngressi();
        }
        break;
        //irrecv.resume();
        IrReceiver.resume();
        //case 0xF9E21D:  //Tempo trascorso
      case 71:  //visualizza il tempo trascorso
        /*
        Questa if impedisce di ricevere comandi ripetuti
        if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
        IrReceiver.resume();
        return;
        }
         */
        digitalWrite(8, LOW);
        // u8x8.clearDisplay();
        if (ledOnOff == LOW) {
          // u8x8.clearDisplay();
          standby();
        } else {
          u8x8.clearDisplay();

          tempoTrascorsoMom();
          delay(5000);
          u8x8.clearDisplay();
          StampaIngressi();
        }
        break;
        //irrecv.resume();
        IrReceiver.resume();

      //Alza il volume (simbolo altoparlante)
      case 255:

        if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
          IrReceiver.resume();
          return;
        }
        volumeUp();

        /*
        if (ledOnOff == HIGH) {
          digitalWrite(led_up, HIGH);
          digitalWrite(8, LOW);  //Spegne il mute
          StampaIngressi();
        } else {
          standby();
          digitalWrite(led_up, LOW);
        }
        */
        break;
        IrReceiver.resume();
        //alza volume (freccia sù)
      case 67:
        /*
      if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
          IrReceiver.resume();
          return;
        }
        */
        volumeUp();
        /*
        if (ledOnOff == HIGH) {
          digitalWrite(led_up, HIGH);
          digitalWrite(8, LOW);  //Spegne il mute
          StampaIngressi();
        } else {
          standby();
          digitalWrite(led_up, LOW);
        }
        */
        break;
        IrReceiver.resume();

        //Abbassa il volume (simbolo altoparlante)
      case 93:
        if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
          IrReceiver.resume();
          return;
        }

        volumeDown();


        // if (ledOnOff == HIGH) {
        // digitalWrite(led_down, HIGH);
        // digitalWrite(8, LOW);  //Spegne il mute
        //StampaIngressi();

        //} else {
        //  standby();
        // digitalWrite(led_down, LOW);
        //}

        break;
        //irrecv.resume();
        IrReceiver.resume();

        //Abbassa il volume (freccia giù)
      case 10:

        /*
         if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
          IrReceiver.resume();
          return;
        }
        */
        volumeDown();


        /*
        if (ledOnOff == HIGH) {
          digitalWrite(led_down, HIGH);
          digitalWrite(8, LOW);  //Spegne il mute
          StampaIngressi();
        } else {
          standby();
          digitalWrite(led_down, LOW);
        }
          */
        break;
        //irrecv.resume();
        IrReceiver.resume();

        // Tasto Mute
      case 138:
        //Questa if impedisce di ricevere comandi ripetuti
        if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
          IrReceiver.resume();
          return;
        }
        // digitalWrite(8, !digitalRead(8));
        click2();

        break;
        IrReceiver.resume();

      //irrecv.resume();

      //Tasto On / Off
      case 87:
        // Questa if impedisce di ricevere comandi ripetuti
        if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
          IrReceiver.resume();
          return;
        }
        click1();
        break;
        IrReceiver.resume();

        //****** abbassa il volume quando acceso *******
      case 79:
        //int ledOnOff = digitalRead(4);
        if (ledOnOff == LOW) {
          standby();
        } else {
          AbbassaVolumeMom();
        }

        break;
        IrReceiver.resume();
      //******* fine abbassa il volume quando acceso ******

      //Pulsante Canale Indietro
      //case 6:
      case 14:
        if (ledOnOff == LOW) {
          // u8x8.clearDisplay();
          standby();
        } else {
          digitalWrite(8, LOW);  //Spegne il led Mute
          ledIngressi--;

          if (ledIngressi < 1) {
            ledIngressi = 4;
          }
          delay(250);

          StampaIngressi();
        }
        break;
        IrReceiver.resume();

      //Pulsante Canale Avanti
      //case 14:
      case 6:
        if (ledOnOff == LOW) {
          // u8x8.clearDisplay();
          standby();
        } else {

          digitalWrite(8, LOW);  //Spegne il led Mute
          ledIngressi++;
          if (ledIngressi > 4) {
            ledIngressi = 1;
          }
          delay(250);

          StampaIngressi();
        }
        break;
        IrReceiver.resume();

        // irrecv.resume();
      default:
        //case UNKNOWN:
        Serial.println(F("Comando sconosciuto"));

        IrReceiver.resume();

        break;
    }

    IrReceiver.resume();

    //irrecv.resume();
  }
  //************************** fine telecomando infrarossi ************************
}

void valoreVolume() {

  int valPot = analogRead(A0);
  int percVolume = map(valPot, 0, 1023, 0, 99);
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.draw2x2String(0, 0, "<");
  u8x8.draw2x2String(14, 0, ">");

  //Aggiunge lo zero prima della cifra
  //quando il valore è minore di 10
  if (percVolume < 10) {
    u8x8.draw2x2String(6, 0, "0");
    u8x8.draw2x2String(8, 0, String(percVolume).c_str());

  } else {

    u8x8.draw2x2String(6, 0, String(percVolume).c_str());
  }
}
void standby() {
  //DateTime now = rtc.now();
  int valPot = analogRead(A0);
  int percVolume = map(valPot, 0, 1023, 0, 99);
  int ledOnOff = digitalRead(4);
  if (ledOnOff == LOW) {
    //printDateTime(now);
    u8x8.setFont(u8x8_font_8x13_1x2_r);
    u8x8.setCursor(0, 0);
    u8x8.print("Audio Dimensions");
    u8x8.setFont(u8x8_font_open_iconic_embedded_2x2);
    //u8x8.setFont(u8x8_font_open_iconic_embedded_4x4);
    //Ux8.setFont(u8x8_font_open_iconic_embedded_1x1);
    u8x8.drawGlyph(7, 6, 'N');
    digitalWrite(8, LOW);
    //********************
    u8x8.setFont(u8x8_font_8x13_1x2_r);
    if (!digitalRead(buttonset1)) {  // If button B1 is pressed
      i = 0;
      while (!digitalRead(buttonset1))
        ;

      hour = edit1(3, 2, hour);      // Edit hours
      minute = edit1(9, 2, minute);  // Edit minutes

      // Convert decimal to BCD
      minute = ((minute / 10) << 4) + (minute % 10);
      hour = ((hour / 10) << 4) + (hour % 10);
      date = ((date / 10) << 4) + (date % 10);
      month = ((month / 10) << 4) + (month % 10);
      year = ((year / 10) << 4) + (year % 10);
      // End conversion

      // Write data to DS3231 RTC
      Wire.beginTransmission(0x68);  // Start I2C protocol with DS3231 address
      Wire.write(0);                 // Send register address
      Wire.write(0);                 // Reset sesonds and start oscillator
      Wire.write(minute);            // Write minute
      Wire.write(hour);              // Write hour
      Wire.write(day);               // Write day
      Wire.write(date);              // Write date
      Wire.write(month);             // Write month
      Wire.write(year);              // Write year
      Wire.endTransmission();        // Stop transmission and release the I2C bus
      delay(200);                    // Wait 200ms
    }

    Wire.beginTransmission(0x68);   // Start I2C protocol with DS3231 address
    Wire.write(0);                  // Send register address
    Wire.endTransmission(false);    // I2C restart
    Wire.requestFrom(0x68, 7);      // Request 7 bytes from DS3231 and release I2C bus at end of reading
    second = Wire.read();           // Read seconds from register 0
    minute = Wire.read();           // Read minuts from register 1
    hour = Wire.read();             // Read hour from register 2
    day = Wire.read();              // Read day from register 3
    date = Wire.read();             // Read date from register 4
    month = Wire.read();            // Read month from register 5
    year = Wire.read();             // Read year from register 6
    Wire.beginTransmission(0x68);   // Start I2C protocol with DS3231 address
    Wire.write(0x11);               // Send register address
    Wire.endTransmission(false);    // I2C restart
    Wire.requestFrom(0x68, 2);      // Request 2 bytes from DS3231 and release I2C bus at end of reading
    temperature_msb = Wire.read();  // Read temperature MSB
    temperature_lsb = Wire.read();
    // Read temperature LSB
    //if(ledOnOff == LOW){
    //display_day();  // Stampa giorno settimana
    //DS3231_display();                            // Stampa ora e data (time & calendar) e temperatura
    DS3231_display_notemp();  //Chiama la funzione senza mostrare la temperatura
    delay(50);
  }

  if (ledOnOff == HIGH) {
    valoreVolume();
  }
}
void tempoTrascorsoMom() {
  //legge dalla memoria il tempo totale di funzionamento
  EEPROM.get(1, min);
  EEPROM.get(2, ore);
  //e lo mostra sul display
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.setCursor(0, 0);
  u8x8.print("Audio Dimensions");
  u8x8.setCursor(1, 2);
  u8x8.print("UTILIZZATO PER");
  u8x8.setCursor(2, 4);
  u8x8.print("ORE");
  u8x8.setCursor(8, 4);
  u8x8.print("MINUTI");
  u8x8.setCursor(3, 6);
  u8x8.print(ore);
  u8x8.setCursor(10, 6);
  u8x8.print(min);
}
//PULSANTE ACCENSIONE ON/OFF
static void click1() {
  //int ledMute = digitalRead(8);
  digitalWrite(8, LOW);
  u8x8.display();
  u8x8.clearDisplay();
  //int ledOff = 0;
  int ledOnOff = 0;
  digitalWrite(4, !digitalRead(4));

  //ledOff = digitalRead(4);
  ledOnOff = digitalRead(4);
  //if (ledOff == LOW) {
  if (ledOnOff == LOW) {
    //tempoArresto = millis() / 1000UL;
    tempoArresto = millis();
    //tempoAcceso = tempoArresto - tempoAvvio;  // se tempi già in sec non serve dividere / 1000UL
    tempoAcceso = (tempoArresto - tempoAvvio) / 1000UL;
    //funzione accumulo
    tempoTotale = tempoTotale + tempoAcceso;
    // calcolo tempo totale in hh:mm
    ore = tempoTotale / 3600UL;  // UL suffisso per forzare costante a unsigned long
    min = (tempoTotale - (ore * 3600UL)) / 60UL;
    //Ancora più semplice:
    //min = (tempoTotale % 3600UL) / 60UL;//modulo 60
    //min = tempoTotale / 60UL;
    /*
    Serial.print("Avvio:");
    Serial.print(tempoAvvio);
    Serial.println(" sec");
    Serial.print("Arresto:");
    Serial.print(tempoArresto);
    Serial.println(" sec");
    Serial.print("Intervallo:");
    Serial.print(tempoAcceso);
    Serial.println(" sec");
    Serial.print("Totale:");
    Serial.print(ore);
    Serial.print(":");
    Serial.println(min);
    */
    //allo spegnimento aggiorna i dati in memoria
    EEPROM.update(0, ledIngressi);
    //EEPROM.update(1, ore);
    //EEPROM.update(2, minuti);
    EEPROM.put(1, min);
    EEPROM.put(2, ore);
    delay(200);

    //Funione spegnimento
    int valPot = analogRead(A0);
    //int percVolume = map(valPot, 0, 1023, 0, 98);
    int percVolume = map(valPot, 0, 1023, 0, 100);
    valoreVolume();
    u8x8.setFont(u8x8_font_8x13_1x2_r);
    u8x8.setCursor(2, 4);
    digitalWrite(8, HIGH);
    u8x8.print("SPEGNIMENTO");
    u8x8.setCursor(3, 6);
    u8x8.print("IN  CORSO");
    //Il potenziometro ruota finché il valore non scende a zero
    while (percVolume >= 1) {
      digitalWrite(led_down, HIGH);
      valPot = analogRead(A0);
      //percVolume = map(valPot, 0, 1023, 0, 98);
      percVolume = map(valPot, 0, 1023, 0, 100);
      valoreVolume();
    }
    digitalWrite(led_down, LOW);
    digitalWrite(8, LOW);
    u8x8.display();
    u8x8.clearDisplay();
    u8x8.setFont(u8x8_font_8x13_1x2_r);
    u8x8.setCursor(0, 4);
    u8x8.print(" <<<  OFF  >>> ");
    delay(2000);
    u8x8.clearDisplay();
  }
  //Fine funzione spegnimento

  //if (ledOff == HIGH) {
  if (ledOnOff == HIGH) {
    //tempoAvvio = (millis() / 1000);
    tempoAvvio = millis();
    digitalWrite(8, HIGH);
    u8x8.setFont(u8x8_font_8x13_1x2_r);

    AbbassaVolume();
    u8x8.clearDisplay();

    //preriscaldamento lampeggiante
    /*
    int indice = 0;
    while (indice <= 15) {  //era 15
      digitalWrite(8, HIGH);
      u8x8.setCursor(7, 6);
      u8x8.print(indice);
      u8x8.setCursor(0, 0);
      u8x8.print("Audio Dimensions");
      u8x8.setCursor(0, 4);
      //u8x8.print("< PRERISCALDO >");
      u8x8.print("< ATTENDERE... >");
      delay(1000);
      u8x8.setCursor(0, 4);
      u8x8.print("                ");
      delay(1000);
      indice++;
      u8x8.setCursor(7, 6);
      u8x8.print(indice);    
    }
    */
    //fine preriscaldamento

    int indice = 30;
    while (indice >= 1) {  //era 15
      digitalWrite(8, HIGH);

      u8x8.setCursor(0, 0);
      u8x8.print("Audio Dimensions");
      u8x8.setCursor(0, 4);
      //u8x8.print("< PRERISCALDO >");
      //u8x8.print("< ATTENDERE... >");
      // u8x8.print("...ATTENDERE...");
      // u8x8.print("-- ATTENDERE --");
      u8x8.print("<< ATTENDERE >>");
      //delay(1000);
      //indice--;

      //aggiunge lo zero quando il valore è inferiore a 10
      if (indice < 10) {
        u8x8.drawString(7, 6, "0");
        u8x8.drawString(8, 6, String(indice).c_str());
      } else {
        u8x8.drawString(7, 6, String(indice).c_str());
      }
      delay(1000);
      indice--;
    }
    u8x8.clearDisplay();
    AlzaVolume();
    StampaIngressi();
    digitalWrite(8, LOW);
    //EEPROM.get(1, min);
    // EEPROM.get(2, ore);
    //tempoTotale = ore * 3600UL + min * 60UL;
  }
}
// PULSANTE MUTE
static void click2() {
  t1 = millis();
  RUN = true;

  ledMute = digitalRead(8);

  if (ledOnOff == LOW) {
    //u8x8.clearDisplay();
    standby();
  } else {

    digitalWrite(8, !digitalRead(8));
    int ledMute = digitalRead(8);

    if (ledMute == HIGH) {
      u8x8.setFont(u8x8_font_8x13_1x2_r);

      for (int i = 1; i < 4; i++) {
        u8x8.draw2x2String(2, 4, " MUTE  ");
        delay(1000);
        //u8x8.clearDisplay();
        u8x8.draw2x2String(2, 4, "              ");
        delay(250);
      }
      u8x8.setFont(u8x8_font_8x13_1x2_r);
      u8x8.drawString(0, 4, "SPEGNIMENTO TRA");
      u8x8.drawString(0, 6, "   30 MINUTI   ");
      delay(5000);
      u8x8.clearDisplay();
      u8x8.draw2x2String(2, 4, " MUTE  ");



    } else if (ledMute == LOW) {
      RUN = false;
      u8x8.setFont(u8x8_font_8x13_1x2_r);
      StampaIngressi();
    }
  }
}
static void cancMem(void *offButton1) {
  EEPROM.write(1, 0);
  EEPROM.write(2, 0);
  EEPROM.write(3, 0);
  delay(200);
  u8x8.clearDisplay();
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.setCursor(5, 1);
  u8x8.print("TEMPO");
  u8x8.setCursor(2, 3);
  u8x8.print("DI UTILIZZO");
  u8x8.setCursor(4, 5);
  u8x8.print("AZZERATO");
  delay(2000);
  u8x8.clearDisplay();
  //StampaIngressi();
}
void StampaIngressi() {

  u8x8.setFont(u8x8_font_8x13_1x2_r);

  switch (ledIngressi) {
    case 1:
      //u8x8.draw2x2String(3, 4, "PHONO  ");
      u8x8.draw2x2String(2, 4, " AUX2   ");
      break;
    case 2:
      //u8x8.draw2x2String(2, 4, "  CD    ");
      u8x8.draw2x2String(2, 4, " AUX1   ");
      break;
    case 3:
      //u8x8.draw2x2String(2, 4, " AUX1   ");
      u8x8.draw2x2String(2, 4, "  CD    ");
      break;
    case 4:
      //u8x8.draw2x2String(2, 4, " AUX2   ");
      u8x8.draw2x2String(3, 4, "PHONO  ");
      break;
    default:
      break;
  }
}
void printDateTimeMom(DateTime dt) {
  char daysOfTheWeek[7][12] = { "DOM", "LUN", "MAR", "MER", "GIO", "VEN", "SAB" };
  DateTime now = rtc.now();
  char dateBuffer[] = "DD/MM/YYYY";
  // char timeBuffer[] = "hh:mm:ss";
  char timeBuffer[] = "hh:mm";
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  //u8x8.setCursor(1, 0);
  //u8x8.print(daysOfTheWeek[now.dayOfTheWeek()]);
  //u8x8.setCursor(5, 0);
  //u8x8.print(dt.toString(dateBuffer));
  u8x8.setCursor(0, 0);
  u8x8.print("Audio Dimensions");
  u8x8.setCursor(5, 2);
  u8x8.print(dt.toString(timeBuffer));
  u8x8.drawString(2, 4, "TEMPERATURA");
  //int temperatura = rtc.getTemperature();
  float temperatura = rtc.getTemperature();
  u8x8.setCursor(4, 6);
  u8x8.print(temperatura);
  //u8x8.setCursor(2,5);
  //u8x8.print("°C");
  u8x8.drawString(10, 6, "'C");
}

void AbbassaVolume() {

  // u8x8.clearDisplay();

  //Abbassa il volume momentaneamente fino a 5
  int valPot = analogRead(A0);
  //int percVolume = map(valPot, 0, 1023, 0, 98);
  int percVolume = map(valPot, 0, 1023, 0, 100);
  valoreVolume();
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.setCursor(2, 5);
  digitalWrite(8, HIGH);

  //Il potenziometro ruota finché il valore non scende a zero
  while (percVolume >= 1) {
    digitalWrite(led_down, HIGH);
    // digitalWrite(8, HIGH);
    valPot = analogRead(A0);
    //percVolume = map(valPot, 0, 1023, 0, 98);
    percVolume = map(valPot, 0, 1023, 0, 100);
    valoreVolume();
  }
  digitalWrite(led_down, LOW);
  digitalWrite(8, LOW);
  // u8x8.display();
  // u8x8.clearDisplay();
}

void AbbassaVolumeMom() {

  // u8x8.clearDisplay();

  //Abbassa il volume momentaneamente fino a 5
  int valPot = analogRead(A0);
  //int percVolume = map(valPot, 0, 1023, 0, 98);
  int percVolume = map(valPot, 0, 1023, 0, 100);

  valoreVolume();
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.setCursor(2, 5);
  digitalWrite(8, HIGH);

  //Il potenziometro ruota finché il valore non scende a 5
  while (percVolume >= 6) {
    digitalWrite(led_down, HIGH);
    // digitalWrite(8, HIGH);
    valPot = analogRead(A0);
    //percVolume = map(valPot, 0, 1023, 0, 98);
    percVolume = map(valPot, 0, 1023, 0, 100);
    valoreVolume();
  }
  digitalWrite(led_down, LOW);
  digitalWrite(8, LOW);
  // u8x8.display();
  // u8x8.clearDisplay();
}

void AlzaVolume() {

  // u8x8.clearDisplay();

  //Abbassa il volume momentaneamente fino a 5
  int valPot = analogRead(A0);
  //int percVolume = map(valPot, 0, 1023, 0, 98);
  int percVolume = map(valPot, 0, 1023, 0, 100);
  valoreVolume();
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.setCursor(2, 5);
  digitalWrite(8, HIGH);

  //Il potenziometro ruota finché il valore non va a 5
  while (percVolume <= 4) {
    digitalWrite(led_up, HIGH);
    // digitalWrite(8, HIGH);
    valPot = analogRead(A0);
    //percVolume = map(valPot, 0, 1023, 0, 98);
    percVolume = map(valPot, 0, 1023, 0, 100);
    valoreVolume();
  }
  digitalWrite(led_up, LOW);
  digitalWrite(8, LOW);
  // u8x8.display();
  // u8x8.clearDisplay();
}

//funzione che ferma il potenziometro
//quando il valore arriva a zero

void volumeDown() {

  int valPot = analogRead(A0);
  //int percVolume = map(valPot, 0, 1023, 0, 98);
  int percVolume = map(valPot, 0, 1023, 0, 100);
  //se il valore è zero il motore si ferma
  if ((ledOnOff == HIGH) && (percVolume >= 1)) {
    digitalWrite(led_down, HIGH);
    //digitalWrite(8, LOW);  //Spegne il mute
    StampaIngressi();
  } else {
    standby();
    digitalWrite(led_down, LOW);
  }
  if (percVolume == 0) {
    digitalWrite(8, HIGH);
  }
}
void volumeUp() {
  int valPot = analogRead(A0);
  //
  int percVolume = map(valPot, 0, 1023, 0, 100);
  //se il valore supera 98 il motore si ferma
  if ((ledOnOff == HIGH) && (percVolume <= 98)) {
    digitalWrite(led_up, HIGH);
    /*
    if(percVolume >= 0 && percVolume < 20){
    digitalWrite(led_up, HIGH);
    delay(500);//240
    digitalWrite(led_up, LOW);  
    }
    if(percVolume >= 20 && percVolume < 30){
    digitalWrite(led_up, HIGH);
    delay(500);//70
    digitalWrite(led_up, LOW);  
    }
    if(percVolume >= 30 && percVolume < 50){
    digitalWrite(led_up, HIGH);
    delay(500);//40
    digitalWrite(led_up, LOW);  
    }
    if(percVolume >= 50 && percVolume < 70){
    digitalWrite(led_up, HIGH);
    delay(500);//25
    digitalWrite(led_up, LOW);  
    }
    if(percVolume >= 70 && percVolume < 99){
    digitalWrite(led_up, HIGH);
    delay(35);//20
    digitalWrite(led_up, LOW);  
    }
    */
    //digitalWrite(led_up, HIGH);
    /*     
     delay(50);
     digitalWrite(led_up, LOW); 
      delay(500);
    */
    digitalWrite(8, LOW);  //Spegne il mute
    StampaIngressi();
    //valoreVolume();
  } else {
    standby();
    digitalWrite(led_up, LOW);
  }
}

Esempio tratto dallo switch relativo al telecomando, togliendo il codice commentato:

case 67:
        volumeUp();
        break;
        IrReceiver.resume();

        //Abbassa il volume (simbolo altoparlante)
      case 93:

ed è così anche quello degli altri case.
IrReceiver.resume(), che non so bene cosa faccia, non verrà mai eseguito, perchè si trova dopo il break, che è un salto all'uscita dello switch().

Ciao, Ale.

E meno male.
Perchè la .resume() della libreria IRRemote deve essere richiamata solo una volta, alla fine dello switch(), ovvero dopo aver "processato" il tasto premuto.

@giordano58
Non capisco, hai dei delay() dentro la switch che risponde al telecomando, quindi rallenta tutto.
Inoltre "quale" tasto premi del telecomando per avere che i motori vanno a scatti?
Se ad esempio "alza volume", vedo che ad ogni pressione di alza volume fai eseguire molto codice, ovvio che il programma vada a scatti. Non hai un sistema multitask.
Poi leggi di seguito le indicazioni di @fabpolli

Il fatto che con il telecomando vada a scatti e premendo il pulsante no è perché nella gestione dei pulsanti imposti l'uscita led_up a LOW e finché non rilasci sta così per poi essere impostata a HIGH.
Nella gestione con telecomando nel metodo volumeUp() imposti l'uscita, attendi e poi reimposti in modo che il motore si fermi, poi fai altre cose nella StampaIngressi() che richiedono un certo tempo e riparti con il ciclo.
Dovresti uniformare i comportamenti in modo che venga subito messa l'uscita alla pressione e così resti finché non rilasci il tasto altrimenti procederà sempre a scatti

OK, grazie per le risposte. Purtroppo non sono molto esperto di programmazione, anzi direi per niente :wink:. Ora proverò a fare qualche modifica.

Potresti darmi qualche indicazione più precisa?

Scusal la domanda, il delay dentro lo switch non viene eseguito solo in presenza di un determinato codice? Comunque chiedo scusa a tutti, mi sono accorto ora di aver caricato il codice sbagliato. Domani caricherò quello corretto. Spero di non essermi imbarcato in un progetto troppo grande per me. :wink:

Si, ma quando hai posto la domanda...

... non hai specificato quale tasto del telecomando ti da quel problema. Nel caso specifico di quel tasto quel delay può dare problemi, Negli altri casi, bisogna vedere cosa fai, cosa rallenta (visto la quantità di codice) e come dice @fabpolli se hai codice che interferisce con i motori.

I
Questo è il codice corretto con cui sto lavorando.

I tasti del telecomando utilizati sono quelli dello switch case:
10 e 93 per la funzione volumeDown, 255 e 67 per volumeUp


#include <Wire.h>
#include "U8glib.h"
#include <OneButton.h>
#include <EEPROM.h>
#include <IRremote.h>  //versione libreria 3.5.0
#include <i2cdetect.h>
#include <Arduino.h>
#include <U8x8lib.h>
#include "RTClib.h"
RTC_DS3231 rtc;

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif

U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/U8X8_PIN_NONE);
//U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/U8X8_PIN_NONE);
//Celle utilizzate per memorizzare ore, minuti e l'ingresso
#define cellaLed 0
#define cellaore 1
#define cellaminuti 2

//Definizione dei pin pulsanti volume più e meno
//e dei led corrispondenti
#define led_up 15
#define led_down 3
#define puls_volume_up 17
#define puls_volume_down 16

//const int RECV_PIN = 9;

#define IR_RECEIVE_PIN 9  //pin dove è collegato il ricevitore IR

#define buttonset1 0  // Button B1 is connected to Arduino pin 0
#define buttonset2 1  // Button B2 is connected to Arduino pin 1

OneButton button1(2, false);  //false = pulldown resistenza da 10k verso massa
OneButton button2(7, false);  //true = pullup resistenza 10k verso positivo
int buttonUp = 6;
int buttonDown = 5;
//int led = 1;
//Led ingressi
const byte led1 = 13;
const byte led2 = 12;
const byte led3 = 11;
const byte led4 = 10;
byte ledIngressi = 0;
int ledOnOff = 0;
int ledMute = 0;

static void click1();
static void click2();
static void cancMem(void *offButton1);

int valore_up = 0;
int valore_down = 0;

int secondi = 0;

//variabili globali per calcolare i tempi di funzionamento
unsigned long tempoAvvio;
unsigned long tempoAcceso;
unsigned long tempoArresto;
unsigned long tempoTotale;
uint8_t min = 0;
uint16_t ore = 0;
//********** aggiunte nuovo orologio **********************
//char Time[] = "  :  :  ";
char Time[] = "  :  ";  //:  ";
char Calendar[] = "  /  /20  ";
char temperature[] = " 00.00";
char temperature_msb;
byte i, second, minute, hour, day, date, month, year, temperature_lsb;

void display_day() {
  switch (day) {
    case 1: draw_text(1, 0, "DOM"); break;
    case 2: draw_text(1, 0, "LUN"); break;
    case 3: draw_text(1, 0, "MAR"); break;
    case 4: draw_text(1, 0, "MER"); break;
    case 5: draw_text(1, 0, "GIO"); break;
    case 6: draw_text(1, 0, "VEN"); break;
    default: draw_text(1, 0, "SAB");
  }
}

void DS3231_display() {
  // Conversione da BCD a decimale
  second = (second >> 4) * 10 + (second & 0x0F);
  minute = (minute >> 4) * 10 + (minute & 0x0F);
  hour = (hour >> 4) * 10 + (hour & 0x0F);
  date = (date >> 4) * 10 + (date & 0x0F);
  month = (month >> 4) * 10 + (month & 0x0F);
  year = (year >> 4) * 10 + (year & 0x0F);
  // Fne conversione

  Time[7] = second % 10 + 48;
  Time[6] = second / 10 + 48;
  Time[4] = minute % 10 + 48;
  Time[3] = minute / 10 + 48;
  Time[1] = hour % 10 + 48;
  Time[0] = hour / 10 + 48;
  Calendar[9] = year % 10 + 48;
  Calendar[8] = year / 10 + 48;
  Calendar[4] = month % 10 + 48;
  Calendar[3] = month / 10 + 48;
  Calendar[1] = date % 10 + 48;
  Calendar[0] = date / 10 + 48;
  if (temperature_msb < 0) {
    temperature_msb = abs(temperature_msb);
    temperature[0] = '-';
  } else
    temperature[0] = ' ';
  temperature_lsb >>= 6;
  temperature[2] = temperature_msb % 10 + 48;
  temperature[1] = temperature_msb / 10 + 48;
  if (temperature_lsb == 0 || temperature_lsb == 2) {
    temperature[5] = '0';
    if (temperature_lsb == 0) temperature[4] = '0';
    else temperature[4] = '5';
  }
  if (temperature_lsb == 1 || temperature_lsb == 3) {
    temperature[5] = '5';
    if (temperature_lsb == 1) temperature[4] = '2';
    else temperature[4] = '7';
  }
}

void DS3231_display_notemp() {
  // Convert BCD to decimal
  second = (second >> 4) * 10 + (second & 0x0F);
  minute = (minute >> 4) * 10 + (minute & 0x0F);
  hour = (hour >> 4) * 10 + (hour & 0x0F);
  date = (date >> 4) * 10 + (date & 0x0F);
  month = (month >> 4) * 10 + (month & 0x0F);
  year = (year >> 4) * 10 + (year & 0x0F);
  // End conversion

  Time[7] = second % 10 + 48;
  Time[6] = second / 10 + 48;
  Time[4] = minute % 10 + 48;
  Time[3] = minute / 10 + 48;
  Time[1] = hour % 10 + 48;
  Time[0] = hour / 10 + 48;
  Calendar[9] = year % 10 + 48;
  Calendar[8] = year / 10 + 48;
  Calendar[4] = month % 10 + 48;
  Calendar[3] = month / 10 + 48;
  Calendar[1] = date % 10 + 48;
  Calendar[0] = date / 10 + 48;
  if (temperature_msb < 0) {
    temperature_msb = abs(temperature_msb);
    temperature[0] = '-';
  } else
    temperature[0] = ' ';
  temperature_lsb >>= 6;
  temperature[2] = temperature_msb % 10 + 48;
  temperature[1] = temperature_msb / 10 + 48;
  if (temperature_lsb == 0 || temperature_lsb == 2) {
    temperature[5] = '0';
    if (temperature_lsb == 0) temperature[4] = '0';
    else temperature[4] = '5';
  }
  if (temperature_lsb == 1 || temperature_lsb == 3) {
    temperature[5] = '5';
    if (temperature_lsb == 1) temperature[4] = '2';
    else temperature[4] = '7';
  }

  draw_text1(3, 2, Time);  // Display the time
}

void blink_parameter() {
  byte j = 0;
  while (j < 10 && digitalRead(buttonset1) && digitalRead(buttonset2)) {
    j++;
    delay(25);
  }
}
byte edit(byte x_pos, byte y_pos, byte parameter) {
  char text[3];
  sprintf(text, "%02u", parameter);
  while (!digitalRead(buttonset1))
    ;  // Wait until button B1 released
  while (true) {
    while (!digitalRead(buttonset2)) {  // If button B2 is pressed
      parameter++;
      if (i == 0 && parameter > 31)  // If date > 31 ==> date = 1
        parameter = 1;
      if (i == 1 && parameter > 12)  // If month > 12 ==> month = 1
        parameter = 1;
      if (i == 2 && parameter > 99)  // If year > 99 ==> year = 0
        parameter = 0;
      if (i == 3 && parameter > 23)  // If hours > 23 ==> hours = 0
        parameter = 0;
      if (i == 4 && parameter > 59)  // If minutes > 59 ==> minutes = 0
        parameter = 0;
      sprintf(text, "%02u", parameter);
      draw_text(x_pos, y_pos, text);
      delay(200);  // Wait 200ms
    }

    draw_text(x_pos, y_pos, "  ");
    blink_parameter();
    draw_text(x_pos, y_pos, text);
    blink_parameter();
    if (!digitalRead(buttonset1)) {  // If button B1 is pressed
      i++;                           // Increament 'i' for the next parameter
      return parameter;              // Return parameter value and exit
    }
  }
}
byte edit1(byte x_pos, byte y_pos, byte parameter) {
  char text[3];
  sprintf(text, "%02u", parameter);
  while (!digitalRead(buttonset1))
    ;  // Wait until button B1 released
  while (true) {
    while (!digitalRead(buttonset2)) {  // If button B2 is pressed
      parameter++;
      //if (i == 0 && parameter > 31)  // If date > 31 ==> date = 1
      //  parameter = 1;
      //if (i == 1 && parameter > 12)  // If month > 12 ==> month = 1
      //  parameter = 1;
      //if (i == 2 && parameter > 99)  // If year > 99 ==> year = 0
      //  parameter = 0;
      if (i == 0 && parameter > 23)  // If hours > 23 ==> hours = 0
        parameter = 0;
      if (i == 1 && parameter > 59)  // If minutes > 59 ==> minutes = 0
        parameter = 0;
      sprintf(text, "%02u", parameter);
      draw_text1(x_pos, y_pos, text);
      delay(200);  // Wait 200ms
    }

    draw_text1(x_pos, y_pos, "   ");
    blink_parameter();
    draw_text1(x_pos, y_pos, text);
    blink_parameter();
    if (!digitalRead(buttonset1)) {  // If button B1 is pressed
      i++;                           // Increament 'i' for the next parameter
      return parameter;              // Return parameter value and exit
    }
  }
}


void draw_text(byte x_pos, byte y_pos, char *text) {
  //void draw_text(byte x_pos, byte y_pos, char *text, byte text_size) {
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.setCursor(x_pos, y_pos);

  u8x8.print(text);
  u8x8.display();
}

void draw_text1(byte x_pos, byte y_pos, char *text) {
  u8x8.setFont(u8x8_font_courB18_2x3_n);
  u8x8.setCursor(x_pos, y_pos);

  u8x8.print(text);
  u8x8.display();
}

void setup() {

  pinMode(buttonset1, INPUT_PULLUP);
  pinMode(buttonset2, INPUT_PULLUP);
  delay(1000);

  // Serial.begin(9600);  //Inizializza il monitor seriale
  rtc.begin();

  Wire.begin();
  IrReceiver.begin(IR_RECEIVE_PIN);
  //IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);//lampeggia il led sul pin 13
  pinMode(16, INPUT);  // volume +
  pinMode(17, INPUT);  // volume -
  pinMode(8, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(15, OUTPUT);

  button1.setPressMs(3000);
  button1.setDebounceMs(20);
  button1.attachClick(click1);
  button1.attachLongPressStop(cancMem, &button1);

  button2.setDebounceMs(20);
  button2.attachClick(click2);

  //Doppio click sul pulsante mute
  //apre schermata del tempo totale di utilizzo
  button2.attachDoubleClick(
    []() {
      if (ledOnOff == HIGH) {
        //inizio codice schermata tempo trascorso
        u8x8.clearDisplay();
        tempoTrascorsoMom();
        delay(5000);
        //DateTime now = rtc.now();
        //printDateTimeMom(now);

        u8x8.clearDisplay();

        int ledMute = digitalRead(8);
        if (ledMute == HIGH) {

          u8x8.setFont(u8x8_font_8x13_1x2_r);
          u8x8.draw2x2String(2, 4, " MUTE  ");

        } else if (ledMute == LOW) {

          StampaIngressi();
        }
      }
    });
  //fine codice schermata tempo trascorso

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(buttonUp, INPUT);
  pinMode(buttonDown, INPUT);
  digitalWrite(buttonUp, HIGH);    //abilitazione resistenze interne di pullup
  digitalWrite(buttonDown, HIGH);  //Pulsanti avanti e indietro canali ingresso

  u8x8.begin();
  u8x8.setPowerSave(0);
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.clearDisplay();
  u8x8.setCursor(0, 4);
  u8x8.print(" <<<   ON   >>>  ");
  delay(2000);

  u8x8.clearDisplay();

  ledIngressi = EEPROM.read(cellaLed);
  EEPROM.get(0, ledIngressi);
  EEPROM.get(1, min);
  EEPROM.get(2, ore);
  tempoTotale = ore * 3600UL + min * 60UL;
}
unsigned long t1, dt;  //variabili tempo accensione mute
bool RUN = false;      //quando premo MUTE diventa true
int menu = 0;


void loop() {
  dt = millis() - t1;
  if ((dt >= 1800000) && RUN) {  //Spegne dopo un certo tempo che il Mute è acceso
                                 // if ((dt >= 60000) && RUN) {
    click1();
    RUN = false;
  }
  button1.tick();
  button2.tick();
  DateTime now = rtc.now();
  ledOnOff = digitalRead(4);

  //DateTime now = rtc.now();
  standby();

  //Alza volume pulsante pannello

  valore_up = digitalRead(puls_volume_up);

  if ((valore_up == HIGH) && (ledOnOff == HIGH)) {
    digitalWrite(led_up, HIGH);
    digitalWrite(8, LOW);  //Spegne mute
    StampaIngressi();
    //digitalWrite(led_up, LOW);
  } else {
    standby();
    digitalWrite(led_up, LOW);
  }

  //Abbassa volume pulsante pannello
  valore_down = digitalRead(puls_volume_down);

  //int vol_down = digitalRead(16);
  if ((valore_down == HIGH) && (ledOnOff == HIGH)) {
    digitalWrite(led_down, HIGH);
    digitalWrite(8, LOW);  //Spegne il mute
    StampaIngressi();
  } else {
    standby();
    digitalWrite(led_down, LOW);
  }

  //Accende in sequenza, avanti e indietro
  // i 4 led degli ingressi
  //if ((valore_up == HIGH) && (ledOnOff == HIGH)) {
  if ((digitalRead(buttonUp) == 0) && (ledOnOff == HIGH)) {
    digitalWrite(8, LOW);
    ledIngressi++;
    delay(250);
    StampaIngressi();
    //delay(250);
    if (ledIngressi > 4) {
      ledIngressi = 1;
      StampaIngressi();
    } else {
      standby();
    }
  }
  //if (digitalRead(buttonDown) == 0) {
  if ((digitalRead(buttonDown) == 0) && (ledOnOff == HIGH)) {
    digitalWrite(8, LOW);
    ledIngressi--;
    delay(250);
    StampaIngressi();
    //delay(250);
    if (ledIngressi < 1) {
      ledIngressi = 4;
      StampaIngressi();
    } else {
      standby();
    }
  }
  if (ledIngressi == 1) {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
  }
  if (ledIngressi == 2) {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
  }
  if (ledIngressi == 3) {
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, LOW);
  }
  if (ledIngressi == 4) {
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, HIGH);
  }



  //************ Telecomando infrarossi ************
  //if (irrecv.decode(&results)) {  //Decodifica i dati ricevuti e salva i dati in results
  // IrReceiver.resume();

  // if (results.bits > 0) {
  //Serial.println(F("======== COMANDO RICEVUTO ======="));
  //Serial.print("Valore: 0x");
  //Serial.println(results.value, HEX);

  if (IrReceiver.decode()) {
    unsigned long keycode = IrReceiver.decodedIRData.command;
    Serial.print("Valore: ");
    Serial.println(keycode);

    switch (keycode) {
      //***********************
      case 22:  //visualizzazione orario
        /*
        Questa if impedisce di ricevere comandi ripetuti
        if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
        IrReceiver.resume();
        return;
        }
         */

        if (ledOnOff == LOW) {
          //  u8x8.clearDisplay();
          standby();
        } else {
          u8x8.clearDisplay();
          printDateTimeMom(now);
          //  tempoTrascorsoMom();

          delay(5000);
          u8x8.clearDisplay();
          StampaIngressi();
        }
        break;
        //irrecv.resume();
        IrReceiver.resume();
        //case 0xF9E21D:  //Tempo trascorso
      case 71:  //visualizza il tempo trascorso
        /*
        Questa if impedisce di ricevere comandi ripetuti
        if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
        IrReceiver.resume();
        return;
        }
         */
        digitalWrite(8, LOW);
        // u8x8.clearDisplay();
        if (ledOnOff == LOW) {
          // u8x8.clearDisplay();
          standby();
        } else {
          u8x8.clearDisplay();

          tempoTrascorsoMom();
          delay(5000);
          u8x8.clearDisplay();
          StampaIngressi();
        }
        break;
        //irrecv.resume();
        IrReceiver.resume();

      //Alza il volume (simbolo altoparlante)
      case 255:

        if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
          IrReceiver.resume();
          return;
        }
        volumeUp();

        
        break;
        IrReceiver.resume();
        //alza volume (freccia sù)
      case 67:
        /*
      if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
          IrReceiver.resume();
          return;
        }
        */
        volumeUp();
        
        break;
        IrReceiver.resume();

        //Abbassa il volume (simbolo altoparlante)
      case 93:
        if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
          IrReceiver.resume();
          return;
        }

        volumeDown();        
        break;
        //irrecv.resume();
        IrReceiver.resume();

        //Abbassa il volume (freccia giù)
      case 10:

        /*
         if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
          IrReceiver.resume();
          return;
        }
        */
        volumeDown();
        
        break;
        //irrecv.resume();
        IrReceiver.resume();

        // Tasto Mute
      case 138:
        //Questa if impedisce di ricevere comandi ripetuti
        if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
          IrReceiver.resume();
          return;
        }
        // digitalWrite(8, !digitalRead(8));
        click2();

        break;
        IrReceiver.resume();

      //irrecv.resume();

      //Tasto On / Off
      case 87:
        // Questa if impedisce di ricevere comandi ripetuti
        if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) {
          IrReceiver.resume();
          return;
        }
        click1();
        break;
        IrReceiver.resume();

        //****** abbassa il volume quando acceso *******
      case 79:
        //int ledOnOff = digitalRead(4);
        if (ledOnOff == LOW) {
          standby();
        } else {
          AbbassaVolumeMom();
        }

        break;
        IrReceiver.resume();
      //******* fine abbassa il volume quando acceso ******

      //Pulsante Canale Indietro
      //case 6:
      case 14:
        if (ledOnOff == LOW) {
          // u8x8.clearDisplay();
          standby();
        } else {
          digitalWrite(8, LOW);  //Spegne il led Mute
          ledIngressi--;

          if (ledIngressi < 1) {
            ledIngressi = 4;
          }
          delay(250);

          StampaIngressi();
        }
        break;
        IrReceiver.resume();

      //Pulsante Canale Avanti
      //case 14:
      case 6:
        if (ledOnOff == LOW) {
          // u8x8.clearDisplay();
          standby();
        } else {

          digitalWrite(8, LOW);  //Spegne il led Mute
          ledIngressi++;
          if (ledIngressi > 4) {
            ledIngressi = 1;
          }
          delay(250);

          StampaIngressi();
        }
        break;
        IrReceiver.resume();

        // irrecv.resume();
      default:
        //case UNKNOWN:
        Serial.println(F("Comando sconosciuto"));

        IrReceiver.resume();

        break;
    }

    IrReceiver.resume();

    //irrecv.resume();
  }
  //************************** fine telecomando infrarossi ************************
}

void valoreVolume() {

  int valPot = analogRead(A0);
  int percVolume = map(valPot, 0, 1023, 0, 99);
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.draw2x2String(0, 0, "<");
  u8x8.draw2x2String(14, 0, ">");

  //Aggiunge lo zero prima della cifra
  //quando il valore è minore di 10
  if (percVolume < 10) {
    u8x8.draw2x2String(6, 0, "0");
    u8x8.draw2x2String(8, 0, String(percVolume).c_str());

  } else {

    u8x8.draw2x2String(6, 0, String(percVolume).c_str());
  }
}
void standby() {
  //DateTime now = rtc.now();
  int valPot = analogRead(A0);
  int percVolume = map(valPot, 0, 1023, 0, 99);
  int ledOnOff = digitalRead(4);
  if (ledOnOff == LOW) {
    //printDateTime(now);
    u8x8.setFont(u8x8_font_8x13_1x2_r);
    u8x8.setCursor(0, 0);
    u8x8.print("Audio Dimensions");
    u8x8.setFont(u8x8_font_open_iconic_embedded_2x2);
    //u8x8.setFont(u8x8_font_open_iconic_embedded_4x4);
    //Ux8.setFont(u8x8_font_open_iconic_embedded_1x1);
    u8x8.drawGlyph(7, 6, 'N');
    digitalWrite(8, LOW);
    //********************
    u8x8.setFont(u8x8_font_8x13_1x2_r);
    if (!digitalRead(buttonset1)) {  // If button B1 is pressed
      i = 0;
      while (!digitalRead(buttonset1))
        ;

      hour = edit1(3, 2, hour);      // Edit hours
      minute = edit1(9, 2, minute);  // Edit minutes

      // Convert decimal to BCD
      minute = ((minute / 10) << 4) + (minute % 10);
      hour = ((hour / 10) << 4) + (hour % 10);
      date = ((date / 10) << 4) + (date % 10);
      month = ((month / 10) << 4) + (month % 10);
      year = ((year / 10) << 4) + (year % 10);
      // End conversion

      // Write data to DS3231 RTC
      Wire.beginTransmission(0x68);  // Start I2C protocol with DS3231 address
      Wire.write(0);                 // Send register address
      Wire.write(0);                 // Reset sesonds and start oscillator
      Wire.write(minute);            // Write minute
      Wire.write(hour);              // Write hour
      Wire.write(day);               // Write day
      Wire.write(date);              // Write date
      Wire.write(month);             // Write month
      Wire.write(year);              // Write year
      Wire.endTransmission();        // Stop transmission and release the I2C bus
      delay(200);                    // Wait 200ms
    }

    Wire.beginTransmission(0x68);   // Start I2C protocol with DS3231 address
    Wire.write(0);                  // Send register address
    Wire.endTransmission(false);    // I2C restart
    Wire.requestFrom(0x68, 7);      // Request 7 bytes from DS3231 and release I2C bus at end of reading
    second = Wire.read();           // Read seconds from register 0
    minute = Wire.read();           // Read minuts from register 1
    hour = Wire.read();             // Read hour from register 2
    day = Wire.read();              // Read day from register 3
    date = Wire.read();             // Read date from register 4
    month = Wire.read();            // Read month from register 5
    year = Wire.read();             // Read year from register 6
    Wire.beginTransmission(0x68);   // Start I2C protocol with DS3231 address
    Wire.write(0x11);               // Send register address
    Wire.endTransmission(false);    // I2C restart
    Wire.requestFrom(0x68, 2);      // Request 2 bytes from DS3231 and release I2C bus at end of reading
    temperature_msb = Wire.read();  // Read temperature MSB
    temperature_lsb = Wire.read();
    // Read temperature LSB
    //if(ledOnOff == LOW){
    //display_day();  // Stampa giorno settimana
    //DS3231_display();                            // Stampa ora e data (time & calendar) e temperatura
    DS3231_display_notemp();  //Chiama la funzione senza mostrare la temperatura
    delay(50);
  }

  if (ledOnOff == HIGH) {
    valoreVolume();
  }
}
void tempoTrascorsoMom() {
  //legge dalla memoria il tempo totale di funzionamento
  EEPROM.get(1, min);
  EEPROM.get(2, ore);
  //e lo mostra sul display
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.setCursor(0, 0);
  u8x8.print("Audio Dimensions");
  u8x8.setCursor(1, 2);
  u8x8.print("UTILIZZATO PER");
  u8x8.setCursor(2, 4);
  u8x8.print("ORE");
  u8x8.setCursor(8, 4);
  u8x8.print("MINUTI");
  u8x8.setCursor(3, 6);
  u8x8.print(ore);
  u8x8.setCursor(10, 6);
  u8x8.print(min);
}
//PULSANTE ACCENSIONE ON/OFF
static void click1() {
  //int ledMute = digitalRead(8);
  digitalWrite(8, LOW);
  u8x8.display();
  u8x8.clearDisplay();
  //int ledOff = 0;
  int ledOnOff = 0;
  digitalWrite(4, !digitalRead(4));

  //ledOff = digitalRead(4);
  ledOnOff = digitalRead(4);
  //if (ledOff == LOW) {
  if (ledOnOff == LOW) {
    //tempoArresto = millis() / 1000UL;
    tempoArresto = millis();
    //tempoAcceso = tempoArresto - tempoAvvio;  // se tempi già in sec non serve dividere / 1000UL
    tempoAcceso = (tempoArresto - tempoAvvio) / 1000UL;
    //funzione accumulo
    tempoTotale = tempoTotale + tempoAcceso;
    // calcolo tempo totale in hh:mm
    ore = tempoTotale / 3600UL;  // UL suffisso per forzare costante a unsigned long
    min = (tempoTotale - (ore * 3600UL)) / 60UL;
    //Ancora più semplice:
    //min = (tempoTotale % 3600UL) / 60UL;//modulo 60
    //min = tempoTotale / 60UL;
    /*
    Serial.print("Avvio:");
    Serial.print(tempoAvvio);
    Serial.println(" sec");
    Serial.print("Arresto:");
    Serial.print(tempoArresto);
    Serial.println(" sec");
    Serial.print("Intervallo:");
    Serial.print(tempoAcceso);
    Serial.println(" sec");
    Serial.print("Totale:");
    Serial.print(ore);
    Serial.print(":");
    Serial.println(min);
    */
    //allo spegnimento aggiorna i dati in memoria
    EEPROM.update(0, ledIngressi);
    //EEPROM.update(1, ore);
    //EEPROM.update(2, minuti);
    EEPROM.put(1, min);
    EEPROM.put(2, ore);
    delay(200);

    //Funione spegnimento
    int valPot = analogRead(A0);
    //int percVolume = map(valPot, 0, 1023, 0, 98);
    int percVolume = map(valPot, 0, 1023, 0, 100);
    valoreVolume();
    u8x8.setFont(u8x8_font_8x13_1x2_r);
    u8x8.setCursor(2, 4);
    digitalWrite(8, HIGH);
    u8x8.print("SPEGNIMENTO");
    u8x8.setCursor(3, 6);
    u8x8.print("IN  CORSO");
    //Il potenziometro ruota finché il valore non scende a zero
    while (percVolume >= 1) {
      digitalWrite(led_down, HIGH);
      valPot = analogRead(A0);
      //percVolume = map(valPot, 0, 1023, 0, 98);
      percVolume = map(valPot, 0, 1023, 0, 100);
      valoreVolume();
    }
    digitalWrite(led_down, LOW);
    digitalWrite(8, LOW);
    u8x8.display();
    u8x8.clearDisplay();
    u8x8.setFont(u8x8_font_8x13_1x2_r);
    u8x8.setCursor(0, 4);
    u8x8.print(" <<<  OFF  >>> ");
    delay(2000);
    u8x8.clearDisplay();
  }
  //Fine funzione spegnimento

  //if (ledOff == HIGH) {
  if (ledOnOff == HIGH) {
    //tempoAvvio = (millis() / 1000);
    tempoAvvio = millis();
    digitalWrite(8, HIGH);
    u8x8.setFont(u8x8_font_8x13_1x2_r);

    AbbassaVolume();
    u8x8.clearDisplay();

    
    
    int indice = 30;
    while (indice >= 1) {  //era 15
      digitalWrite(8, HIGH);

      u8x8.setCursor(0, 0);
      u8x8.print("Audio Dimensions");
      u8x8.setCursor(0, 4);
      //u8x8.print("< PRERISCALDO >");
      //u8x8.print("< ATTENDERE... >");
      // u8x8.print("...ATTENDERE...");
      // u8x8.print("-- ATTENDERE --");
      u8x8.print("<< ATTENDERE >>");
      //delay(1000);
      //indice--;

      //aggiunge lo zero quando il valore è inferiore a 10
      if (indice < 10) {
        u8x8.drawString(7, 6, "0");
        u8x8.drawString(8, 6, String(indice).c_str());
      } else {
        u8x8.drawString(7, 6, String(indice).c_str());
      }
      delay(1000);
      indice--;
    }
    u8x8.clearDisplay();
    AlzaVolume();
    StampaIngressi();
    digitalWrite(8, LOW);
    //EEPROM.get(1, min);
    // EEPROM.get(2, ore);
    //tempoTotale = ore * 3600UL + min * 60UL;
  }
}
// PULSANTE MUTE
static void click2() {
  t1 = millis();
  RUN = true;

  ledMute = digitalRead(8);

  if (ledOnOff == LOW) {
    //u8x8.clearDisplay();
    standby();
  } else {

    digitalWrite(8, !digitalRead(8));
    int ledMute = digitalRead(8);

    if (ledMute == HIGH) {
      u8x8.setFont(u8x8_font_8x13_1x2_r);

      for (int i = 1; i < 4; i++) {
        u8x8.draw2x2String(2, 4, " MUTE  ");
        delay(1000);
        //u8x8.clearDisplay();
        u8x8.draw2x2String(2, 4, "              ");
        delay(250);
      }
      u8x8.setFont(u8x8_font_8x13_1x2_r);
      u8x8.drawString(0, 4, "SPEGNIMENTO TRA");
      u8x8.drawString(0, 6, "   30 MINUTI   ");
      delay(5000);
      u8x8.clearDisplay();
      u8x8.draw2x2String(2, 4, " MUTE  ");



    } else if (ledMute == LOW) {
      RUN = false;
      u8x8.setFont(u8x8_font_8x13_1x2_r);
      StampaIngressi();
    }
  }
}
static void cancMem(void *offButton1) {
  EEPROM.write(1, 0);
  EEPROM.write(2, 0);
  EEPROM.write(3, 0);
  delay(200);
  u8x8.clearDisplay();
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.setCursor(5, 1);
  u8x8.print("TEMPO");
  u8x8.setCursor(2, 3);
  u8x8.print("DI UTILIZZO");
  u8x8.setCursor(4, 5);
  u8x8.print("AZZERATO");
  delay(2000);
  u8x8.clearDisplay();
  //StampaIngressi();
}
void StampaIngressi() {

  u8x8.setFont(u8x8_font_8x13_1x2_r);

  switch (ledIngressi) {
    case 1:
      //u8x8.draw2x2String(3, 4, "PHONO  ");
      u8x8.draw2x2String(2, 4, " AUX2   ");
      break;
    case 2:
      //u8x8.draw2x2String(2, 4, "  CD    ");
      u8x8.draw2x2String(2, 4, " AUX1   ");
      break;
    case 3:
      //u8x8.draw2x2String(2, 4, " AUX1   ");
      u8x8.draw2x2String(2, 4, "  CD    ");
      break;
    case 4:
      //u8x8.draw2x2String(2, 4, " AUX2   ");
      u8x8.draw2x2String(3, 4, "PHONO  ");
      break;
    default:
      break;
  }
}
void printDateTimeMom(DateTime dt) {
  char daysOfTheWeek[7][12] = { "DOM", "LUN", "MAR", "MER", "GIO", "VEN", "SAB" };
  DateTime now = rtc.now();
  char dateBuffer[] = "DD/MM/YYYY";
  // char timeBuffer[] = "hh:mm:ss";
  char timeBuffer[] = "hh:mm";
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  //u8x8.setCursor(1, 0);
  //u8x8.print(daysOfTheWeek[now.dayOfTheWeek()]);
  //u8x8.setCursor(5, 0);
  //u8x8.print(dt.toString(dateBuffer));
  u8x8.setCursor(0, 0);
  u8x8.print("Audio Dimensions");
  u8x8.setCursor(5, 2);
  u8x8.print(dt.toString(timeBuffer));
  u8x8.drawString(2, 4, "TEMPERATURA");
  //int temperatura = rtc.getTemperature();
  float temperatura = rtc.getTemperature();
  u8x8.setCursor(4, 6);
  u8x8.print(temperatura);
  //u8x8.setCursor(2,5);
  //u8x8.print("°C");
  u8x8.drawString(10, 6, "'C");
}

void AbbassaVolume() {

  // u8x8.clearDisplay();

  //Abbassa il volume momentaneamente fino a 5
  int valPot = analogRead(A0);
  //int percVolume = map(valPot, 0, 1023, 0, 98);
  int percVolume = map(valPot, 0, 1023, 0, 100);
  valoreVolume();
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.setCursor(2, 5);
  digitalWrite(8, HIGH);

  //Il potenziometro ruota finché il valore non scende a zero
  while (percVolume >= 1) {
    digitalWrite(led_down, HIGH);
    // digitalWrite(8, HIGH);
    valPot = analogRead(A0);
    //percVolume = map(valPot, 0, 1023, 0, 98);
    percVolume = map(valPot, 0, 1023, 0, 100);
    valoreVolume();
  }
  digitalWrite(led_down, LOW);
  digitalWrite(8, LOW);
  // u8x8.display();
  // u8x8.clearDisplay();
}

void AbbassaVolumeMom() {

  // u8x8.clearDisplay();

  //Abbassa il volume momentaneamente fino a 5
  int valPot = analogRead(A0);
  //int percVolume = map(valPot, 0, 1023, 0, 98);
  int percVolume = map(valPot, 0, 1023, 0, 100);

  valoreVolume();
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.setCursor(2, 5);
  digitalWrite(8, HIGH);

  //Il potenziometro ruota finché il valore non scende a 5
  while (percVolume >= 6) {
    digitalWrite(led_down, HIGH);
    // digitalWrite(8, HIGH);
    valPot = analogRead(A0);
    //percVolume = map(valPot, 0, 1023, 0, 98);
    percVolume = map(valPot, 0, 1023, 0, 100);
    valoreVolume();
  }
  digitalWrite(led_down, LOW);
  digitalWrite(8, LOW);
  // u8x8.display();
  // u8x8.clearDisplay();
}

void AlzaVolume() {

  // u8x8.clearDisplay();

  //Abbassa il volume momentaneamente fino a 5
  int valPot = analogRead(A0);
  //int percVolume = map(valPot, 0, 1023, 0, 98);
  int percVolume = map(valPot, 0, 1023, 0, 100);
  valoreVolume();
  u8x8.setFont(u8x8_font_8x13_1x2_r);
  u8x8.setCursor(2, 5);
  digitalWrite(8, HIGH);

  //Il potenziometro ruota finché il valore non va a 5
  while (percVolume <= 4) {
    digitalWrite(led_up, HIGH);
    // digitalWrite(8, HIGH);
    valPot = analogRead(A0);
    //percVolume = map(valPot, 0, 1023, 0, 98);
    percVolume = map(valPot, 0, 1023, 0, 100);
    valoreVolume();
  }
  digitalWrite(led_up, LOW);
  digitalWrite(8, LOW);
  // u8x8.display();
  // u8x8.clearDisplay();
}

//funzione che ferma il potenziometro
//quando il valore arriva a zero

void volumeDown() {

  int valPot = analogRead(A0);
  //int percVolume = map(valPot, 0, 1023, 0, 98);
  int percVolume = map(valPot, 0, 1023, 0, 100);
  //se il valore è zero il motore si ferma
  if ((ledOnOff == HIGH) && (percVolume >= 1)) {
    digitalWrite(led_down, HIGH);
    //digitalWrite(8, LOW);  //Spegne il mute
    StampaIngressi();
  } else {
    standby();
    digitalWrite(led_down, LOW);
  }
  if (percVolume == 0) {
    digitalWrite(8, HIGH);
  }
}
void volumeUp() {
  int valPot = analogRead(A0);
  //
  int percVolume = map(valPot, 0, 1023, 0, 100);
  //se il valore supera 98 il motore si ferma
  if ((ledOnOff == HIGH) && (percVolume <= 98)) {
    digitalWrite(led_up, HIGH);

    
    digitalWrite(8, LOW);  //Spegne il mute
    StampaIngressi();
    //valoreVolume();
  } else {
    standby();
    digitalWrite(led_up, LOW);
  }
}

Ciao. Nello sketch con i tasti del telecomando richiamo due funzioni, volumeUp e volumeDown. Poiché voglio fare in modo che il potenziometro si fermi quando arriva alla fine della corsa. Nello switch case non potevo mettere le if o almeno non ci sono riuscito. Comando il motore del potenziometro del volume sia con due pulsanti che con un telecomando infrarossi. Con i pulsanti, finchè sono premuti, mandano a livello alto i pin di uscita. Con il telecomando invece il valore di tensione sul pin varia al variare degli impulsi. La mia idea era quella di far funzionare il tasto del telecomando come il pulsante e cioè mandare a livello alto il pin finchè ci sono degli impulsi con quel determinato codice.

Ciao nid69ita. I tasti del telecomando utilizzati sono quelli dello switch case
10 e 93 per la funzione volumeDown, 255 e 67 per volumeUp. Io richiamo la .resume() ad ogni case. Questo potrebbe essere uno degli errori? Il led che accendo con il telecomando (sullo stesso pin del motore) è intermittente, come se gli impulsi si fermassero. Ho provato a seguire i consigli di @fabpolli ma con la mia pochissima esperienza non sono proprio riuscito a capire dove può essere questa interruzione. L'uscita è subito alta, il led si accende subito ma poi si spegne e così via. Hai qualche idea?

Dubito.
in uno switch() , tutto quello che scrivi dopo il break; non verrà mai eseguito
Quindi

switch(keycode)
{ case 22: 
    ...
    break;
    IrReceiver.resume();          // ??? mai eseguito !!
  case 71:

Fai un pò di pulizia, quelle righe tra break: e case toglile

Verifica anche tutti i commenti, facendo in modo che siano esatti e comprensibili, e la relativa parte di programma!
Qualche riga a caso:

Io ridurrei il codice all'essenziale, tipo quello che segue.
Però mi rendo conto che avrai problemi ad integrarlo nel progetto, il
motivo è legato al fatto che crei "codice bloccante", con i vari while che includono anche delay.

void loop() {
    byte keycode = 0; // variabile locale
    if (IrReceiver.decode()) {
        keycode = IrReceiver.decodedIRData.command;
        Serial.print("Valore: ");
        Serial.println(keycode);
    }  // end  if (IrReceiver.decode())

    switch (keycode) {
      //***********************
      case 10:  // alza volume
      case 93: //    "     "
          //  qui il codice per alzare 
          if (volSetpoint < 100) {
              volSetpoint++;
          }
      break; // case 10, 93

      case 67:    // abbassa volume
      case 255: //      "      " 
           if (volSetpoint > 1) {
              volSetpoint--;
          }
      break;  // case 67, 255
}

Testando questa porzione di codice, tenendo premuto il pulsante 10,93 il volume si incrementerà molto rapidamente, sempre che il telecomando ha l'autorepeat. Per rallentare l'incremento allora basta usare millis() nel modo consueto.

Poi toccherà occuparsi si fare girare il motore fino a quando: volume == volSetpoint.

Ciao.

Lo so, piuttosto disordinato. Mi rendo conto che non è facile ricevere un aiuto. Purtroppo la mancanza di esperienza non mi ha permesso di organizzare meglio il lavoro dall'inizio.

Ciao Mauro, Grazie per l'esempio. Non sono molto esperto per svilupparlo con millis(), ma spero di riuscircici.

Se il codice bloccante può influire o meno con certezza io non sono stato capace di dedurlo. Io non uso mai delay (quasi). In ogni caso scrivendo codice per la sola gestione del volume motorizzato (senza introdurre "codice bloccante"), ci sono molti vantaggi:

  • Non c'è altro codice che può influire.
  • Essendoci meno codice si evita di dovere fare su e giù con la rotella del mouse per scorrere il codice.

Il codice suggerito è strutturato. Ciò significa che se hai sul pannello
dei pulsanti "Vol+" e "Vol-" si fa presto a integrare la lettura dei pulsanti che restituiscono 10 per "Vol+" e 67 per "Vol-" attivando così i rispettivi case.

Per millis lo si vede dopo. Per adesso mi servirebbe sapere se il telecomando ha l'autorepeat, cioè tenendo premuto il pulsante per aumentare il volume (es.10) entrerà nel case 10, 93 con un repeat rate di n ripetizioni al secondo. Possono anche modificare il codice per stampare il repeat rate.

Ciao.