LusoRobótica - Robótica em Português
Sistemas específicos => Arduino / AVR => Tópico iniciado por: almamater em 28 de Abril de 2010, 23:47
-
Hi!
Estou a tentar ligar um sensor LM60 BIZ (http://www.national.com/ds/LM/LM60.pdf) ao Arduino.
[img removida]
int potPin = 0;
float temperature = 0;
void setup()
{
Serial.begin(9600);
Serial.println("LM35 Thermometer ");
analogReference(INTERNAL);
}
void printTenths(int value) {
// prints a value of 123 as 12.3
Serial.print(value / 10);
Serial.print(".");
Serial.println(value % 10);
}
void loop() {
int span = 20;
int aRead = 0;
for (int i = 0; i < span; i++) {
aRead = aRead+analogRead(potPin);
}
aRead = aRead / 20;
temperature = ((100*1.1*aRead)/1024)*10;
// convert voltage to temperature
Serial.print("Analog in reading: ");
Serial.print(long(aRead));
// print temperature value on serial monitor
Serial.print(" - Calculated Temp: ");
printTenths(long(temperature));
delay(500);
}
Acontece que qdo ligo o Arduino ele apenas acende a luz PWR e há um curto qualquer pq o LM60 fica quentinho... não posso ligar desta forma? tenho de meter uma resistencia no sensor?
-
A datasheet não diz que existe uma versão num pacote TO220 como esse que tens na figura... de certeza que é um LM60 que tens?
-
A datasheet não diz que existe uma versão num pacote TO220 como esse que tens na figura... de certeza que é um LM60 que tens?
Sim.. diz "LM60 BIZ", eu tinha comprado uns 3 há uns tempos para fazer um projecto com um PIC mas não correu muito bem e fiquei com eles aqui..
Pensei que o esquema fosse igual ao LM35, de qualquer forma o melhor é mesmo arranjar um LM35
P.s.: A imagem que coloquei foi só para mostrar como fiz as ligações.. Base/Colector/Emissor que copiei dessa forma.
-
Mas o pacote do que aí tens é como esse da figura, grande com "alheta" metálica? É que se é, então isso não é um LM60 independentemente do que possa ter escrito. O LM60 só existe em SOT-23 (SMD) ou TO-92 (aqueles transistores tipicos pequenos e todos pretos como um BC5xx).
Se tens um TO-92 então tens os fios preto e amarelos trocados, o GND é o pino da direita.
-
Mas o pactoe do que aí tens é como esse da figura, grande com "alheta" metálica? É que se é, então isso não é um LM60 independentemente do que possa ter escrito. O LM60 só existe em SOT-23 (SMD) ou TO-92 (aqueles transistores tipicos pequenos e todos pretos como um BC5xx).
Se tens um TO-92 então tens os fios preto e amarelos trocados, o GND é o pino da direita.
Tem este formato o meu:
http://www.modtronix.com/images/to92.jpg (http://www.modtronix.com/images/to92.jpg)
-
Tá certo, é um TO-92 tal como diz o nome da imagem, lol. Então é isso, tens o GND e o Vout trocados.
O pinout to TO-92 tá logo na 1ª página da datasheet, no canto inferior direito, não há que enganar.
Entretanto como já "stressaste" os chips, podem já não estar bons ou muito bons.
-
Tá certo, é um TO-92 tal como diz o nome da imagem, lol. Então é isso, tens o GND e o Vout trocados.
O pinout to TO-92 tá logo na 1ª página da datasheet, no canto inferior direito, não há que enganar.
Entretanto como já "stressaste" os chips, podem já não estar bons ou muito bons.
Esquece a imagem.. já a removi! eu não a segui, apenas a coloquei como exemplo do circuito que fiz.. os pinos eu segui pela datasheet do LM60 http://www.national.com/ds/LM/LM60.pdf (http://www.national.com/ds/LM/LM60.pdf)
Ligando a +5 do Arduino, ao Grnd e o Vout ao Pino 9 do Arduino..
Mas secalhar pode ser defeito do LM60 ou posso ter queimado em alguma circustância.. vou testar com outro LM60... :o
Gracias pelas respostas.. se correr mal já digo outra vez ::) de qualquer forma vou tb tentar arranjar um LM35 já que todos os circuitos e códigos são na maior parte dos casos para este último
-
Ok!
Com o LM35 tenho temperaturas de 25º C com o seguinte código:
int potPin = 0;
float temperature = 0;
void setup()
{
Serial.begin(9600);
Serial.println("LM35 Thermometer ");
analogReference(INTERNAL);
}
void printTenths(int value) {
// prints a value of 123 as 12.3
Serial.print(value / 10);
Serial.print(".");
Serial.println(value % 10);
}
void loop() {
int span = 20;
int aRead = 0;
for (int i = 0; i < span; i++) {
aRead = aRead+analogRead(potPin);
}
aRead = aRead / 20;
temperature = ((100*1.1*aRead)/1024)*10;
// convert voltage to temperature
Serial.print("Analog in reading: ");
Serial.print(long(aRead));
// print temperature value on serial monitor
Serial.print(" - Calculated Temp: ");
printTenths(long(temperature));
delay(500);
}
com o mesmo código mas com o LM60 vai para os :
nalog in reading: 554 - Calculated Temp: 59.5
Analog in reading: 554 - Calculated Temp: 59.5
Analog in reading: 554 - Calculated Temp: 59.5
Analog in reading: 554 - Calculated Temp: 59.5
Analog in reading: 554 - Calculated Temp: 59.5
Analog in reading: 554 - Calculated Temp: 59.5
Analog in reading: 554 - Calculated Temp: 59.5
Analog in reading: 554 - Calculated Temp: 59.5
Tem a ver com este cálculo temperature = ((100*1.1*aRead)/1024)*10 não é ? e com o valor 1.1 julgo eu..
-
Tem a ver com o 10. O LM35 dá-te 10mV por cada ºC, o LM60 dá-te 424mV mais 6.25mV por cada ºC (ou seja, a 0ºC o LM35 dá-te 0V e o LM60 dá-te 424mV).
analogReference(INTERNAL); muda a tensão de referência do ADC para uma referência interna do mega que é de 1.1V, passando então as medições com o ADC a fazerem-se numa escala de 0 a 1.1V em vez da escala por omissão que é de 0 a 5V.
Na verdade esse projecto tem um erro máximo de +/-10ºC (podem estar 15ºC ou 35ºC e o programa a dizer 25ºC). Isto porque a tensão interna de referência do mega é nominal 1.1V mas pode variar entre 1V e 1.2V de chip para chip, por diferenças de fabrico. A tensão tem esta pequena variação mas é muito estável, ou seja, se ela for por exemplo 1.16V num certo chip isso "nunca" mudará nesse chip. Para corrigir este erro de +/-10ºC é preciso medir o valor real da tensão interna de referência e usar esse valor em vez de 1.1V nos cálculos. Podes fazer essa medida num passo inicial de calibração e guardar o valor na EEPROM, depois o programa vai lá buscar o valor para fazer a conta.
-
Ok, percebi e faz sentido.. estive tb a ver o tópico http://lusorobotica.com/index.php?topic=1610.0 (http://lusorobotica.com/index.php?topic=1610.0)
É complicado calcular essa tensão de referência ?
-
Não, basta medir com a referência interna uma tensão conhecida. Metes à entrada do ADC uma tensão (vamos chamar-lhe Vin) qualquer mas conhecida (medes com o multimetro) e lês o ADC (vamos chamar VAL ao valor lido) com a referência interna de 1.1V (vamos chamar-lhe Vref). Aí é fácil calcular o valor exacto da referência interna, pois
Vin = VAL * Vref / 1024
Resolvendo em ordem a Vref temos
Vref = Vin * 1024 / VAL
Se o teu Vin fosse 0.95V (por exempo de uma pilha NiMH bem gasta) e lesses 850 do ADC, então o Vref real do teu chip seria
Vref = 0.95 * 1024 / 850 ~ 1.144V
Guardavas este valor na EEPROM (por exemplo multiplicado por 1000 para ser um número inteiro, 1144) e depois o software ia lá ler para fazer as contas.
-
Obrigado pela explicação :) fiquei a perceber! Assim que conseguir já vejo o Vin da corrente que estou a fornecer ao circuito!
Basta depois fazer algo como isto:
#include <avr/eeprom.h>
#define EEPROM_SERVOPOS_ADDR 3
typedef struct {
int servo1;
int servo2;
} TServos;
TServos servoPos;
...
// guardar as posições em EEPROM...
eeprom_write_block (&servoPos, (void*)EEPROM_SERVOPOS_ADDR, sizeof(servoPos));
...
// recuperar as posições da EEPROM...
eeprom_read_block (&servoPos, (void*)EEPROM_SERVOPOS_ADDR, sizeof(servoPos));
que li por aqui ;D
ou então numa variável qualquer, tb deve dar.
-
Por cuirosidade... Este código que vi noutro site será tb necessário recorrer a este cálculo da Voltagem de refª?
/*
An open-source LM35DZ Temperature Sensor for Arduino. This project will be enhanced on a regular basis
(cc) by Daniel Spillere Andrade , http://www.danielandrade.net
http://creativecommons.org/license/cc-gpl
*/
int pin = 0; // analog pin
int tempc = 0,tempf=0; // temperature variables
int samples[8]; // variables to make a better precision
int maxi = -100,mini = 100; // to start max/min temperature
int i;
void setup()
{
Serial.begin(9600); // start serial communication
}
void loop()
{
for(i = 0;i< =7;i++){ // gets 8 samples of temperature
samples[i] = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;
tempc = tempc + samples[i];
delay(1000);
}
tempc = tempc/8.0; // better precision
tempf = (tempc * 9)/ 5 + 32; // converts to fahrenheit
if(tempc > maxi) {maxi = tempc;} // set max temperature
if(tempc < mini) {mini = tempc;} // set min temperature
Serial.print(tempc,DEC);
Serial.print(" Celsius, ");
Serial.print(tempf,DEC);
Serial.print(" fahrenheit -> “);
Serial.print(maxi,DEC);
Serial.print(” Max, “);
Serial.print(mini,DEC);
Serial.println(” Min”);
tempc = 0;
delay(1000); // delay before loop
}
Podia alterar o 5.0 da fórmula samples = ( 5.0 * analogRead(pin) * 100.0) / 1024.0; para a tensão que o multimetro me indicasse, certo?
-
Este programa usa Vcc (a tensão de alimentação do AVR) como tensão de referência do ADC. Normalmente é utilizado um regulador de 5V para alimentar o AVR, como o 7805, e estes dão uma tensão muito aproximada de 5V. Ainda assim podem ter algum desvio dos 5V, especialmente com variações de temperatura e corrente, mas para condições "usuais" o erro deve ser pequeno, e portanto pode funcionar melhor do que usando a Vref interna do AVR.
Este erro pode ser facilmente calculado, mas não o vou fazer aqui a não ser que queiram mesmo :)
A razão principal para usar a Vref interna do AVR em vez dos 5V para medir o LM60 tem a ver com resolução. Com 5V o ADC mede tensões em passos de 5 / 1024 ~ 4.88 mV. Isto quer dizer que para medir 1ºC de um LM35 temos cerca de "2 contagens" do ADC (10mV / 4.88 ~ 2). Portanto podemos medir grau a grau sem problemas. Já com o LM60, que varia 6.25mV / ºC, só temos 1.28 contagens do ADC, na prática 1 porque o ADC só dá números inteiros. Aqui estamos muito perto da resolução do ADC e vemos ter medições com maior erro e estar mais sujeito a ver o valor dos ºC variar devido a ruído (fica mais frequentemente a variar rapidamente entre 2 valores consecutivos de ºC).
Já com a Vref interna de 1.1V, a nossa resolução é de 1.1 / 1024 ~ 1mV e portanto temos cerca de 6 contagens do ADC para cada ºC.