Interrupt: collegamento partitore di tensione per la misura dei volt ad un pin digitale

Ciao a tutti,
non sto trovando in rete come collegare a livello hardware un partitore di tensione(questo) ad un pin per attivare poi un'interrupt su arduino mega.

al momento verifico il tutto collegando l'alimentazione ai morsetti a vite della schedina e poi "S" ad un pin analogico e gnd al gnd di arduino e misuro i Volt dell'alimentazione... vorrei poi far fare qualcosa ad arduino al variare di questo voltaggio attivando appunto un'interrupt... ma come collego il tutto ad un pin digitale se nel frattempo lho collegato ad un pin analogico? :slight_smile:

Certo che potevano metterci un condensatore su quella schedina.

Sai bene che il valore letto da analogRead() va da 0÷1023 e che è instabile per natura. Tu vorresti che leggendo in sequenza 800, 801 si sollevasse una interruzione. Questa funzione non c'è, non è possibile agganciare un interrupt su ADC in questo modo.

Gli interrupt su ADC si possono abilitare ma una interruzione viene sollevata quando il convertitore ADC ha portato a termine la conversione.

Al posto di sollevare una interruzione perché non provi con le due variabili da confrontare.
Esempio:

uint16_t a0Value;
uint16_t a0OldValue = 1024;

void loop () {
    a0Value = analogRead(A0);
    if (a0Value != a0OldValue) {
        a0OldValue = a0Value;
        Serial.println(a0Value);
    }


}

Ciao.

Sto provando a far salvare su eeprom dei dati utilizzando un super consensatore per ritardare lo spegnimento di arduino quel tanto che basta per permettere tramite quella schedina di rilevare il calo di tensione e quindi salvare. Vorrei essere sicuro, dato che ho un loop lungo, di salvare ogni volta e nn beccarma la sfiga do un salvataggio mancato...

Atmel328P datasheet ... capitolo 22 ... pagina 202 ...
... buono studio :slight_smile:

Guglielmo

Ok allora ti serve proprio un interrupt. Che MCU monta la scheda in questione?

Se monta il 328, c'è il comparatore analogico che quando commuta può sollevare un interruzione. In sostanza non usi più analogRead() ma qualche resistore esterno per fissare la soglia in cui scatta il comparatore.

Ciao.

... mi correggo vedo che usi ATmega2560 ... datasheet ... capitolo 25, pagina 265 :wink:

Guglielmo

So che in questo thread sono il meno competente... Ma provo lo stesso a dire la mia...
Quanto è lungo il loop?
Quanto consuma il tutto?
Io ho fatto la stessa cosa senza interrupt e con un normale condensatore da 1000uF... E senza quel sensore ma con un normale partitore di tensione.
Ad ogni giro di loop leggo la tensione dal partitore su un pin analogico e se il valore è sotto una certa soglia salvo in eeprom.

1 Like

... già in un'altro thread (dove viene usato lo stesso sensore) ponevo la domanda ... ma a che diavolo serve l'alimentazione su un partitore di tensione? :open_mouth: :open_mouth: :open_mouth:

Questi "sensori" altro non sono che volgari partitori di tensione con due resistenze e un rapporto 1/5 (alcune recensioni, su Amazon, dicono che invece il rapporto è 1/6.5 ... il che già la dice lunga sulla qualità e precisione delle resitenze montate) ...

... ora, va bene l'ingresso da una parte (GND e VCC), va bene il '-' e l'uscita ('S') dall'altra, ma ... il '+', perché cavolo uno dovrebbe portarlo?

Mah ... :roll_eyes:

Guglielmo

Forse pensano di portare l'alimentazione sui morsetti e dall'altro lato prelevare l'alimentazione e l'uscita del partitore...
Comunque, quasi 10€ per ciò che si può fare con pochi centesimi per due resistenze è mostruoso!

1 Like

... credo di aver appurato altrove che il pin '+' è un pin ... N.C. :joy: :joy: :joy:

L'ipotesi più comune è che, chi lo ha fatto la prima volta, abbia prodotto magari un kit di sensori e che tutti siano dotati dello stesso connettore a 3 pin ... così da non creare dubbi nei novizi :wink:

Concordo al 100% ... una delle tante assurdità ... :roll_eyes:

Guglielmo

Nn so se monta il 328....come lo verifico?

inoltre quali resistenze usare e quale schema se voglio farmelo da solo?

partitore

Banalmente rp è il rapporto di partizione calcolato così:

rp = R2 / (R1 + R2)
rp = 7500 / (30000 + 7500) = 0.2
Quindi se entrano 25V moltiplicati per rp fa 25 x 0.2 = 5

Io non ho capito in quale scheda arduino vuoi che scatti un interrupt.
Se è la Mega essa monta la MCU 2560. Mentre la UNO o nano montano il 328,
La sigla corretta dovrebbe essere ATmega2560 o ATmega328.

Nel datasheet della MCU c'è scritto a quali pin è collegato il comparatore analogico, ad esempio PD6 e PD7 sono gli ingressi del comparatore nel 328.

ho un arduino mega.... quindi niente 328.... consigli su come fare con un loop mooolto lungo?

lato partitore quindi, stabilisco il mio voltaggio di entrata al partitore, che poi sarebbe quallo di Arduino(circa 9v) e mi calcolo le due resistenze... l'uscita di V dal partitore deve essere 5V spaccato?

perchè ad esempio con due resistenze da 12k e in ingresso 9v ottengo in uscita 4,5v... potrebbe andar bene?

Guglielmo si è corretto nel messaggio n.6 e ha pubblicato il collegamento al datasheet.

Con que resistenze uguali ottieni metà tensione, quindi 4,5V con 9V all'ingresso. L'importante è che la tensione all'uscita del partitore non superi mai la tensione di alimentazione del microcontrollore. A quanto è alimentato il 2560 del Mega? 5V, mi sembra.

Comunque, con la piccola corrente che scorre con due resistenze da oltre 10k la tensione all'uscita del partitore verrebbe tosata dai diodi di protezione sugli ingressi del microcontrollore e l'unico problema sarebbe non riuscire a leggere tensioni maggiori di 6,6V.

Sul Mega, però, puoi selezionare il riferimento interno a 1,1V o quello a 2,56V: nel primo caso, per leggere una tensione di 9V devi fare un partitore 9:1 (9,9V f.s.) con due resistenze con un rapporto 8:1 (per esempio 12k e 1k5); nel secondo caso, devi fare un partitore 4:1 (10,24v F.S.) con due resistenze con un rapporto 3:1 (per esempio 10k e 3k3).

Non lo so questo lo devi stabilire tu. Se vuoi tentare di usare il comparatore analogico allora rp = 1.1 / 9 = 0.12. Questo a causa del fatto che il pin AIN0 non è accessibile dai connettori della scheda. Quindi non resta altra possibilità da codice di collegare AIN0 al riferimento interno a 1.1V. L'altro ingresso del comparatore AIN1 è su pin 5.

Mentre da 9V a 5V rp = 5/9 = 0.55, da questo ricavi R1 + R2 imponendo a R2 = 10k
rp = 10000 / 0.55 = 18181,81. Ottieni R1 = 18181.81 - 10000 = 8181,81 (8.2k)

Per riprova ricalcoli rp = 10000 / (10000 + 8200) = 0,549

Siamo molto vicini.

Valori diversi di R1 e R2 possono essere ottenuti da più resistenze in parallelo.
Trovi online come calcolare Rtot da resistenze in parallelo. Se non lo trovi chiedi che ti sarà dato.

Chi ha la mega è vuole sperimentare ANALOG_COMP_vect si faccia avanti. La fregatura è che non possiamo imporre isteresi al comparatore interno.

Ciao.

grazie, me lo ero perso...
me lo sono letto e in parte anche compreso, ma ora come lo metto in pratica... esempi pratici da dove iniziare?

Non lo so questo lo devi stabilire tu

in che senso?

Mentre da 9V a 5V rp = 5/9 = 0.55, da questo ricavi R1 + R2 imponendo a R2 = 10k
rp = 10000 / 0.55 = 18181,81. Ottieni R1 = 18181.81 - 10000 = 8181,81 (8.2k)

ok quindi mi hai gentilmente detto che valori di resistenza utilizzare, grazie

Chi ha la mega è vuole sperimentare ANALOG_COMP_vect

io sono interessato, ma non ne sono in grado senza esempi pratici o supporto...

cercando in rete ho trovato questo

di quel link non ho capito questa parte: quali pin devo impostare ak posto di (AIN+, AIN-);? nel mio caso collego l'uscita "S" del partitore ad A0 e gnd a GND di arduino...

Per scegliere gli ingressi del comparatore analogico si usa il metodo setOn():

analogComparator.setOn(AIN+, AIN-);

Le scelte per AIN+ sono le seguenti:

  • AIN0: imposta il pin AIN0 come ingresso
  • INTERNAL_REFERENCE: imposta la tensione interna di riferimento come ingresso

Per AIN- potete scegliere fra le seguenti voci:

  • AIN1: imposta il pin AIN1 come ingresso
  • A0…Ax: imposta uno specifico ingresso analogico (il valore massimo dipende dal tipo di microcontrollore, se superato viene scelto il pin A0)

Ora che ci penso il problema principale è sempre il loop che dura tanto.
Cioè ammesso di attivare l'interrupt cosa fai, mica puoi scrivere in eeprom dentro la routine dell'interrupt. Non lo puoi fare perché gli interrupt globali risultano disabiliti e la eeprom necessità degli interrupt globali abilitati.

Allora pensi, alzo una variabile ad HIGH quando la routine di interrupt viene chiamata e poi nel loop usa una if (variabile == HIGH) salva. Però se il loop è lungo e ci impiega 1 secondo per ricominciare siamo al punto di partenza.

In verità ho fatto un esempio in modo che tu possa calcolarti in futuro qualunque
partitore; Come dire gli do delle dritte per pescare il pesce invece di pescarglielo io.

Ciao.

Umh... quindi niente interrupt.... :frowning:

A costo di sembrare noioso... Ma quanto dura il loop?
E quanto consuma tutto il circuito?
Magari ottimizzando il loop si riesce a fare tutto senza interrupt e compagnia cantando.