Ciao a tutti!
Premetto che so poco di programmazione ed elettronica. Mi arrangio con quel che riesco a capire, con i limiti e i difetti che ne seguono.
Scrivo perchè ho in progetto di pilotare una valvola d'aria, in base alla temperatura rilevata da un sensore che restituisce valori in ohm, in una scala non lineare da 11600 (-10 gradi) a 300 ohm circa (100 gradi).
A questo fine, ho chiesto miseramente a ChatGPT di prepararmi un codice per programmare arduino, in cui il valore PWM deve decrescere da 80% a 20%, proporzionalmente ai valori di ohm rilevati dal sensore.
Ho anche chiesto di accendere un led verde quando il PWM è tra 20% e 35%, led rosso quando è superiore al 35%.
Mi sono anche fatto dare una "lista della spesa" per assemblare il tutto, ma questo attiene ai profili hardware, di cui non parlerà per non risultare Off Topic.
Vorrei un vostro parere sulla bontà di questo codice, prima di fare delle prove empiriche.
Grazie a chi avrà la pazienza di leggerlo e vorrà aiutarmi...
// --- Coefficienti Steinhart–Hart calcolati dalla tua tabella ---
const float A = 1.236208e-03;
const float B = 2.446229e-04;
const float C = 1.367672e-07;
// Definizione variabili min/max temperatura (°C)
const float tempMin = -10.0;
const float tempMax = 100.0;
// Pin e valori PWM
const int pwmPin = 5;
const int ledRedPin = 13;
const int ledGreenPin = 12;
const int analogPin = A0; // Pin analogico per lettura NTC
// Mappatura PWM (0-255) corrispondente a temperatura da -10 a 100 °C
const int PWM_min = 51; // ~20%
const int PWM_max = 204; // ~80%
// Isteresi in °C per evitare frequenti oscillazioni
const float hysteresis = 1.0;
// Variabile per tenere traccia dell’ultima temperatura letta
float lastTemp = -1000.0;
// Variabili per gestione temporale non bloccante
unsigned long previousMillis = 0;
const unsigned long interval = 200; // ms tra letture
// Parametri circuito partitore
const float R_fixed = 10000.0; // Resistenza fissa partitore (ohm)
const float V_in = 5.0; // Tensione di alimentazione (V)
// Numero di campioni per media lettura analogica
const int numSamples = 10;
void setup() {
pinMode(pwmPin, OUTPUT);
pinMode(ledRedPin, OUTPUT);
pinMode(ledGreenPin, OUTPUT);
Serial.begin(115200); // Baud rate più veloce per debug
}
// Funzione di mapping float analogo a map() ma con float e 0-255 PWM
float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
// Invertiamo la mappatura: dato PWM (0-255), ottieni temperatura
float inverseMapTemp(float pwm) {
float temp = (PWM_max - pwm) * (tempMax - tempMin) / (PWM_max - PWM_min) + tempMin;
return temp;
}
// Funzione che converte temperatura in PWM (0-255)
int tempToPWM(float temperatura) {
float pwmF = mapFloat(temperatura, tempMin, tempMax, PWM_max, PWM_min);
return constrain((int)pwmF, PWM_min, PWM_max);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
float R_ntc = leggiResistenzaSensore();
float temperatura = interpolateTemp(R_ntc);
if (abs(temperatura - lastTemp) > hysteresis) {
int pwmValue = tempToPWM(temperatura);
analogWrite(pwmPin, pwmValue);
// Gestione LED con soglia 35% duty cycle reale
int dutyCyclePercent = (int)((pwmValue / 255.0) * 100);
int thresholdPercent = 35;
if (dutyCyclePercent <= thresholdPercent) {
digitalWrite(ledRedPin, LOW);
digitalWrite(ledGreenPin, HIGH);
} else {
digitalWrite(ledRedPin, HIGH);
digitalWrite(ledGreenPin, LOW);
}
lastTemp = temperatura;
Serial.print("Temp: ");
Serial.print(temperatura, 2);
Serial.print(" °C, PWM: ");
Serial.print(pwmValue);
Serial.print(" (");
Serial.print(dutyCyclePercent);
Serial.println("%)");
}
}
}
// Conversione da resistenza a temperatura usando Steinhart–Hart
float interpolateTemp(float R) {
float logR = log(R);
float invT = A + B * logR + C * pow(logR, 3);
float T_K = 1.0 / invT;
return T_K - 273.15; // Converti da Kelvin a °C
}
// Legge resistenza NTC (media analogica)
float leggiResistenzaSensore() {
long sum = 0;
for (int i = 0; i < numSamples; i++) {
sum += analogRead(analogPin);
delay(5);
}
float avgReading = sum / (float)numSamples;
float V_out = (avgReading / 1023.0) * V_in;
if (V_out <= 0.01) return 1e6;
float R_ntc = R_fixed * (V_in / V_out - 1.0);
return R_ntc;
}
Una IA è molto utile per farsi fare dei lavori di manovalanza, o per farsi spiegare dei dettagli riguardo qualcosa che in buona parte già si conosce. In sostanza una IA mi assiste (con suggerimenti e variazioni) riguardo a un lavoro che io sto facendo, ma non fa tutto il lavoro per me. In particolare il primo codice che genera è sempre solo un'ipotesi di lavoro contenente diverse inesattezze e diversi punti lasciati "in bianco" (o inventati) in quanto attinenti a questioni hardware non ancora definite. Bisogna sempre essere in grado di comprendere la risposta fornita, per correggerla e completarla a mano, oppure per spiegare all'IA cosa c'è da correggere, e allora di solito entro una decina di interazioni e chiarimenti si riesce ad ottenere qualcosa di funzionante. Inoltre la ricchezza, completezza e precisione nel formulare la domanda incide fortemente sulla qualità della risposta.
Riassumendo,l'IA non è li per fare un lavoro al tuo posto, ma per permettere a te di fare quel lavoro in modo molto più semplice e veloce. È uno strumento che si affianca a libri, documentazione online e forum, aggiungendo molte possibilità, prima tra tutte quella di poter chiedere spiegazioni su ogni parte delle risposte precedenti (il che equivale a poter fare un corso su misura sui singoli dettagli che di volta in volta si vogliono comprendere).
La domanda rivolta a noi (sulla bontà del codice) paradossalmente sarebbe stata da rivolgere all'IA, chiedendo spiegazioni sul perché ha scritto determinate cose, quale ragionamento ha seguito ecc ecc. E per ogni ulteriore punto oscuro chiedere altre delucidazioni.
Visto che adesso è letteralmente possibile procedere in questo modo, mi sto domandando in questi giorni se grazie all'IA sia possibile apprendere la programmazione partendo dalla fine per arrivare all'inizio, cioè il contrario di come si è sempre fatto
(Ne invento uno mio, di neologismo: Quovido: condivido e quoto...)
Comunque nel caso particolare credo che la AI ci abbia preso o ci sia andata molto vicina
Adesso la parte difficile:
Capire come ha fatto e sfrondare quel "cespuglio" di funzioni tutte spinose
Fino a tirarne fuori un prato all'inglese di eleganza
Grazie per le vostre risposte! Per arrivare a questo codice ho interrogato più volte ChatGPT, chiedendogli di verificare se c'erano errori, di migliorare il codice ecc... ecc... ha modificato il codice circa 15 volte, ma alla fine è arrivato ad un punto in cui non riusciva ad effettuare più modifiche migliorative. Mi domandava proprio per questo motivo se il risultato dell'IA fosse prossimo alla perfezione. Mi sembra di capire, però, che l'occhio umano riesce sempre a cogliere qualche "intuizione" in più che l'IA ancora non riesce a cogliere...
Non si sa perché usi tante variabili float di passaggio, per giunta globali, anziché scrivere tutto di seguito, dato che mi sembra che non vengano usate altrove. Probabilmente le usa per far capire il procedimento.
// Conversione da resistenza a temperatura usando Steinhart–Hart
float interpolateTemp(float R) {
return 1.0/(A + B*log(R) + C*pow(logR,3)) - 273.15;
}
Anch'io sono dell'idea che AI nell strutturare programmi è molto utile nel training e nel learning della sintassi corretta ma visto che i programmi complessi sono opere d'arte non riuscirà mai a evitare di studiare a fondo.
Come dice sempre il buon Guglielmo.
In sintesi fa programmi da scimmia per le scimmie, le scimmie non conoscono l'arte, ne della programmazione ne in altri campi
Trovo interessante la tua osservazione sull’intelligenza artificiale come “strumento per le scimmie” e sull’arte della programmazione riservata evidentemente a pochi eletti.
Ma vedi, proprio questa idea che la programmazione sia un' “arte nobile” da preservare da strumenti di supporto – come se fossero un’eresia – è esattamente il tipo di atteggiamento che ha spesso frenato la diffusione della conoscenza.
Se oggi una persona che non viene dal mondo tecnico riesce a scrivere codice funzionante, capire come interagiscono elettronica e software, e farsi domande sensate… non è un segnale di decadenza culturale, ma di democratizzazione dell’accesso al sapere.
Nessuno ha detto che si possa delegare tutto all’IA o evitare lo studio. Ma screditare chi ci prova – dando implicitamente del primate – dice più sulla postura mentale di chi giudica che sulla qualità del codice.
L’arte non è solo nel creare, ma anche nel trasmettere, semplificare e includere. E in questo, chi usa l’intelligenza artificiale per imparare, magari ha capito qualcosa in più di chi la guarda dall’alto con sufficienza.
In sintesi, da accademico e professionista di altro settore, mi permetto di ricordare che la comunicazione socialmente civile appartiene agli uomini evoluti.
Chi non riesce a praticarla, probabilmente, appartiene allo stesso ordine delle scimmie che – a quanto pare – non conoscono nemmeno l’arte del comunicare.