# Gestione del'interrupt software

**URL:** <https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904>\
**Category:** Software\
**Created:** [January 12, 2025, 5:34pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904 "2025-01-12T17:34:14Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![mauro\_bellucci](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/mauro_bellucci/32/1127009_2.png) [@mauro\_bellucci](https://forum.arduino.cc/u/mauro_bellucci)\
**Post date:** [January 12, 2025, 5:34pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/1 "2025-01-12T17:34:14Z")

</div>

Buonasera, sono un eterno principiante, nel senso che ogni volta che scopro qualcosa di nuovo diventa un chiodo fisso.  
Ho da poco scoperto gli Esp32 e i vari sensori tra cui il D18B20 per testare la temperatura.  
fatto il primo sketch con il ciclo loop leggo le temperature tranquillamente.  
Poi però l'utilizzo di "loop" mi andava stretto, in quanto utilizzando delay tra una lettura e l'altra non potevo gestire altre operazioni con intervalli diversi.  
Cerco e scopro gli interrupt software, su cui la maggior parte della documentazione è riferita a versioni precedenti.  
Dopo ulteriori ricerche ho trovato qualcosa sulla nuova versione e facendo qualche prova con WOKWI funziona perfettamente.  
La realtà ha evidenziato risultati più deludenti.  
Ad ogni ciclo mi viene restituito un errore credo su indirizzi di memoria non gestibili.

Interrupt ...28:13:6b:58:00:00:00:b9 -\> 20.31°  
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.

Core 1 register dump:  
PC : 0x40083f5c PS : 0x00050d31 A0 : 0x800d20c7 A1 : 0x3ffbf8ec  
A2 : 0x00000040 A3 : 0x00018040 A4 : 0x000637ff A5 : 0x3ffbf8cc  
A6 : 0x00000000 A7 : 0xb33fffff A8 : 0x800d4610 A9 : 0x4008aac2  
A10 : 0x00000000 A11 : 0x7da15afe A12 : 0x800838d8 A13 : 0x3ffbf8ac  
A14 : 0x3ffc1fe8 A15 : 0x400854e4 SAR : 0x00000019 EXCCAUSE: 0x0000001c  
EXCVADDR: 0x800d20d3 LBEG : 0x400866b5 LEND : 0x400866c5 LCOUNT : 0xffffffff

Backtrace: 0x40083f59:0x3ffbf8ec |\<-CORRUPTED

su questo non riesco a trovare soluzioni.  
vi allego il codice, se qualcuno potesse aiutarmi

```arduino
#include <OneWire.h>
#include <DallasTemperature.h>

// GPIO where the DS18B20 is connected to
const int oneWireBus = 4; 

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);

// Pass our oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);
DeviceAddress mac;
struct rdTemp
{
  String sndMac;
  float temp ;
};

hw_timer_t *timer = NULL;
rdTemp x; 
void ARDUINO_ISR_ATTR onTimer()
{
  Serial.print("Interrupt ...");
  rdTemp dati = readTemp();
  Serial.print(dati.sndMac);
  Serial.print(" -> ");
  Serial.print(dati.temp);
  Serial.print("°");
 Serial.println();
}

rdTemp readTemp()
{
  sensors.requestTemperatures(); 
  float temperatureC = sensors.getTempCByIndex(0);
  String wMac = decodMac() ; 
  rdTemp x ={ wMac, temperatureC};
  return x;
}

String decodMac()
{
    String wMac = "" ;
    String sep = "" ;
    for (uint8_t ii = 0; ii < 8; ii++) 
    {
      String mc = "00" + String(mac[ii], HEX) ;  
      int l = mc.length() ;
      mc = mc.substring(l -2,l); 
      wMac += sep + mc ;
      sep = ":" ;
    }
    return wMac ;
}

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  
  sensors.begin();
  sensors.getAddress(mac, 0);
  decodMac(); 

  delay(100);
  timer = timerBegin(1000000);
  timerAttachInterrupt(timer, onTimer);
  timerAlarm(timer, 5000000, true, 0);
}

void loop()
{

}

```

---

<div class="post-metadata">

**Author:** ![UKHeliBob](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/ukhelibob/32/215663_2.png) [@UKHeliBob](https://forum.arduino.cc/u/UKHeliBob)\
**Post date:** [January 12, 2025, 5:35pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/2 "2025-01-12T17:35:24Z")

</div>

⚠  
Ti segnalo che, nella sezione in lingua **Inglese** , si può scrivere **SOLO** in **Inglese**... quindi, per favore, la prossima volta **presta più attenzione** in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella [sezione di lingua Italiana](https://forum.arduino.cc/c/international/italiano/50) ... la prossima volta potrebbe venire direttamente eliminato.  
Grazie.

---

<div class="post-metadata">

**Author:** ![gpb01](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gpb01/32/830685_2.png) [@gpb01](https://forum.arduino.cc/u/gpb01)\
**Post date:** [January 12, 2025, 5:55pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/3 "2025-01-12T17:55:01Z")

</div>

A quanto detto da **UKHeliBob** aggiungo ...

... cortesemente, come prima cosa, leggi attentamente il [REGOLAMENTO](https://forum.arduino.cc/t/regolamento-come-usare-questo-forum/145566) della sezione **Italiana** del forum, (_... e, per evitare future possibili discussioni/incomprensioni, prestando sempre molta attenzione al punto 15_), dopo di che, come da suddetto regolamento (_punto 16.7_), **fai la tua presentazione** [NELL'APPOSITA DISCUSSIONE](https://forum.arduino.cc/t/re-presentazioni-nuovi-iscritti-fatevi-conoscere-da-tutti-part-2/) (_... quello che vedi in blu è un link, fai click su di esso per raggiungere la discussione_) spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie,

Guglielmo

_P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. 😉_

_P.P.S.: Evitate di utilizzare la traduzione automatica fatta dal browser ... vi impedisce di capire la lingua della sezione dove andate a scrivere ..._

---

<div class="post-metadata">

**Author:** ![gpb01](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gpb01/32/830685_2.png) [@gpb01](https://forum.arduino.cc/u/gpb01)\
**Post date:** [January 13, 2025, 11:54am UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/4 "2025-01-13T11:54:26Z")

</div>

> [@mauro\_bellucci](#):
>
> Poi però l'utilizzo di "loop" mi andava stretto, in quanto **utilizzando delay** tra una lettura e l'altra non potevo gestire altre operazioni con intervalli diversi.

Invece di incasinarti subito la vita utilizzando cose che richiedono più esperienza, impara a **NON** usare la funzione delay() che è bloccante ed studiati invece come si usa la funzione [millis()](https://www.arduino.cc/reference/en/language/functions/time/millis/), prima [QUI](https://www.leonardomiliani.com/?p=576), poi [QUI](https://www.leonardomiliani.com/?p=758) e [QUI](https://docs.arduino.cc/built-in-examples/digital/BlinkWithoutDelay) e [QUI](http://www.baldengineer.com/pushbutton-and-flashing-led-tutorial-with-millis.html) e tutti gli articoli che sono in [QUESTA](https://www.baldengineer.com/arduino-millis-examples.html) pagina ... vedrai che poi ti sarà tutto più chiaro come fare ... 😉

Guglielmo

---

<div class="post-metadata">

**Author:** ![cotestatnt](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cotestatnt/32/238781_2.png) [@cotestatnt](https://forum.arduino.cc/u/cotestatnt)\
**Post date:** [January 13, 2025, 12:49pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/5 "2025-01-13T12:49:33Z")

</div>

Sisi usando una libreria che usa gli interrupt (`Wire.h`) all'interno di una Interrupt Service Routine associata quindi ad un'altro interrupt.

Non possono che venirne fuori solo guai...

---

<div class="post-metadata">

**Author:** ![mauro\_bellucci](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/mauro_bellucci/32/1127009_2.png) [@mauro\_bellucci](https://forum.arduino.cc/u/mauro_bellucci)\
**Post date:** [January 13, 2025, 1:29pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/6 "2025-01-13T13:29:49Z")

</div>

Ho capito che mi sto incasinando, ma se non lo faccio ora che sono agli inizi, quando lo faccio?  
gestire millis() come suggerisce **Guglielmo** significa utilizzare gli IF che considero il male assoluto dei codici.  
Ho letto qualcosa riguardo alla definizione " **volatile**", che credo possa centrare, ma non trovo più l'articolo.  
Potrebbe essere una strada?

---

<div class="post-metadata">

**Author:** ![Maurotec](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/maurotec/32/213982_2.png) [@Maurotec](https://forum.arduino.cc/u/Maurotec)\
**Post date:** [January 13, 2025, 1:34pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/7 "2025-01-13T13:34:59Z")

</div>

Guarda caso hai indovinato tutto ciò che riguarda gli interrupt, tutto il resto è la causa del problema.

```arduino
return wMac ;

```

Non restituire una variabile locale. Il tipo String è una classe C++, con il suo costruttore, costruttore di copia, assegnamento e distruttore. Il distruttore viene chiamato automaticamente quando la funzione termina e questo è buono perché libera la memoria allocata (a run-time) da String, diversamente si verificherebbe un "memory leak".

```arduino
  rdTemp x ={ wMac, temperatureC};
  return x;
}

```

La parola chiave **struct** è presente sia in C che in C++, ma in C++ è equivalente ad una classe.  
Uno ci si aspetta che venga fatta una copia dell'oggetto locale (x) per essere restituito così come avviene con i tipi built-in (int, uint, ecc), ma non accade.

```arduino
void decodMac(String &wMac)
{
    
    String sep = "" ;
    for (uint8_t ii = 0; ii < 8; ii++) 
      {
        String mc = "00" + String(mac[ii], HEX) ;  
         int l = mc.length() ;
         mc = mc.substring(l -2,l); 
         wMac += sep + mc ; // usa il riferimento passato come argomento wMac
         sep = ":" ;
    }
 }

```

la chiamata sarebbe simile a:

```arduino
String wMac;
decodeMac(wMac);
// qui puoi direttamente stampare wMac
// ma occhio che essendo per forza di cose dentro una funzione quando questa 
// termina viene chiamato il distruttore su wMac per liberare la memoria.

```

Stesso ragionamento per la funzione `readTemp()`.

Per il discorso loop() visto che la scheda è una esp32 hai tanti modi differenti aggirare il problema,  
uno è usare FreeRTOS già incluso, che ti permette programmazione concorrente, con tutti i problemi che ne derivano (Serve polso e lucidità, non è banale).

Mentre millis() e i timer hardware per piccoli/medi programmi è la soluzione più usata, l'unico problema è che devi disintossicarti 😃 da **delay()**.

Ti lascio un link ad un articolo dove si descrive il programmino per realizzare un termostato, dove  
viene usato millis().

> **[Termostato con arduino (2° puntata)](https://programmersqtcpp.blogspot.com/2022/07/termostato-con-arduino-2-puntata.html)**
>
> termostato digitale, sonda NTC, pseudo linguaggio, Bottom-Up, media aritmetica, variabili globali, relay controllato, cella frigorifera ecc.

> **[Applicazione accesso a parcheggio](https://programmersqtcpp.blogspot.com/2022/03/applicazione-accesso-parcheggio.html)**
>
> L’implementazione di una macchina a stati finiti tramite lo switch case.
> Automazione per plastico.

Ciao.

---

<div class="post-metadata">

**Author:** ![Maurotec](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/maurotec/32/213982_2.png) [@Maurotec](https://forum.arduino.cc/u/Maurotec)\
**Post date:** [January 13, 2025, 1:47pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/8 "2025-01-13T13:47:29Z")

</div>

Wire.h come I2c?  
Oppure OneWire?

Cioè OneWire e Dallas ecc usano interrupt su ESP?

PS: di ESP conosco poco e male.

Ciao.

---

<div class="post-metadata">

**Author:** ![gpb01](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gpb01/32/830685_2.png) [@gpb01](https://forum.arduino.cc/u/gpb01)\
**Post date:** [January 13, 2025, 2:13pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/9 "2025-01-13T14:13:21Z")

</div>

> [@mauro\_bellucci](#):
>
> utilizzare gli IF che considero il male assoluto dei codici.

Ehhhh ???

E questa dove l'hai letta ????

Guglielmo

---

<div class="post-metadata">

**Author:** ![cotestatnt](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cotestatnt/32/238781_2.png) [@cotestatnt](https://forum.arduino.cc/u/cotestatnt)\
**Post date:** [January 13, 2025, 2:23pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/10 "2025-01-13T14:23:48Z")

</div>

> [@mauro\_bellucci](#):
>
> `#include <OneWire.h>`

Non proprio a dire il vero, però si tratta di operazioni che vengono comunque eseguite con una certa criticità e non son sicuro che questo blocco di codice venga eseguito correttamente all'interno di una ISR.

> <https://github.com/PaulStoffregen/OneWire/blob/master/OneWire.cpp#L151>

Secondo me la strada maestra in questi casi è FreeRTOS per quanto possa apparire poco user friendly e richieda impegno.  
Anche gestire tutto temporizzando con `millis()` va altrettanto bene, tanto l'ESP32 riesce a fare questo ed altri 20 task simili senza problemi tutti all'interno di `loop()`

L'approccio del timer hardware invece non mi sembra "buono" in questo caso... sarebbe come usare uno scheduler (il timer) all'interno di uno scheduler già esistente (FreeRTOS).

---

<div class="post-metadata">

**Author:** ![cotestatnt](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cotestatnt/32/238781_2.png) [@cotestatnt](https://forum.arduino.cc/u/cotestatnt)\
**Post date:** [January 13, 2025, 2:25pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/11 "2025-01-13T14:25:26Z")

</div>

> [@mauro\_bellucci](#):
>
> gli IF che considero il male assoluto dei codici.

😮 😮 😮

Questo equivale più o meno ad affermare che le vocali sono il male assoluto delle lingue parlate...

---

<div class="post-metadata">

**Author:** ![mauro\_bellucci](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/mauro_bellucci/32/1127009_2.png) [@mauro\_bellucci](https://forum.arduino.cc/u/mauro_bellucci)\
**Post date:** [January 13, 2025, 2:38pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/12 "2025-01-13T14:38:31Z")

</div>

Riguardo agli **IF** , mi viene il mal di stomaco ogni volta che devo scontrarmi con roba del genere.

```arduino
	For Each strVarianti In cfgVar
		arrVarianti = split(strVarianti,"|")		
		result = True
		For Each variante In split(arrVarianti(0),",")
			codVar = split(variante,"=")(0)
			rispVar = split(variante,"=")(1)
			If instr(codVar, ":") > 0 Then		
				amb.reg.var.letv split(codVar,":")(0),rispVar
				rispCalc = UCase(amb.reg.gzvar.valuta("$(" & codVar & ")"))
				if inStr(rispVar, "{") > 0 Then
					rispVar = replace(rispVar,"{","")
					rispVar = replace(rispVar,"}","")
					rispVar = ";" & rispVar & ";"
					if inStr(rispVar, ";" & rispCalc & ";") = 0 Then
						result = False
					end if
				else						
					If uCase(rispCalc) <> uCase(rispVar) Then
						result = False
					End If
				end if
			Else
				if instr(rispVar, "{") > 0 Then
					rispVar = replace(rispVar,"{","")
					rispVar = replace(rispVar,"}","")
					resValVar = false
					for each valVar in split(rispVar,";")
						fakeVal = uCase(codVar) & "=" & uCase(valVar)
						if instr(strArg, ";" & uCase(fakeVal) & ";") > 0 Then
							resValVar = true
						end if
					next
					
					if not resValVar then
						result = False
					end if

				else				
					If inStr(uCase(strArg), ";" & uCase(variante) & ";") = 0 Then
						result = False
					End If

				End if
			End If				
		Next
		
		If result Then
			checkVarianti = arrVarianti(1)
		End If
	Next

```

**Grazie** per la collaborazione, stasera approfondisco.  
per il momento ho da sbattermi con gli **IF**

---

<div class="post-metadata">

**Author:** ![cotestatnt](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cotestatnt/32/238781_2.png) [@cotestatnt](https://forum.arduino.cc/u/cotestatnt)\
**Post date:** [January 13, 2025, 2:50pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/13 "2025-01-13T14:50:09Z")

</div>

A me invece viene ogni volta che vedo un listato Visual Basic 🤣

Comunque scherzi a parte, il problema di base quando si è agli inizi è che non si elaborano gli algoritmi in modo "modulare" separando il codice in "funzioni" le quali aiutano a suddividere un programma complesso in parti più piccole e gestibili (moduli) migliorando l'organizzazione, la leggibilità e la manutenzione del codice.

---

<div class="post-metadata">

**Author:** ![Maurotec](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/maurotec/32/213982_2.png) [@Maurotec](https://forum.arduino.cc/u/Maurotec)\
**Post date:** [January 13, 2025, 3:21pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/14 "2025-01-13T15:21:09Z")

</div>

Ma non mi dire, anche io provo nausea con annidamenti di profondità simile e non c'è linguaggio che tenga. Quando incontro codice simile, alle volte mi chiedo quanto tempo ci ha messo per farlo funzionare? Io di sicuro non riesco a farlo funzionare se lo devo scrivere così annidato, ma considera che c'è di peggio, cioè quando l'annidamento si estende per diverse pagine. Io con i miei due neuroni non c'è la posso fare. 😃

Quindi scompongo il problema in pezzi e affronto un pezzo per volta, testo il pezzo di codice nella funzione e se si comporta come previsto passo all'altro pezzo, in sostanza tendo a fare dei puzzle, come sintetizzato da @cotestatnt .

> [@cotestatnt](#):
>
> eseguite con una certa criticità e non son sicuro che questo blocco di codice venga eseguito correttamente all'interno di una ISR.

Si, ok, ad intuito dovrebbe funzionare, male perché la ISR si prende più tempo del necessario a causa delle temporizzazioni bloccanti per il loop(). Sempre ad intuito IRAM\_ATTR serve a spostare la ISR da flash alla ram oltre a marcare la funzione, puoi confermare?  
Ma purtroppo l'intuito non basta, serve provare e verificare cosa accade nel dettaglio e che ESP-32 e la sua SDK sono complesse e non basta qualche ora per venirne a capo.

Dalla doc ufficiale su IRAM\_ATTR:  
[https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/memory-types.html#how-to-place-code-in-iram](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/memory-types.html#how-to-place-code-in-iram)

Ciao.

---

<div class="post-metadata">

**Author:** ![mauro\_bellucci](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/mauro_bellucci/32/1127009_2.png) [@mauro\_bellucci](https://forum.arduino.cc/u/mauro_bellucci)\
**Post date:** [January 17, 2025, 8:50pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/15 "2025-01-17T20:50:04Z")

</div>

Buonasera, ho fatto centinaia di prove e sinceramente mi sta venendo il dubbio che ci sia qualcosa che non va nella libreria "DallasTemperature".

Ho riscritto lo sketch

```arduino
#include <OneWire.h>
#include <DallasTemperature.h>

// GPIO where the DS18B20 is connected to
const int oneWireBus = 4; 

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);

// Pass our oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);

struct rdTemp
{
  String sndMac;
  float temp ;
};

hw_timer_t *timer = NULL;
void ARDUINO_ISR_ATTR onTimer()
{
  Serial.print("Interrupt ...");
  rdTemp dati = readTemp();

  Serial.print(dati.sndMac);
  Serial.print(" -> ");
  Serial.print(dati.temp);
  Serial.print("°");
  Serial.println();
}

rdTemp readTemp()
{
 float temperatureC = 0 ;
  DeviceAddress mac ; 
  sensors.getAddress(mac, 0);
  sensors.requestTemperatures(); 
  // temperatureC = sensors.getTempCByIndex(0);

  String wMac = decodMac(mac); 
  rdTemp x ={ wMac, temperatureC };
  return x;
}

String decodMac(DeviceAddress baAddr)
{
    String wMac = "" ;
    String sep = "" ;
    for (uint8_t ii = 0; ii < 8; ii++) 
    {
      String mc = "00" + String(baAddr[ii], HEX) ;  
      int l = mc.length() ;
      mc = mc.substring(l -2,l); 
      wMac += sep + mc ;
      sep = ":" ;
    }
    return wMac ;
}

void setup()
{
  Serial.begin(115200);
  sensors.begin();
  delay(100);

  timer = timerBegin(1000000);
  timerAttachInterrupt(timer, onTimer);
  timerAlarm(timer, 5000000, true, 0);

}

void loop()
 {

}

```

nella funzione readTemp

leggo il MAC della sonda collegata, che funziona ripetutamente,  
come anche la riga successiva  
con requestTemperatures()  
Mentre  
// temperatureC = sensors.getTempCByIndex(0);

che ho commentato, funziona solo la prima volta.

Oltre questo ho scritto un successivo sketch dove mio malgrado ho abbandonato l'idea degli interrupt e ho utilizzato gli " **IF**" visto che "switch" è ben diverso da quello di PHP con cui ho più affiatamento.

Qui ho gestito comunque chiamate ad intervalli diversi.  
Mi dite cosa ne pensate se ci sono alternative più performanti?

```arduino
#include <OneWire.h>
#include <DallasTemperature.h>

// GPIO where the DS18B20 is connected to
const int oneWireBus = 4; 
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);

    struct rdTemp
    {
      String sndMac;
      float temp ;
    };

    unsigned long mllsTime;
    unsigned long bitTime = 0 ;
    unsigned long intervall = 1 ;
    unsigned long lastTime1 = 0 ; 
    unsigned long lastTime2 = 0 ; 

    void setup() 
    {
      Serial.begin(9600);
      sensors.begin();
    }

    void loop() 
    {
      mllsTime = millis() ;
      bitTime = int((mllsTime) / (intervall * 1000)) ; 
      
      if(int(bitTime / 1) * 1 != lastTime1)
        {
          lastTime1 = int(bitTime / 1) * 1 ; // per comatibilità con gli altri blocchi
          Serial.println("interval 1 : "); 
          rdTemp dati = readTemp();
          outputTemp(dati);  

        }
          
      if( int(bitTime / 2) * 2 != lastTime2 )
        {
          lastTime2 = int(bitTime / 2) * 2 ; 
          Serial.println("interval 2 : "); 
        }
    }

    rdTemp readTemp()
    {
      DeviceAddress mac; 
      sensors.getAddress(mac, 0);
      sensors.requestTemperatures(); 
      float temperatureC = sensors.getTempC(mac);
      String wMac = decodMac(mac); 
      rdTemp x = {wMac, temperatureC};
      return x;
    }

    String decodMac(DeviceAddress baAddr)
    {
      String wMac = "" ;
      String sep = "" ;
      for (uint8_t ii = 0; ii < 8; ii++) 
      {
        String mc = "00" + String(baAddr[ii], HEX) ;  
        int l = mc.length() ;
        mc = mc.substring(l -2,l); 
        wMac += sep + mc ;
        sep = ":" ;
      }
      return wMac ;
    }

    void outputTemp(rdTemp dati)
    {
      Serial.print(dati.sndMac);
      Serial.print(" -> ");
      Serial.print(dati.temp);
      Serial.print("°");
      Serial.println();
    }

```

---

<div class="post-metadata">

**Author:** ![Maurotec](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/maurotec/32/213982_2.png) [@Maurotec](https://forum.arduino.cc/u/Maurotec)\
**Post date:** [January 17, 2025, 10:41pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/16 "2025-01-17T22:41:48Z")

</div>

I linguaggi che conosci sono ben diversi da C++.  
Stai usando variabili locali che cessano di esistere quando la funzione termina.

```arduino
float temperatureC
rdTemp x

```

Sono variabili che esistono solo dentro la funzione `readTemp()`.  
Dichiarale globali, ad esempio `oneWireBus` è una variabile globale accessibile da ogni funzione.

Ciao.

---

<div class="post-metadata">

**Author:** ![mauro\_bellucci](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/mauro_bellucci/32/1127009_2.png) [@mauro\_bellucci](https://forum.arduino.cc/u/mauro_bellucci)\
**Post date:** [January 18, 2025, 8:57am UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/17 "2025-01-18T08:57:35Z")

</div>

Ciao Maurotec  
perdonami, ma le variabili per come le ho strutturate funzionano.  
il valori memorizzati nella struct rdTemp vengono restituiti regolarmente.  
Ciò che fa saltare la procedura è la chiamata alla libreria dallasTemterature getTempCByIndex(0), che stranamente funziona solo al primo ciclo.  
In ogni caso grazie per avermi incuriosito con "&" in un commento, ho imparato l'uso dei puntatori.

---

<div class="post-metadata">

**Author:** ![cotestatnt](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cotestatnt/32/238781_2.png) [@cotestatnt](https://forum.arduino.cc/u/cotestatnt)\
**Post date:** [January 18, 2025, 12:11pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/18 "2025-01-18T12:11:17Z")

</div>

> [@mauro\_bellucci](#):
>
> ci sia qualcosa che non va nella libreria "DallasTemperature".

La libreria in questione è una delle più utilizzate da lungo tempo... ti assicuro che non c'è nulla che non va.

Secondo me piuttosto stai facendo un po' dei tentativi "a caso" senza avere ben chiaro quello che stai facendo.

> [@mauro\_bellucci](#):
>
> ```arduino
> mllsTime = millis() ;
> bitTime = int((mllsTime) / (intervall * 1000)) ; 
>       
> if(int(bitTime / 1) * 1 != lastTime1)
> {
> lastTime1 = int(bitTime / 1) * 1 ;   
> 
> ```

Ad esempio, a me sfugge la logica che c'è dietro a questo codice...  
Se è necessario solo per temporizzare le letture, mi sembra eccessivamente complesso.

Adesso hai aggiunto una struct, quindi prevedi la gestione di più sensori, oppure è solo una tra le "centinaia" di prove che hai fatto?

Secondo me devi fare qualche passo indietro, guardare con calma e attenzione gli esempi inclusi nella libreria per farti un'idea di cosa e come è possibile farlo e partire da li per sviluppare il tuo progetto.

---

<div class="post-metadata">

**Author:** ![mauro\_bellucci](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/mauro_bellucci/32/1127009_2.png) [@mauro\_bellucci](https://forum.arduino.cc/u/mauro_bellucci)\
**Post date:** [January 18, 2025, 2:07pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/19 "2025-01-18T14:07:26Z")

</div>

la struct era già nel primo sketch.  
In effetti l'idea è quella di gestire n sonde, per poi trasmettere le variazioni di temperatura ad un server (evviva linux/php) da cui estrarre un registro con le temperature giornaliere.  
il MAC formattato da decodMac() serve da chiave di ricerca frigorifero.  
Sempre nell'idea (non è ancora un progetto definito), vorrei aggiungere il controllo dell'apertura porta.  
Le diverse temporizzazioni mi servirebbero per verificare le temperature ogni bitTime  
e la verifica connessione ogni 2 o più bitTime.  
Inoltre voglio anche gestire Blynk per le notifiche.

Il codice da te evidenziato, sono d'accordo che non abbia senso, ma come scritto nel commento

```arduino
      lastTime1 = int(bitTime / 1) * 1 ; // per compatibilità con gli altri blocchi

```

serviva solo a mantenere la compatibilità con gli altri blocchi di calcolo degli intervalli.

Se hai di meglio da consigliarmi ben venga (possibilmente risparmiando sugli **IF** ).

---

<div class="post-metadata">

**Author:** ![cotestatnt](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cotestatnt/32/238781_2.png) [@cotestatnt](https://forum.arduino.cc/u/cotestatnt)\
**Post date:** [January 18, 2025, 6:19pm UTC](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904/20 "2025-01-18T18:19:58Z")

</div>

> [@mauro\_bellucci](#):
>
> di gestire n sonde

Ottima idea quella della struct, ma messa cosi "da sola" è inutile e non va bene per il tuo obiettivo: devi definire un tipo dati custom (ovvero la tua struct) e poi gestire `n` istanze di questo tipo dati.  
Stai usando un microcontrollore che ti permetterebbe di usare senza problemi vettori dinamici, map, list etc etc, ma per ora è opportuno rimanere su cose più basilari e quindi direi di usare un array di struct allocato staticamente (quindi il numero di sensori deve essere noto a priori).

Usare una stringa come chiave di ricerca, a prescindere dal linguaggio utilizzato, non è una buona idea. I sensori Dallas DS18B20 sono identificati grazie ad un **id univoco** rappresentato da un intero a 64 bit (attenzione, non si tratta di un MAC address) il quale sarebbe il tipo di chiave perfetto in un sistema multi-sensore.

La libreria usa però il tipo dati custom `typedef uint8_t DeviceAddress[8]` ovvero un array di 8 byte, per ragioni di compatibilità perché in molte piattaforme non esiste l'intero a 64 bit.  
In realtà, se i sensori rimangono sempre nella stessa posizione, si può semplicemente usare l'indice del bus che rimane costante ed è assegnato in funzione della posizione del device all'interno del bus OneWire durante il setup.

Per quanto riguarda la temporizzazione, come scritto anche altrove, io uso sempre un template del genere:

```arduino
  // Variabile locale di tipo static cosi non interferisco con eventuali altre variabili globali 
  // con lo stesso nome e posso mantenere un naming semplice e chiaro
  static uint32_t printTime; /
  if (millis() - printTime > 1000)
  {
    printTime = millis();
    etc etc
  } 

```

Un possibile esempio pratico di quello che intendo (ci sono altri mille modi possibili):

> **[3 DS18B20 - Wokwi ESP32, STM32, Arduino Simulator](https://wokwi.com/projects/420416445473504257?dark=1)**
>
> Run IoT and embedded projects in your browser: ESP32, STM32, Arduino, Pi Pico, and more. No installation required!

P.S.  
Il simulatore online ha qualche problema con i gradi centigradi.

[Next page](https://forum.arduino.cc/t/gestione-delinterrupt-software/1341904.md?page=2)
