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

Título: Rede de sensores DS18S20
Enviado 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 é:

Código: [Seleccione]
#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&ccedil;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("&ordm; C</td></tr>");
      }
      ethernet.print("</table></body></html>");
      ethernet.respond();
    }
  }
 
 

Se alguém me puder dar uma ajuda agradeço muito.

Cumprimentos,

Pedro
Título: Re: Rede de sensores DS18S20
Enviado por: senso em 31 de Agosto de 2011, 00:34
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.
Título: Re: Rede de sensores DS18S20
Enviado por: poliveira1978 em 31 de Agosto de 2011, 08:50
Com itoa não funciona... "Invalid conversion from uint8_t to int"...

Vou ver se consigo fazer de outra maneira.
Título: Re: Rede de sensores DS18S20
Enviado por: vdr em 31 de Agosto de 2011, 10:41
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.
Título: Re: Rede de sensores DS18S20
Enviado por: poliveira1978 em 31 de Agosto de 2011, 11:44
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.
Título: Re: Rede de sensores DS18S20
Enviado por: vdr em 31 de Agosto de 2011, 12:20
parvoice minha, li na diagonal, e pensei que não desse para fazer print de floats que seriam os valores das leituras do sensor.  :-[
Título: Re: Rede de sensores DS18S20
Enviado por: senso em 31 de Agosto de 2011, 14:34
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)
Título: Re: Rede de sensores DS18S20
Enviado por: poliveira1978 em 31 de Agosto de 2011, 21:05
Ainda assim não funciona, continua a dar o mesmo erro, invalid convertion from uint8_t to long int.

Obrigado na mesma pelo link.
Título: Re: Rede de sensores DS18S20
Enviado por: senso em 31 de Agosto de 2011, 21:16
Mostra o código então, é que sem código ninguem adivinha qual é o problema.
Título: Re: Rede de sensores DS18S20
Enviado por: poliveira1978 em 31 de Agosto de 2011, 21:22
o código está logo no post de abertura deste tópico. ;-)
Título: Re: Rede de sensores DS18S20
Enviado por: senso em 31 de Agosto de 2011, 21:43
O código em que usas a função ltoa ou itoa?
Título: Re: Rede de sensores DS18S20
Enviado por: poliveira1978 em 31 de Agosto de 2011, 22:07
ok, sorry....

Código: [Seleccione]
ethernet.print("</td><td>");
ethernet.print(ltoa(tempDeviceAddress));
ethernet.print("</td><td>");

O problema é que não é possivel fazer ethernet.print(variavel ,HEX);
Título: Re: Rede de sensores DS18S20
Enviado por: senso em 31 de Agosto de 2011, 22:10
Por esse exemplo é perfeitamente visivel que leste sobre como usar essa função não foi?

Código: [Seleccione]
  #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&ccedil;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("&ordm; C</td></tr>");
      }
      ethernet.print("</table></body></html>");
      ethernet.respond();
    }
  }
Título: Re: Rede de sensores DS18S20
Enviado por: poliveira1978 em 31 de Agosto de 2011, 22:26
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
Título: Re: Rede de sensores DS18S20
Enviado por: senso em 31 de Agosto de 2011, 22:29
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
Título: Re: Rede de sensores DS18S20
Enviado por: poliveira1978 em 31 de Agosto de 2011, 22:58
Código: [Seleccione]
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:

Código: [Seleccione]
ltoa (deviceAddress,buffer,16);
no ficheiro DallasTemperature.h o tipo DeviceAddress é definido assim:
Código: [Seleccione]
typedef uint8_t DeviceAddress[8];
Título: Re: Rede de sensores DS18S20
Enviado por: senso em 31 de Agosto de 2011, 23:31
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.
Título: Re: Rede de sensores DS18S20
Enviado por: poliveira1978 em 01 de Setembro de 2011, 20:37
Para mostrar o endereço na página algo do género:
Código: [Seleccione]
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.
Título: Re: Rede de sensores DS18S20
Enviado por: vdr em 01 de Setembro de 2011, 21:18
isto serviria?

Código: [Seleccione]

String str_aux = String();

for (j=0;j<8;j++)
{

str_aux += deviceAddress[j];

}

Título: Re: Rede de sensores DS18S20
Enviado por: zordlyon em 01 de Setembro de 2011, 21:38

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.
Título: Re: Rede de sensores DS18S20
Enviado por: senso em 01 de Setembro de 2011, 22:21
Esse erro é porque ele estava a passar um ponteiro de uint8_t quando a função esperava um long.
Título: Re: Rede de sensores DS18S20
Enviado por: poliveira1978 em 01 de Setembro de 2011, 23:23
Após várias tentativas e depois de testar com os sketches de demonstração da lib DallasTemperature, constatei que mesmo usando
Código: [Seleccione]
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 é:
Código: [Seleccione]

#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&ccedil;&atilde;o</td><td>Temperatura</td><td>Alimenta&ccedil;&atilde;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("&ordm; 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();
  }
}