Cerca

Curriculum vitae e bio dell'autore Un paio di articoli relativi al mio hobby - robotica
Le mie impressioni circa l'immigrazione in Australia. Solo in russo. Ricette per risolvere i problemi quotidiani
Linux posti legati Windows-posti legati
Software posti legati Un sacco di informazioni su hardware
Diversi strumenti che potrebbe risultare utile Messaggi su tecnologie web vari
Tutto ciò che non rientra nel resto del menu Feed RSS per questo blog

Tag Cloud

Archivio

Links

Blog di Andrey Mikhalchuk

English flagItalian flagKorean flagChinese (Simplified) flagPortuguese flagGerman flagFrench flagSpanish flagJapanese flagRussian flagDanish flagFinnish flagHebrew flag

Technoblog sulla vita

20 giu 2011 ATtiny85/45/25 lettura del sensore di temperatura interno

ATtiny85 has internal temperature sensor

ATTINY85 dispone di sensore di temperatura interna

Sto lavorando su uno dei miei progetti da video blog RTFMs (check out http://rtfms.com ) che richiede di rilevamento della temperatura in un packaging molto piccolo. Naturalmente la mia scelta è ATTINY85 - un chip impressionante poco da AVR che, oltre a altri beni (come 6 canali PWM, interfaccia seriale, ecc) ha sensore di temperatura interna. Così ho deciso di utilizzare uno. Non è stato facile, ma dopo poche ore di forum e schede tecniche di scavo mi si avvicinò con una classe che fa il lavoro di affidabilità abbastanza impressionante e precisione.


Prima di tutto per eseguire questo codice è necessario un Arduino-Tiny ( http://code.google.com/p/arduino-tiny/ ) core e un qualche tipo di ISP. Sto utilizzando Arduino Duemilanove come ISP. Vedere la mia RTFMs blog per maggiori dettagli su come farlo funzionare in questo modo, come caricare nucleo corretta ecc AFAIK tutti i core popolari funzionano bene con questo codice. Ho solo recomment Arduino-Tiny a causa della sua ricca gamma di funzionalità che può essere usato per diffondere una maggiore potenza di ATTINY85.
La soluzione si compone di due file che è possibile copiare nel progetto. Basta CopyPaste da questa pagina:

InternalTemperatureSensor.h

# Ifndef _INTERNAL_TEMPERATURE_SENSOR_H_
# Define _INTERNAL_TEMPERATURE_SENSOR_H_

# Define TEMPERATURE_SAMPLES 30
# Define TEMPERATURE_ADJUSTMENT -13
# Define EXTREMES_RATIO 5

# Define MAXINT 32767
# Define MININT -32.767

/ *
* Basato su campioni:
* - Il sensore di temperatura interno ha deviazione orribile. La sua uscita varia parecchio (+ / -10 gradi / sec), quindi richiede
* Alcuni "smoothing". Sto eliminando i valori estremi ed in esecuzione di rotolamento avg sul resto. Questa operazione riporta ok
* I risultati su 20 campioni e altro ancora. È possibile ridurre il numero di campioni per ridurre il tempo di risposta, ma questo
* Diminuirà precisione.
* - La linearità è ok e circa 1.0 come promesso la scheda tecnica
* - La necessità di spostamento che deve essere calcolato per ogni chip fornito separatamente e in c'tor
*
* Per calaculate il gancio valere come terminale al pin 2 (Serial TX) 9600 8N1 e utilizzare
* Temperature.print () chiamata al metodo. Questo stamperà letture di temperatura. Partita contro la vostra
* Calibrato termometro attaccato al chip. Regolare Tos in c'tor se necessario.
* Si veda il capitolo 17,12 del foglio dati ATTINY85 per i dettagli un po 'più
* /

class {InternalTemperatureSensor
int offset;
Coefficiente di galleggiare;
letture int [TEMPERATURE_SAMPLES];
int pos;

pubblico:
InternalTemperatureSensor (float k, int o): offset (o), coefficiente di (k), pos (0) {}
/ / È chiamata ogni volta che è necessario preparare il chip per leggere sensore (cioè nel setup)
/ / Se si sta utilizzando altre ADC oltre la temperatura si chiama prima di ogni lettura della temperatura
void init ();
/ / Restituisce la temperatura attuale mediato in LSB
int in_lsb ();
/ / Restituisce la temperatura attuale mediato in gradi Celsius
int in_c ();
/ / Restituisce la temperatura attuale mediato in gradi Fahrenheit
int in_f ();
/ / Restituisce la temperatura attuale mediato in gradi Kelvin
int in_k ();
/ / Restituisce la temperatura attuale prima lettura dal sensore
int raw ();
/ / Stampa le letture di temperatura e corrente in vari formati
annullare print ();
};
# Endif / / _INTERNAL_TEMPERATURE_SENSOR_H_

InternalTemperatureSensor.pde

# Include "InternalTemperatureSensor.h"

vuoto InternalTemperatureSensor :: init () {
/ / AnalogReference (INTERNAL1V1);
/ / ATTINY85 datasheet p140 (17.13.2), P137 (17.12)
/ / Configura ADMUX
ADMUX = B1111; / / Seleziona Sensore di temperatura
ADMUX & = ~ _BV (Adlar); / / Right-regolazione risultato
ADMUX | = _BV (REFS1), la tensione Ref / / Set
ADMUX & = ~ (_BV (REFS0) | _BV (REFS2)); / / a 1.1V
/ / Configura ADCSRA
ADCSRA & = ~ (_BV (aDate) | _BV (ADIE)); / / Disattiva AutoTrigger, Disabilita interrupt
ADCSRA | = _BV (ADEN); / / Abilita ADC
ADCSRA | = _BV (ADSC); / / Start prima conversione
/ / Seed campioni
int raw_temp;
while (((raw_temp = raw ()) <0));
for (int i = 0; i <TEMPERATURE_SAMPLES; i + +) {
letture di [i] = raw_temp;
}
}

int InternalTemperatureSensor :: in_lsb () {
int readings_dup [TEMPERATURE_SAMPLES];
int raw_temp;
/ / Ricordo del campione
if ((raw_temp = raw ())> 0) {
letture [pos] = raw_temp;
pos + +;
pos% = TEMPERATURE_SAMPLES;
}
/ / Copiare i campioni
for (int i = 0; i <TEMPERATURE_SAMPLES; i + +) {
readings_dup [i] = letture [i];
}
/ / Estremi bolla alla estremità della matrice
int extremes_count = TEMPERATURE_SAMPLES / EXTREMES_RATIO;
int swap;
for (int i = 0; i <extremes_count; + + i) {/ / per cento di iterazioni di sorta bolla sulle piccole N agisce più velocemente del Q-sort
for (int j = 0; j <TEMPERATURE_SAMPLES - 1; j + +) {
if (readings_dup [i]> readings_dup [i +1]) {/ / potrebbe essere fatto con 3 XOR e non di swap, se volete fantasia
swap = readings_dup [i];
readings_dup [i] = readings_dup [i +1];
readings_dup [i +1] = swap;
}
}
}
/ / Media mezzo della matrice
sum_temp int = 0;
for (int i = extremes_count; i <TEMPERATURE_SAMPLES - extremes_count; i + +) {
sum_temp + = readings_dup [i];
}
ritorno sum_temp / (TEMPERATURE_SAMPLES - extremes_count * 2);
}

int InternalTemperatureSensor :: in_c () {
ritorno in_k () - 273;
}

int InternalTemperatureSensor :: in_f () {
ritorno in_c () * 9/5 + 32;
}

int InternalTemperatureSensor :: in_k () {
ritorno in_lsb () + offset;! / / per SEMPLICITÀ sto usando k = 1, utilizzare la riga successiva se si vuole K = 1,0
/ / Return (int) (in_lsb () * coefficiente) + offset;
}

int InternalTemperatureSensor :: raw () {
if (ADCSRA & _BV (ADSC)) {
return -1;
Else {}
int ret = ADCL | (ADCH << 8); / / Prendi il risultato precedente di conversione
ADCSRA | = _BV (ADSC); / / Inizia nuova conversione
ritorno ret;
}
}

vuoto InternalTemperatureSensor :: print () {
Serial.print ("> R:");
Serial.print (raw (), DEC);
Serial.print ("L:");
Serial.print (in_lsb (), DEC);
Serial.print ("K:");
Serial.print (in_k (), DEC);
Serial.print ("C:");
Serial.print (in_c (), DEC);
Serial.print ("F:");
Serial.print (in_f (), DEC);
Serial.println ("#");
}

Uso

Temperatura InternalTemperatureSensor (1,0, TEMPERATURE_ADJUSTMENT); / / L'argomento viene ignorato 1,0 per impostazione predefinita, si vedano i commenti c'tor
vuoto setup () {
temperature.init (); / / Chiama init () in configurazione o ogni volta che dopo aver modificato ADCSRA o ADMUX
}

void loop () {
/ / Temperature.print (); / / scommentare questa riga per eseguire il debug di uscita del sensore tramite collegamento seriale
int war_sensor_data = temperature.raw (); / / Questo restituisce un output del sensore poco sfruttabili
int temperature_in_celsius = temperature.in_c (); temperatura / / Questa operazione riporta più utilizzabile in gradi Celsius
}

Spiegazione

ATtinyX5 utilizza ADC4 per leggere dati dal sensore interno. Nel metodo Init () tutto magico con la necessaria registri viene fatto per preparare il sistema di lettura di questi dati. È necessario chiamare questo metodo ogni volta che si desidera configurare ADMUX e ADCSRA per il recupero dei dati di temperatura del sensore. Se l'unico canale ADC che utilizzate nel vostro programma è ADC4 il sensore di temperatura di allora si dovrebbe chiamare solo nel setup (), vale a dire una volta. Questo riduce il tempo a leggere la temperatura procedura almeno di un fattore due.

Metodo InternalTemperatureSensor :: raw () restituisce i dati grezzi provenienti dal sensore. Purtroppo questi dati sono poco sfruttabili. Per illustrare il problema di dare un'occhiata in uscita dal InternalTemperatureSensor :: print () metodo di debug. La prima colonna è ciò che il sensore ritorna. La velocità d'uscita è di circa 5 righe al secondo, quindi entro 2 secondi il sensore valori restituiti con 18 gradi di differenza.

ATtiny85 Internal Temperature Sensor Readouts

ATTINY85 della temperatura interna del sensore Indicatori


Al fine di renderlo più fruibile InternalTemperatureSensor metodo di dati :: in_lsb fa media mobile e rimuove gli estremi dall'ingresso. Il risultato si può vedere dalla foto sopra: l'uscita in_lsb contrassegnato come L: è il modo più usabile. E 'più accurata troppo. È possibile regolare i parametri di media mobile, ma nel complesso non mi consiglia di effettuare TEMPERATURE_SAMPLES inferiore a 20 e superiore a 50. Se è inferiore a 20 allora deviazione cresce in modo significativo. Fare TEMPERATURE_SAMPLES superiore a 50 non migliora la precisione ma la memoria rifiuti e rallenta i calcoli. Anche EXTREMES_RATIO definisce la quantità di valori estremi sarà tagliato, non rendono meno di 2 (che eliminerà tutti i valori). Rendere più efficace TEMPERATURE_SAMPLES si impedisce la rimozione estremi dai campioni.
Oltre a questi metodi fondamentali 3 alcuni in_c utilità metodi (), in_k (), in_f () sono forniti. Tornano temperatura in gradi Celsius, Fahrenheit e Kelvin.

Un altro problema con il sensore interno che non è calibrato, quindi per ogni chip è necessario utilizzare il metodo print () per produrre la lettura e regolare il secondo parametro del costruttore per abbinare questi valori con il termometro calibrato. Il valore di -13 nel codice sorgente funziona solo per uno dei miei ATtinies, non vi è alcuna garanzia che funzionerà per gli altri.
Nel complesso il sensore interno è utilizzabile, ma non aspettatevi molto da essa. I sensori esterni sono ancora molto meglio.

Questo post è pubblicato in Hardware , Robotics .

Non ci sono commenti

Non ci sono commenti finora

Lascia un commento

Mappa del sito (C) Andrey Mikhalchuk, 2005-2008