Allenamento per l’esame di maturità
Percorso di laboratorio con Arduino per studenti di quinta ITIS
Obiettivo didattico
Organizzare il programma come scheduler cooperativo con tre task indipendenti: acquisizione analogica, lampeggio di stato e trasmissione seriale periodica. L’attività mostra come il loop() possa diventare un piccolo supervisore software.
Materiali suggeriti
- Arduino UNO R3 o UNO R4;
- 1 potenziometro;
- 2 LED;
- 2 resitori (per i LED);
- breadboard;
- cavetti jumper.
Schema di collegamento
Richiamo teorico
In un sistema embedded semplice non si usa un vero sistema operativo, ma si può costruire uno scheduler cooperativo con millis(). Ogni task possiede il proprio intervallo e il proprio istante dell’ultima esecuzione. Il loop() controlla se ciascun task è pronto e lo richiama.
Schema logico dell’attività
Il programma inizializza i timer dei tre task. Nel loop legge il tempo corrente e verifica uno dopo l’altro se è il momento di eseguire il task di acquisizione, quello di segnalazione e quello di stampa seriale. Se il tempo non è scaduto, passa al controllo successivo.
Diagramma di flusso
Diagramma di flusso Mermaid
flowchart TD
A[Inizio] --> B[Configura pin, seriale e timer]
B --> C[Leggi tempo attuale]
C --> D{Task acquisizione pronto?}
D -- Sì --> E[Esegui acquisizione]
D -- No --> F{Task LED pronto?}
E --> F
F -- Sì --> G[Commuta LED di stato]
F -- No --> H{Task seriale pronto?}
G --> H
H -- Sì --> I[Invia dati in seriale]
H -- No --> J[Ritorna al loop]
I --> J
J --> C
Programma
/*
Prof. Maffucci Michele
Esercizio 3: scheduler cooperativo con tre task indipendenti
*/
const int PIN_SENSORE = A0;
const int PIN_LED_STATO = 8;
const int PIN_LED_SOGLIA = 9;
// ---------------------------
// Intervalli dei tre task
// ---------------------------
const unsigned long PERIODO_ACQUISIZIONE = 50;
const unsigned long PERIODO_LED = 300;
const unsigned long PERIODO_SERIALE = 500;
// ---------------------------
// Istanti ultima esecuzione
// ---------------------------
unsigned long ultimoTaskAcquisizione = 0;
unsigned long ultimoTaskLed = 0;
unsigned long ultimoTaskSeriale = 0;
// ---------------------------
// Variabili condivise
// ---------------------------
int valoreGrezzo = 0;
float tensione = 0.0;
bool statoLed = false;
void setup() {
pinMode(PIN_LED_STATO, OUTPUT);
pinMode(PIN_LED_SOGLIA, OUTPUT);
Serial.begin(9600);
}
void loop() {
// Il loop assume il ruolo di piccolo scheduler.
unsigned long adesso = millis();
// ---------------------------
// Task 1: acquisizione
// ---------------------------
if ((adesso - ultimoTaskAcquisizione) >= PERIODO_ACQUISIZIONE) {
ultimoTaskAcquisizione = adesso;
taskAcquisizione();
}
// ---------------------------
// Task 2: LED di stato
// ---------------------------
if ((adesso - ultimoTaskLed) >= PERIODO_LED) {
ultimoTaskLed = adesso;
taskLed();
}
// ---------------------------
// Task 3: seriale
// ---------------------------
if ((adesso - ultimoTaskSeriale) >= PERIODO_SERIALE) {
ultimoTaskSeriale = adesso;
taskSeriale();
}
}
// ----------------------------------------------------------
// Legge il sensore e calcola una tensione equivalente.
// ----------------------------------------------------------
void taskAcquisizione() {
valoreGrezzo = analogRead(PIN_SENSORE);
// Conversione esplicita ADC -> tensione.
tensione = (valoreGrezzo * 5.0) / 1023.0;
// Uso della misura per attivare un LED di soglia.
if (tensione >= 2.50) {
digitalWrite(PIN_LED_SOGLIA, HIGH);
} else {
digitalWrite(PIN_LED_SOGLIA, LOW);
}
}
// ----------------------------------------------------------
// Task di segnalazione periodica.
// ----------------------------------------------------------
void taskLed() {
if (statoLed == false) {
statoLed = true;
digitalWrite(PIN_LED_STATO, HIGH);
} else {
statoLed = false;
digitalWrite(PIN_LED_STATO, LOW);
}
}
// ----------------------------------------------------------
// Task di comunicazione seriale.
// ----------------------------------------------------------
void taskSeriale() {
Serial.print("ADC = ");
Serial.print(valoreGrezzo);
Serial.print(" Tensione = ");
Serial.print(tensione, 2);
Serial.println(" V");
}














