Problemi suono buzzer in sveglia multifunzione

Salve a tutti, sto costruendo una sveglia con wemos d1 mini, modulo rtc, ds18b20, buzzer,display lcd e un bottone
funziona bene secondo quello che voleva, l'unica cosa è che quando la sveglia è attivata per suonare e l'orario è giusto il buzzer suona però anzichè suonare per 200ms ogni 200ms si accorda all'aggiornamento della temperatura del sd18b20l producendo un suono discontinuo in base alla variazione della temperatura

a questo punto vorrei cercare di separare separare la lettura del sensore dal suono del buzzer o come minimo bloccare la lettura temperatura quando il buzzer è attivo

#include <DallasTemperature.h>
#include <OneWire.h>
#include <RTClib.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define BACKLIGHT_PIN     13
#define ONE_WIRE_BUS D6

RTC_DS3231 rtc;
OneWire oneWire(ONE_WIRE_BUS); 
DallasTemperature sensore(&oneWire); 
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);  

int stato_bottone= HIGH;
int stato_sveglia=HIGH;
int stato=LOW;

String ora_sveglia="09:36";

void setup() {
Serial.begin(9600);
pinMode(A0, INPUT);
pinMode(D7, OUTPUT); //buzzer
pinMode(D3, OUTPUT); //illuminazione lcd
pinMode(D5, INPUT_PULLUP); //bottone
  rtc.begin();
sensore.begin();
lcd.begin(16,2);
lcd.setBacklightPin(3, POSITIVE);
lcd.setBacklight(HIGH);
lcd.home();

  if (rtc.lostPower()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}

void loop(){


    DateTime now = rtc.now();
  printDateTime(now);


////cambi stato
 if (digitalRead(D5)==LOW) {
   stato_bottone =!stato_bottone;
   delay(200);
   }
 if (digitalRead(D6)==LOW) {
   stato =!stato;
   delay(200);
   }
 
}


void printDateTime(DateTime dt) {

  char dateBuffer[] = "DD/MM";
  char timeBuffer[] = "hh:mm";
  lcd.setCursor(0, 0);
  lcd.print(dt.toString(dateBuffer));
  lcd.setCursor(0, 1);
  lcd.print(dt.toString(timeBuffer));

  sensore.requestTemperatures(); // richiesta lettura temperatura
  float celsius = sensore.getTempCByIndex(0);
  lcd.setCursor(11,0);
  lcd.print(celsius);



////per attivare o disattivare la sveglia
 if (stato_bottone==LOW) {
  ///sveglia attivata
  stato_sveglia=HIGH;
  lcd.setCursor(11,1);
  lcd.print(ora_sveglia);
}else{
  //Sveglia disattivata
  stato_sveglia=LOW;
  lcd.setCursor(11,1);
  lcd.print("     ");

 }

if ((stato_sveglia==HIGH) && (String(timeBuffer)==ora_sveglia)){
 

  digitalWrite(D7,HIGH);
  delay(200);
  digitalWrite(D7,LOW);
  delay(200); 

 }else{
  digitalWrite(D7,LOW);
}

}




Il modo più semplice nel codice presentato è quello di mettere lettura temp e aggiornamento display sotto una condizione. Quando è il momento di suonare fai in modo che la condizione diventi falsa, quando il suono è finito la riabiliti. È sufficiente un'altra variabile di stato.

Oltre a questo, non è necessario misurare e scrivere sul display ad ogni ciclo di programma. Basta farlo una volta al secondo per quanto riguarda l'orario, e una volta ogni tot secondi per la temperatura. Già questo ridurrebbe di molto l'impegno della CPU. Però per fare questo bisogna imparare a gestire i tempi con la funzione millis evitando i delay nel codice.

La condizione per bloccare la lettura della temperatura e l'aggiornamento del display cosa dovrebbe comprendere? Cioè di cosa dovrei vedere lo stato?

Poi per quanto riguarda la seconda parte, praticamente dovrei togliere la misura e l'aggiornamento dal loop?

praticamente ... devi studiarti come si usa la funzione millis(), prima QUI, poi QUI e QUI e QUI e tutti gli articoli che sono in QUESTA pagina ... vedrai che poi ti sarà tutto più chiaro ...

Guglielmo

ho provato a modificare il codice e adesso il suono non è instabile come prima però ogni 3000ms fa una pausa

unsigned long tempo;
#include <DallasTemperature.h>
#include <OneWire.h>
#include <RTClib.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define BACKLIGHT_PIN 13
#define ONE_WIRE_BUS D4

RTC_DS3231 rtc;
OneWire oneWire(ONE_WIRE_BUS); 
DallasTemperature sensore(&oneWire); 
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);  

int stato_bottone= HIGH;
int stato_sveglia=HIGH;

String ora_sveglia="17:22";

void setup() {
  tempo=millis();
  
Serial.begin(9600);
pinMode(D3, OUTPUT); //illuminazione lcd
pinMode(D5, INPUT_PULLUP); //bottone
pinMode(D7, OUTPUT); //buzzer

rtc.begin();
sensore.begin();
lcd.begin(16,2);
lcd.setBacklightPin(3, POSITIVE);
lcd.setBacklight(HIGH);
lcd.home();

if (rtc.lostPower()) {
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}

void loop(){
  int v=analogRead(A0);
  int luce =map(v, 0, 1023, 0, 100);
  Serial.println(luce);
  if (luce<40){
    analogWrite(D3, 40);
  }else{
    analogWrite(D3, 0);
  }

  



    DateTime now = rtc.now();
printDateTime(now);
    
  


////cambi stato
if (digitalRead(D5)==LOW) {
  stato_bottone =!stato_bottone;
  delay(200);
   }

}

void printDateTime(DateTime dt) {

  char dateBuffer[] = "DD/MM";
  char timeBuffer[] = "hh:mm";


   if  ((millis() - tempo>=3000)){
  sensore.requestTemperatures(); 
  float celsius = sensore.getTempCByIndex(0);
  lcd.setCursor(13,0);
  lcd.print(int(celsius));
    lcd.setCursor(15,0);
  lcd.print("C");

  lcd.setCursor(0, 0);
  lcd.print(dt.toString(dateBuffer));
  lcd.setCursor(0, 1);
  lcd.print(dt.toString(timeBuffer));
  tempo=millis();

  } 
  



////per attivare o disattivare la sveglia
 if (stato_bottone==LOW) {
  ///sveglia attivata
  stato_sveglia=HIGH;
  lcd.setCursor(11,1);
  lcd.print(ora_sveglia);
}else{
  //Sveglia disattivata
  stato_sveglia=LOW;
  lcd.setCursor(11,1);
  lcd.print("     ");
 }



if (stato_sveglia==HIGH) // && (String(timeBuffer)==ora_sveglia))
{
  analogWrite(D3, 256);
  digitalWrite(D7,HIGH);
  delay(200);
  digitalWrite(D7,LOW);
  delay(200); 
 }else{
  digitalWrite(D7,LOW);

  }

}

Se durante l'esecuzione dei suoni leggi anche il sensore (750 ms) per forza di cose durante quel tempo (in questo caso ogni tre secondi) si crea una pausa. È giusto leggere il sensore ogni tot secondi per non occupare tutto il tempo CPU, ma comunque solo quando non è attiva la suoneria.