Pages: [1] 2 3 ... 6   Go Down
Author Topic: analogComp, una libreria per gestire il comparatore analogico  (Read 9101 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Oggi vi presento analogComp, una libreria che potete usare per gestire il comparatore analogico integrato nei microcontrollori Atmel. Un comparatore analogico è sostanzialmente un amplificatore operazionale utilizzato in modalità comparatore di tensione che imposta su High la sua uscita quando la tensione presente sull’ingresso non invertente supera quella presente sull’ingresso invertente. Gli ingressi possono essere due pin esterni ai quali far pervenire le tensioni da comparare.

La libreria, che supporta una buona quantità di chip, permette sia di gestire una singola comparazione sia di richiamare una funzione tramite un interrupt ogni qual volta si manifesta una particolare condizione.

Metodi ed utilizzo

Come al solito, scaricate il pacchetto presente nell’articolo linkato info a questo post e scompattatelo, fatto questo copiate la cartella /analogComp che avete ottenuto all’interno della cartella /libraries contenuta nella vostra cartella degli sketch.

Per poter utilizzare la libreria, dovete prima includerla con

Code:
#include "analogComp.h"

Adesso potete impostare ciò che deve essere connesso agli ingressi invertente (AIN-) e non invertente (AIN+) del comparatore analogico. Generalmente, AIN+ è connesso al piedino AIN0 ed AIN- è connesso al piedino AIN1. Per sapere a quali pin corrispondono AIN0 e AIN1 fate riferimento alla mappatura dei pin del microcontrollore in uso. Per l'Atmega328, quindi per l'Arduino UNO, il pin AIN0 è il pin D6 mentre AIN1 è il pin D7.AIN+ può essere anche connesso alla tensione di riferimento interna (1,1V) mentre AIN- può anche essere connesso ad uno degli ingressi analogici del microcontrollore (vedi “Microcontrollori supportati” per alcune limitazioni specifiche).

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

Code:
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)

AIN+ e AIN- sono opzionali, nel caso in cui non fossero passati verranno selezionati AIN0 e AIN1.

Si può attivare un interrupt in modo che esso esegua una routine al verificarsi di un evento:

Code:
analogComparator.enableInterrupt(miaFunzione[, evento]);

miaFunzione è la funzione che deve essere chiamata quando si verifica l’evento. evento può essere:

  • CHANGE: quando la comparazione cambia fra AIN+>AIN- e AIN+<AIN-
  • RISING: quando la tensione su AIN+ diventa maggiore di quella su AIN-
  • FALLING: quando la tensione su AIN+ diventa minore di quella su AIN-

evento è opzionale, se non è specificato viene scelto CHANGE di default.

Si può anche disabilitare un interrupt precedentemente attivato:

Code:
analogComparator.disableInterrupt();

Si può anche attendere per un certo tempo che si verifichi la condizione che AIN+ diventi maggiore di AIN-:

Code:
analogComparator.waitComp([timeout]);

timeout è opzionale e rappresenta il numero di millisecondi da aspettare prima di ritornare al punto di chiamata (il valore di default è 5000). Questo metodo restituisce false (0) se la tensione su AIN- rimane maggiore di quella presente su AIN+ per tutto il periodo indicato da timeout; restituisce true (1) se AIN+ diventa maggiore di AIN- durante l’intervallo specificato.

Se il comparatore analogico non è stato impostato prima di chiamare il metodo waitComp, di default la liberia imposta come ingressi AIN0 e AIN1.

Per spengere il comparatore analogico e disattivare l’eventuale interrupt basta chiamare il metodo setOff():

Code:
analogComparator.setOff();

Microcontrollori supportati

Attualmente la libreria lavora con una buona quantità di microcontrollori Atmel e schede Arduino:
  • Attiny2313/4313
  • Attiny24/44/84
  • Attiny25/45/85
  • Atmega344/644/1284
  • Atmega8
  • Atmega48/88/168/328 (Arduino UNO)
  • Atmega640/1280/1281/2560/2561 (Arduino MEGA)
  • Atmega32U4* (Arduino Leonardo)
*il supporto di alcuni di essi è solo "su carta", vanno materialmente provati

Limitazioni specifiche

  • Attiny2313/4313: a causa del fatto che queste MCU non hanno un ADC integrato, per AIN- è possibile selezionare solo AIN1
  • Atmega32U4: l’AIN- dell’Atmega32U4 può essere connesso solo ad un ingresso analogico a causa del fatto che esso non ha un pin AIN1.

L'articolo aggiornato e l'ultima versione della libreria è disponibile qui:
http://www.leonardomiliani.com/?p=630

Si attendono commenti, critiche e scoperte di bug  smiley-wink
« Last Edit: November 03, 2012, 04:52:12 pm by leo72 » Logged


Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 519
Posts: 12322
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ottimo Leo, come sempre, se dovesse servire questa specifica funzione in un circuito si risparmia un operazionale. Domanda: qual'è la tensione minima applicabile ad AIN+?
Sto lavorando con segnali che spaziano tra 100 e 600mV, ma che in alcuni casi possono arrivare a 5V; secondo te posso applicare una tensione di 90mV su AIN+ ed impostare come azione che un pin vada su HIGH ogni volta che su AIN- ho un valore >=100mV?
Logged

Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10449
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
analogComparato.setOff();
typo?
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@Mike:
Il datasheet riporta pochi dati, ma penso che il range sia comunque quello dell'Atmega, ossia 0-5V. Il datasheet poi riporta la tensione di offset (10 mV).
Sul fatto di poter attivare un led non ci sono problemi, l'esempio allegato fa proprio questo.

@lesto:
sì, manca una "r", ora la aggiungo  smiley-sweat
Logged


Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 519
Posts: 12322
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@Mike:
Il datasheet riporta pochi dati, ma penso che il range sia comunque quello dell'Atmega, ossia 0-5V. Il datasheet poi riporta la tensione di offset (10 mV).
Sul fatto di poter attivare un led non ci sono problemi, l'esempio allegato fa proprio questo.
io non ho parlato di LED, non mi serve, comunque ok smiley-grin
Logged

Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

io non ho parlato di LED, non mi serve, comunque ok smiley-grin
Scusa, stavo pensando all'esempio che ti citavo, che accende un led per un istante. Ovviamente equivale a mettere High un pin  smiley-wink
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Qualcuno l'ha provata?  smiley-sweat
Logged


0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5790
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Test1:
Non superato
Compatibilita' dichiarata con Atmega8 non superata.

Protocollo di test:
Win7-64bit
IDE: Arduino 1.0.1
Board: Arduino NG (board ufficiale presente in Tools-Board)

Argomentazioni:
Non e' necessario avere fisicamente la board in questione in quanto l'errore appare in fase di compilazione.
Code:
D:\arduino-1.0.1\libraries\analogComp\analogComp.cpp: In member function 'uint8_t analogComp::setOn(uint8_t, uint8_t)':
D:\arduino-1.0.1\libraries\analogComp\analogComp.cpp:52: error: 'ADCSRB' was not declared in this scope
D:\arduino-1.0.1\libraries\analogComp\analogComp.cpp:54: error: 'ADCSRB' was not declared in this scope
D:\arduino-1.0.1\libraries\analogComp\analogComp.cpp:56: error: 'DIDR1' was not declared in this scope
D:\arduino-1.0.1\libraries\analogComp\analogComp.cpp:56: error: 'AIN1D' was not declared in this scope
D:\arduino-1.0.1\libraries\analogComp\analogComp.cpp:56: error: 'AIN0D' was not declared in this scope
D:\arduino-1.0.1\libraries\analogComp\analogComp.cpp: In member function 'void analogComp::setOff()':
D:\arduino-1.0.1\libraries\analogComp\analogComp.cpp:109: error: 'DIDR1' was not declared in this scope
D:\arduino-1.0.1\libraries\analogComp\analogComp.cpp:109: error: 'AIN1D' was not declared in this scope
D:\arduino-1.0.1\libraries\analogComp\analogComp.cpp:109: error: 'AIN0D' was not declared in this scope
D:\arduino-1.0.1\libraries\analogComp\analogComp.cpp:110: error: 'ADCSRB' was not declared in this scope


Si procedera' a test reali su Atmega8A successivamente

Tanto era dovuto,
porgo distinti saluti.


« Last Edit: November 04, 2012, 05:55:33 am by Testato » Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 519
Posts: 12322
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

minc, sembri uno delle Poste e Telegrafi smiley-yell
Leuccio, sono alle prese con un migliaio di prove da fare al laboratorio, se riesco ad arrivare a milleuna ci metto pure la tua lib; se vuoi agevolarmi preparami un mini-sketch semplice semplice con cui io possa applicare ad un pin una tensione di riferimento fissa, all'altro pin il segnale variabile e sul terzo pin possa tirare fuori una bella onda quadra a 5V costruita così: la parte LOW quando il segnale di misura è sotto livello, la parte HIGH quando il segnale di misura è sopra livello.
Per le prove userò Arduino, alle 14 vado al lab ed inizio le altre prove importanti, ma tengo sott'occhio il Forum, se riesci a scrivermi le righe vedo di buttarle su Arduino e provarle al volo smiley-sweat
Scusa, non è per pappa pronta, anche perché sei stato chiarissimo, come sempre, nella spiegazione, ma è proprio che non ho un secondo di tempo. In cambio ti posto le foto del DSO smiley-wink
Logged

Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Tanto era dovuto,
porgo distinti saluti.

La ringraziamo per il Suo interessamento al nostro prodotto e, nel salutarLa, Le porgiamo i nostri più Distinti Saluti.

Leonardo Miliani
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

minc, sembri uno delle Poste e Telegrafi smiley-yell
Leuccio, sono alle prese con un migliaio di prove da fare al laboratorio, se riesco ad arrivare a milleuna ci metto pure la tua lib; se vuoi agevolarmi preparami un mini-sketch semplice semplice con cui io possa applicare ad un pin una tensione di riferimento fissa, all'altro pin il segnale variabile e sul terzo pin possa tirare fuori una bella onda quadra a 5V costruita così: la parte LOW quando il segnale di misura è sotto livello, la parte HIGH quando il segnale di misura è sopra livello.
Per le prove userò Arduino, alle 14 vado al lab ed inizio le altre prove importanti, ma tengo sott'occhio il Forum, se riesci a scrivermi le righe vedo di buttarle su Arduino e provarle al volo smiley-sweat
Scusa, non è per pappa pronta, anche perché sei stato chiarissimo, come sempre, nella spiegazione, ma è proprio che non ho un secondo di tempo. In cambio ti posto le foto del DSO smiley-wink
Prima di passarti il codice vorrei chiarirti però che si può agganciare 1 solo interrupt al comparatore analogico per cui si può misurare un solo evento, CHANGE, RISING o FALLING. Quindi quando la situazione tra AIN+ e AIN- cambia (sia che AIN+ diventi maggiore di AIN- che viceversa), che AIN+ diventi maggiore di AIN- oppure che AIN+ diventi minore di AIN-.
Quindi per far accendere un led a seconda che AIN+ sia maggiore o minore di AIN- servirebbero 2 interrupt, uno per monitorare l'evento RISING ed uno per monitorare l'evento FALLING.
Si può provare ad ovviare usando l'evento CHANGE, cambiando di stato ad una variabile ogni volta che la comparazione fra i 2 ingressi cambia.

Code:
#include "analogComp.h"

const byte OUTPUT_PIN = 9;
byte pinSignal = 0;

void setup() {
    pinMode(OUTPUT_PIN, OUTPUT);
    analogComparator.setOn(AIN0, AIN1); //metti su D7 la tensione di riferimento e su D6 la tensione da comparare
    analogComparator.enableInterrupt(changeStatus, CHANGE);
}

void loop() {
    digitalWrite(OUTPUT_PIN, pinSignal);
    delay(200);
}

//interrupt
void changeStatus() {
    pinSignal ^= 1;
}
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@Testato:
ho aggiornato la lib, la versione 1.0.1 compila senza errori su Atmega8 (Arduino NG)
http://www.leonardomiliani.com/?p=630
Logged


0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5790
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

cosi' presto ?
diavolo, ora devo per forza fare l'altro test promesso  smiley-yell
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

cosi' presto ?
diavolo, ora devo per forza fare l'altro test promesso  smiley-yell

smiley-razz

Ho anche perso tempo perché la toolchain aggiornata che sto usando mi ha sollevato un errore su alcune costanti di vettori di interrupt deprecati che ci sono nel file HardwareSerial.cpp e che ho dovuto sistemare prima di poter sistemare poi gli errori che mi avevi segnalato  smiley-sweat
Logged


Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 519
Posts: 12322
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Io devo fare un test di sostituzione del tipico op amp usato come squadratore, quindi ad un ingresso metto la tensione di soglia, all'altro applico un segnale sinusoidale a frequenza ed ampiezza variabile, mi aspetto sull'uscita un bel segnale digitale a 5V, non è questo che fa la tua libreria?
Logged

Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

Pages: [1] 2 3 ... 6   Go Up
Jump to: