LusoRobótica - Robótica em Português
Sistemas específicos => Arduino / AVR => Tópico iniciado por: poliveira1978 em 31 de Agosto de 2011, 00:31
-
Estou a montar uma rede de sensores de temperatura com a possibilidade de ver os dados através da web (com uma shield enc28j60).
Instalei a lib ETHER_28J60 da página http://srmonk.blogspot.com/2010/03/simplified-ethernet-library-for-28j60.html (http://srmonk.blogspot.com/2010/03/simplified-ethernet-library-for-28j60.html).
Já consigo ver todos os sensores e respectivas temperaturas, mas no que diz respeito aos endereços (uma espécie de MAC dos sensores ONEWIRE) só consigo ver o valor em decimal.
Na biblioteca ETHER_28J60 o método ethernet.print só trabalha com inteiros ou char e o campo endereço é de tipo Byte. se fizer cast da variável, só consigo ver o valor decimal, algo do género:
ethernet.print(int(endereco));
o código completo é:
#include "etherShield.h"
#include "ETHER_28J60.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 9
static uint8_t mac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
static uint8_t ip[4] = {192,168,10,159};
static uint16_t port = 80;
ETHER_28J60 ethernet;
int counter;
#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 9
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int numberOfDevices;
DeviceAddress tempDeviceAddress;
void setup()
{
Serial.begin(9600);
digitalWrite(6,LOW);
for (counter=0;counter<=10;counter++)
{
digitalWrite(ledPin,HIGH);
delay(1000);
digitalWrite(ledPin,LOW);
}
ethernet.setup(mac, ip, port);
sensors.begin();
}
void loop()
{
numberOfDevices = sensors.getDeviceCount();
char* param;
char endereco[8];
if (param = ethernet.serviceRequest())
{
ethernet.print("<html><head><title>Temperatura Actual</title></head><body>");
ethernet.print("<table border=\"1\" bordercolor=\"#CC66FF\" style=\"background-color:#00FFFF\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">");
ethernet.print("<tr><td>ID</td><td>Endereço</td><td>Temperatura</td>");
for (int(i)=0;i<numberOfDevices;i++)
{
sensors.getAddress(tempDeviceAddress,i);
ethernet.print("</tr><tr><td>");
ethernet.print(i);
ethernet.print("</td><td>");
ethernet.print(int(tempDeviceAddress));
ethernet.print("</td><td>");
ethernet.print(sensors.getTempC(tempDeviceAddress));
ethernet.print("º C</td></tr>");
}
ethernet.print("</table></body></html>");
ethernet.respond();
}
}
Se alguém me puder dar uma ajuda agradeço muito.
Cumprimentos,
Pedro
-
Se podes meter strings de texto usas a função itoa e convertes o valor do MAC dos sensores para uma string de numeros e usas essa mesma string para fazer o ethernet.print.
-
Com itoa não funciona... "Invalid conversion from uint8_t to int"...
Vou ver se consigo fazer de outra maneira.
-
Podias tentar fazer uma função que te separava a parte inteira e decimal para duas variáveis e depois era só fazer o print com um ponto ou virgula.
-
Não há nenhuma parte decimal... Vou tentar clarificar melhor o problema:
O "MAC" é um valor na forma 0010C0A0. Como a função ethernet.print só aceita como parametros uma string ou um inteiro, se eu tentar fazer ethernet.print(int(0010c0a0)) vou obter 1097888, que é a conversão para base 10 do valor 0010C0A0 em hexa.
Vou tentar fazer uma função que decomponha o valor em hexa e construa uma string.
Depois posto novidades.
-
parvoice minha, li na diagonal, e pensei que não desse para fazer print de floats que seriam os valores das leituras do sensor. :-[
-
Como isso é um long usa a função ltoa e usa antes este site como referência, pois são estas as funções que o avr-gcc usa e que podem ter diferenças quanto ás std do C.
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga4f6b3dd51c1f8519d5b8fce1dbf7a665 (http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga4f6b3dd51c1f8519d5b8fce1dbf7a665)
-
Ainda assim não funciona, continua a dar o mesmo erro, invalid convertion from uint8_t to long int.
Obrigado na mesma pelo link.
-
Mostra o código então, é que sem código ninguem adivinha qual é o problema.
-
o código está logo no post de abertura deste tópico. ;-)
-
O código em que usas a função ltoa ou itoa?
-
ok, sorry....
ethernet.print("</td><td>");
ethernet.print(ltoa(tempDeviceAddress));
ethernet.print("</td><td>");
O problema é que não é possivel fazer ethernet.print(variavel ,HEX);
-
Por esse exemplo é perfeitamente visivel que leste sobre como usar essa função não foi?
#include "etherShield.h"
#include "ETHER_28J60.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 9
static uint8_t mac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
static uint8_t ip[4] = {192,168,10,159};
static uint16_t port = 80;
ETHER_28J60 ethernet;
int counter;
#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 9
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int numberOfDevices;
DeviceAddress tempDeviceAddress;
char buffer[10]; //BUffer usado para a função ltoa
void setup()
{
Serial.begin(9600);
digitalWrite(6,LOW);
for (counter=0;counter<=10;counter++)
{
digitalWrite(ledPin,HIGH);
delay(1000);
digitalWrite(ledPin,LOW);
}
ethernet.setup(mac, ip, port);
sensors.begin();
}
void loop()
{
numberOfDevices = sensors.getDeviceCount();
char* param;
char endereco[8];
if (param = ethernet.serviceRequest())
{
ethernet.print("<html><head><title>Temperatura Actual</title></head><body>");
ethernet.print("<table border=\"1\" bordercolor=\"#CC66FF\" style=\"background-color:#00FFFF\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">");
ethernet.print("<tr><td>ID</td><td>Endereço</td><td>Temperatura</td>");
for (int(i)=0;i<numberOfDevices;i++)
{
sensors.getAddress(tempDeviceAddress,i);
ethernet.print("</tr><tr><td>");
ethernet.print(i);
ethernet.print("</td><td>");
ltoa(tempDeviceAddress, buffer, 16); //Converter a variavel temp... para uma string, com representação em hexa
ethernet.print(buffer); //Imprime a variavel convertida para uma string na linha acima
ethernet.print("</td><td>");
ethernet.print(sensors.getTempC(tempDeviceAddress));
ethernet.print("º C</td></tr>");
}
ethernet.print("</table></body></html>");
ethernet.respond();
}
}
-
O C não é o meu forte... estava a pensar em atoi
o código deve ser algo deste género:
char buffer [sizeof(long)*8+1];
...
ltoa (deviceAddress,buffer,16);
ethernet.print(buffer);
..
Mas agora dá erro no ltoa
-
Que tipo de erros?
Faz include da stdlib.h
Ao fazeres esse buffer assim vais guardar espaço para 8 longs nesse buffer, mais um byte, só precisas de um caracter por cada digito que o teu endereço MAC tem, mais um caracter para o \0
-
char buffer [sizeof(long)*8+1];
guarda espaço para 9 caracteres (8 do endereço + o \0).
Já inclui a stdlib.h, o erro que recebo é:
"invalid convertion from uint8_t* to long int"
na linha:
ltoa (deviceAddress,buffer,16);
no ficheiro DallasTemperature.h o tipo DeviceAddress é definido assim:
typedef uint8_t DeviceAddress[8];
-
Bem, isso quer dizer que cada numero está numa posição do array, se isso usa as funções de print do Arduino, então faz simplesmente print de endereço a endereço que ele imprime o numero.
-
Para mostrar o endereço na página algo do género:
for (j=0;j<8;j++)
{
ethernet.print(deviceAddress[j]);
}
resolve a questão.
Mas dava jeito na mesma poder contruir uma string para poder construir uma tabela de correspondências (algo do género 01234567 -> Quarto X).
Mas aproveito para agradecer a ajuda que já me foi prestada pelo user senso.
-
isto serviria?
String str_aux = String();
for (j=0;j<8;j++)
{
str_aux += deviceAddress[j];
}
-
Já inclui a stdlib.h, o erro que recebo é:
"invalid convertion from uint8_t* to long int"
na linha:
Queria dizer que a função "itoa" não é nativa da biblioteca "stdlib.h"...a função "Atoi" é! a contrária não, esse erro é devido a não ser uma função nativa da stdlib...
Eu tive este problema numa frequência na universidade, e no fim da frequência fui perguntar ao professor e ele na altura disse me que a atoi era nativa da stdlib enquanto que a itoa não.
Já foi a uns tempos valentes, mas acho que o erro era assim algo parecido..
Cumprimentos,
André Carvalho.
-
Esse erro é porque ele estava a passar um ponteiro de uint8_t quando a função esperava um long.
-
Após várias tentativas e depois de testar com os sketches de demonstração da lib DallasTemperature, constatei que mesmo usando
for (int(i)=0;i<8;i++)
{
ethernet.print(deviceAddress[i]);
}
o endereço físico não é bem "copiado" para o html.
Decidi enveredar por outro caminho, usando o ID do sensor no bus, até conseguir fazer de outra maneira.
O código que tenho agora é:
#include "stdlib.h"
#include "etherShield.h"
#include "ETHER_28J60.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include "RTClib.h"
#include "String.h"
#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 9
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int numberOfDevices;
DeviceAddress deviceAddress;
RTC_DS1307 RTC;
static uint8_t mac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
static uint8_t ip[4] = {192,168,10,159};
static uint16_t port = 80;
ETHER_28J60 ethernet;
void setup()
{
Serial.begin(9600);
ethernet.setup(mac, ip, port);
sensors.begin();
Wire.begin();
RTC.begin();
if (!RTC.isrunning())
{
RTC.adjust(DateTime(__DATE__, __TIME__));
}
}
void loop()
{
DateTime now = RTC.now();
sensors.requestTemperatures();
numberOfDevices = sensors.getDeviceCount();
char* param;
if (param = ethernet.serviceRequest())
{
ethernet.print("<html><head><title>Rede de sensores de temperatura (DS18S20)</title></head><body>");
ethernet.print("<table border=\"1\" bordercolor=\"#CC66FF\" style=\"background-color:#00FFFF\" width=\"75%\" cellpadding=\"0\" cellspacing=\"0\">");
ethernet.print("<tr><td>ID</td><td>Localização</td><td>Temperatura</td><td>Alimentação</td><td>Data</td><td>Hora</td");
for (int(i)=0;i<numberOfDevices;i++)
{
sensors.getAddress(deviceAddress,i);
ethernet.print("</tr><tr><td>");
ethernet.print(i);
ethernet.print("</td><td>");
/* for (int(j)=0;j<8;j++)
{
ethernet.print(deviceAddress[j]);
}
*/
if (i==0)
{
ethernet.print("Quarto X");
}
ethernet.print("</td><td>");
float tempC = sensors.getTempC(deviceAddress);
ethernet.print(float(tempC));
ethernet.print("º C</td><td>");
if (sensors.isParasitePowerMode())
{
ethernet.print("Modo Parasitico</td><td>");
}
else ethernet.print("<td>5 V + GND</td><td>");
}
ethernet.print(now.year());
ethernet.print("/");
ethernet.print(now.month());
ethernet.print("/");
ethernet.print(now.day());
ethernet.print("</td><td>");
ethernet.print(now.hour());
ethernet.print(":");
ethernet.print(now.minute());
ethernet.print(":");
ethernet.print(now.second());
ethernet.print("</td></tr></table></body></html>");
ethernet.respond();
}
}