Singole funzioni
Spiegazione
Abstract: Descrizione:
sprintf
Le stringhe in C
setTextWrap
millis
Timer
sprintf
-----------------------------------------------------------------------------o-----------------------------------------------------------------------
La riga:
sprintf(newBuf, "%02d:%02d", h, m);
è una funzione del linguaggio C (o C++) che formatta una stringa e la scrive in newBuf.
Spiegazione dettagliata:
-
sprintf: sta per "string print formatted". Funziona come printf, ma invece di stampare su schermo, scrive il risultato in una stringa (in questo caso newBuf).
-
newBuf: è un array di caratteri (una stringa C) in cui verrà scritta la stringa formattata. Deve essere stato dichiarato prima, ad esempio:
char newBuf[10];
-
"%02d:%02d": è la stringa di formato. Vediamola pezzo per pezzo:
-
%02d: stampa un intero (d) usando almeno 2 cifre, riempiendo con zeri a sinistra se necessario.
-
:: è semplicemente un carattere due punti, che separa ore e minuti.
-
Quindi, la stringa formattata sarà qualcosa tipo "08:30" o "13:05".
-
h e m: sono variabili intere che rappresentano ore e minuti.
Spiegazione del formato %02d:
-
% — indica l'inizio di una specifica di formato.
-
0 — indica che il numero deve essere riempito con zeri a sinistra se ha meno cifre del minimo specificato.
-
2 — indica la larghezza minima del campo: in questo caso, 2 cifre.
-
d — sta per intero decimale (di tipo int).
Il simbolo % viene ripetuto due volte perché ci sono due valori da stampare: le ore (h) e i minuti (m).
Esempio pratico
int h = 9; int m = 5; char newBuf[6]; // Serve spazio per 5 caratteri + terminatore '\0' sprintf(newBuf, "%02d:%02d", h, m); // newBuf ora contiene "09:05".
Attenzione a rispettare le dimensioni della stinga h e m devono avere al max 2 digit ciascuno in modo che la stringa risulti lunga 6 caratteri: 09:05'\0' (6 caratteri) altrimenti sprintif scriverebbe anche oltre il terminatore creando corruzione della memoria e conseguente crash. Se non si èè sicuri usare snprintf che taglia tutto quello che eccede la dimensione es:
snprintf(newBuf, sizeof(newBuf), "%02d:%02d", h, m);
--------------------------------------------------------------------------o-----------------------------------------------------------------------
Le stringhe in C
-----------------------------------------------------------------------------o-----------------------------------------------------------------------
-
Una stringa è un array di char terminato da un carattere nullo ('\0').
-
Non esiste un tipo nativo string. Tutto è basato su array di caratteri.
char str[] = "ciao"; // 5 byte in memoria: 'c' 'i' 'a' 'o' '\0'
La fine della stringa è indicata dal \0. È tua responsabilità assicurarti che ci sia!
Nel caso creassi un buffer più grande della stringa tipo: char s1[20] = "ciao";
Cosa fa il compilatore:
-
Crea un array di 20 caratteri
-
Inizializza i primi 5 elementi con: 'c', 'i', 'a', 'o', '\0' (terminatore di stringa)
-
I restanti 15 caratteri vengono inizializzati a zero ('\0') solo se sei in una variabile globale o statica.
Se invece è una variabile locale, il resto del buffer può contenere spazzatura (valori casuali), a meno che tu non li inizializzi.
Attenzione:
Il fatto che il buffer sia grande non cambia la "lunghezza logica" della stringa:
strlen(s1) restituisce sempre il numero di caratteri prima del '\0', quindi nel tuo caso 4.
Ma se usi sizeof(s1), ottieni la dimensione totale dell'array, cioè 20.
--------------------------------------------------------------------------o-----------------------------------------------------------------------
setTextWrap
-----------------------------------------------------------------------------o-----------------------------------------------------------------------
Il comando:
display.setTextWrap(false);
significa disattivare il ritorno a capo automatico del testo sul display OLED.
Dettaglio:
-
Quando setTextWrap(true) (impostazione predefinita), se il testo che stai stampando con display.print() supera la larghezza del display, va automaticamente a capo sulla riga successiva.
-
Quando setTextWrap(false), invece, non va a capo: il testo prosegue orizzontalmente fuori dallo schermo, tagliandosi se supera la larghezza del display.
--------------------------------------------------------------------------o-----------------------------------------------------------------------
millis
-----------------------------------------------------------------------------o-----------------------------------------------------------------------
La funzione millis() restituisce il numero di millisecondi trascorsi dall'accensione della scheda. È molto utile per gestire temporizzazioni non bloccanti, cioè che non usano delay(), permettendoti di eseguire più operazioni contemporaneamente.
Sempice esempio:
Accendere un LED ogni secondo per un secondo:
const int ledPin = 13; // LED collegato al pin 13 (oppure cambia con il tuo)
unsigned long previousMillis = 0;
const long interval = 1000; // 1 secondo = 1000 millisecondi
bool ledState = false; // Stato attuale del LED
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
unsigned long currentMillis = millis();
// Controlla se è passato un intervallo di tempo
if (currentMillis - previousMillis >= interval) {
// Salva il momento attuale
previousMillis = currentMillis;
// Inverti lo stato del LED
ledState = !ledState;
digitalWrite(ledPin, ledState ? HIGH : LOW);
}
} |
Chiaramente non si potrà rispettatre l'intervallo in modo perfetto. Tutto dipende da quanto il loop è caricato di cose da fare, esagerando per esemplificare se currentMillis = 100 millisecondi ed ogni giro di loop dura 2000 millisecondi già dopo il primo cilcp avremo 2000 - 100 = 1900 ms è >= a 1000 si accendi il led. Il les si è acceso dopo 1900 mls e non mille, Però questo è un esempio non realistico in quanto anche se oberato di cose da fare il loop impiega normalmente pochi mls e quindi a massimo ci potrà essere una dfferenza trascurabile tra l'intervallo impostato e l'effettivo intervallo di tempo trascorso
--------------------------------------------------------------------------o-----------------------------------------------------------------------
Timer
-----------------------------------------------------------------------------o-----------------------------------------------------------------------
Se si vuole avere un intervallo perfetto puoi usare i Timer Hardware, Arduino (Uno e Nano) ne hanno 3:
✅ Timer0, Timer1 e Timer2 su Arduino Uno / Nano (ATmega328P)
Timer |
Bit |
Usato da Arduino per... |
Posso usarlo liberamente? |
Se lo uso, millis() funziona? |
Timer0 |
8-bit |
millis(), micros(), delay() |
❌ NO (riservato da Arduino) |
❌ NO, se lo tocchi |
Timer1 |
16-bit |
PWM su pin 9 e 10, usato da alcune librerie |
✅ SÌ |
✅ SÌ |
Timer2 |
8-bit |
tone(), PWM su pin 3 e 11 (a volte) |
✅ SÌ (con attenzione) |
✅ SÌ, di solito |
Puoi usare Timer2? |
Sì, ma con attenzione a… |
tone() |
❌ Usa Timer2 → evitalo se ti serve tone() |
PWM su 3 e 11 |
❌ Sarà disturbata se Timer2 viene riconfigurato |
Altre libreri |
❗ Controlla se lo usano internamente |
Se eviti tutto ciò |
✅ Nessun problema, Timer2 è tuo |
✅ Usa Timer1
Ecco perché è la scelta migliore:
Caratteristica |
Timer1 |
Bit |
16-bit → alta risoluzione |
PWM associati |
Solo pin 9 e 10 |
Usato da Arduino? |
❌ No (libero!) |
Interferisce con millis()? |
❌ No |
Interferisce con tone()? |
❌ No |
Può generare interrupt precisi? |
✅ Sì |
Supportato da librerie? |
✅ TimerOne, ecc. |
Nei Timer hardware hai solo un argomento che serve per impostare l'intervallo in microsecondi. parte da 0 quando arriva alla fine dell'intervallo scatta e torna a 0 e ricomincia a contare. Però lo devi associare ad un interrupt che eseguiràua funzione ed utilizzare la libreria <TimerOne>.
L'interrupt sono autonomi e non usano quelli classici su D2 e D3
Esempio con TimerOne (accende un LED ogni secondo con interrupt):
#include <TimerOne.h>
void setup() {
pinMode(13, OUTPUT);
Timer1.initialize(1000000); // 1.000.000 µs = 1 secondo
Timer1.attachInterrupt(blink); // chiama blink() ogni secondo
}
void blink() {
digitalWrite(13, !digitalRead(13)); // toggle LED
}
void loop() {
// Il loop può fare qualsiasi altra cosa, o anche niente
} |
--------------------------------------------------------------------------o-----------------------------------------------------------------------
|