LusoRobótica - Robótica em Português

Software => Software e Programação => Tópico iniciado por: nadabro em 31 de Março de 2011, 15:57

Título: Dúvida em programação Arduino
Enviado por: nadabro em 31 de Março de 2011, 15:57
Boas..

Estou concluindo um projecto em que capturo os dados de uma estação vindos de 433.92Mhz, mas tenho uma dúvidas:

-Converter os dados em letras
Citar
float windd;

(...)

windd = (receivedCode.charAt(23)=='1'?1:0)*256 +
         (receivedCode.charAt(22)=='1'?1:0)*128 +
         (receivedCode.charAt(21)=='1'?1:0)*64 +
         (receivedCode.charAt(20)=='1'?1:0)*32 +
         (receivedCode.charAt(19)=='1'?1:0)*16 +
         (receivedCode.charAt(18)=='1'?1:0)*8 +
         (receivedCode.charAt(17)=='1'?1:0)*4 +
         (receivedCode.charAt(16)=='1'?1:0)*2 +
         (receivedCode.charAt(15)=='1'?1:0);
O receivedCode é uma string, o windd é a direcção do vento, recebo os valores correctos : 0 ou 45º ou 90º, etc...mas queria converter nas letras das rosas dos ventos e fazer Serial.print das letras:

0 --> N
45 -> NE
90 -> E
135 -> SE
180 -> S
225-> SW
270-> W
315-> NW

Encontrei isto noutro código, mas não consigo aplicar no meu..
Citar
{
  "N ", "NE ",
  "E ",  "SE ",
  "S ", "SW ",
  "W ", "NNW"
};


Obrigado

Título: Re: Dúvida em programação Arduino
Enviado por: senso em 31 de Março de 2011, 16:05
Tens a tua leitura serial que espero que esteja bem feita usando o Serial.avaliable() e tal, então supondo que tens os teus dados na variavel data_in e que vais meter essas letras num array de 4 posições chamado data_out, 4 posições para contar com o terminador , experimenta algo assim:

Código: [Seleccione]
int num = atoi(data_in);
switch(num){
 case 0: data_out = "N\0";
               break;
 case 45: data_out = "NE\0";
                 break;
....
 case 315: data_out = "NW\0";
                   break;

  default:  data_out = "ERR\0";
                 break;
}

O default é quando o data_in não tem nenhum dos valor esperado, mas podes não colocar nada, depende do que queres fazer, o \0 é o terminador da string, agora é só juntar o resto dos valores.
A função atoi, converte os caracteres ascii recebidos pela porta serial para um inteiro que pode ser muito mais facilmente usado no switch case.
Título: Re: Dúvida em programação Arduino
Enviado por: nadabro em 31 de Março de 2011, 18:58
Ainda sou principiante em programação, o código que estou a usar encontrei na internet, alterei os tempos/protocolo para ser compativel com a minha estação, mas quando se trata de adicionar strings, char, bloqueio. O código ainda ter que ser mt trabalhado, mas é conforme vou aprendendo..

Tenho duas leituras:
-Rain
-WindDirection + Gust

Estas leituras chegam em tempos diferentes: por vezes recebo o "Wind" em intervalos de 30 segundos , outras vezes recebo "Rain" em intervalos de minutos, mas varia, por isso sempre que recebo um pacote RF novo, converto os dados do pacote correspondente e faço Serial.print desse pacote, mas quero que tb faça Serial.print da última leitura do outro pacote.

1º Tenho que definir data_in e data_out se é float, int, etc?
2º Onde insiro o código abaixo? Logo a seguir ao windd = (receivedCode.charAt(23)=='1'?1:0)*256 + ...
3º O Serial.print é o data_out?

Obrigado..

Código: [Seleccione]
int num = atoi(data_in);
switch(num){
 case 0: data_out = "N\0";
               break;
 case 45: data_out = "NE\0";
                 break;
 case 90: data_out = "E\0";
                    break;
                   
 case 135: data_out = "SE\0";
                     break;
 case 180: data_out = "S\0";
                       break;
 case 225: data_out = "SW\0";
                       break;
 case 270: data_out = "W\0";
                       break;
 case 315: data_out = "NW\0";
                   break;
}

Código: [Seleccione]
#define nobits 36
#define initialstring "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
#define   syncmin   7500
#define   syncmax   9900
#define   separatormin 250
#define   separatormax   750
#define   lowmin   1700
#define   lowmax   2300
#define   highmin   3700
#define   highmax   4300
#define baudspeed 9600
#define receiverpin 2
float windd;
float gust;
float rain;
unsigned long lastReadMills;


void setup() {
pinMode(receiverpin, INPUT);
digitalWrite(receiverpin, HIGH);
Serial.begin(baudspeed);
}


void loop()
{
  String receivedCode = ReceiveCode();

       
           if ((receivedCode.charAt(9)=='1')&&(receivedCode.charAt(10)=='1')&&(receivedCode.charAt(12)=='1')&&(receivedCode.charAt(13)=='1')&&(receivedCode.charAt(14)=='1'))
     {
     
       
        {
      windd = (receivedCode.charAt(23)=='1'?1:0)*256 +
         (receivedCode.charAt(22)=='1'?1:0)*128 +
         (receivedCode.charAt(21)=='1'?1:0)*64 +
         (receivedCode.charAt(20)=='1'?1:0)*32 +
         (receivedCode.charAt(19)=='1'?1:0)*16 +
         (receivedCode.charAt(18)=='1'?1:0)*8 +
         (receivedCode.charAt(17)=='1'?1:0)*4 +
         (receivedCode.charAt(16)=='1'?1:0)*2 +
         (receivedCode.charAt(15)=='1'?1:0);
         
         gust = (receivedCode.charAt(31)=='1'?1:0)*128 +
          (receivedCode.charAt(30)=='1'?1:0)*64 +
          (receivedCode.charAt(29)=='1'?1:0)*32 +
          (receivedCode.charAt(28)=='1'?1:0)*16 +
          (receivedCode.charAt(27)=='1'?1:0)*8 +
          (receivedCode.charAt(26)=='1'?1:0)*4 +
          (receivedCode.charAt(25)=='1'?1:0)*2 +
          (receivedCode.charAt(24)=='1'?1:0);
          gust = gust /5;
          }
         
         
         Serial.println("Wind Direction and Gust");
         Serial.print(windd);
         Serial.println("; ");
         Serial.print(gust *3.6);
         Serial.println("kmh; ");
         Serial.print(rain);
         Serial.println("mm; ");
         Serial.print(lastReadMills/1000);
         Serial.println("s; ");
         Serial.println(" ");
         
       }
                else if ((receivedCode.charAt(9)=='1')&&(receivedCode.charAt(10)=='1')&&(receivedCode.charAt(11)=='0')&&(receivedCode.charAt(12)=='1')&&(receivedCode.charAt(13)=='1')&&(receivedCode.charAt(14)=='0'))
       {
         
               {
        rain = (receivedCode.charAt(31)=='1'?1:0)*32768 +
         (receivedCode.charAt(30)=='1'?1:0)*16384 +
         (receivedCode.charAt(29)=='1'?1:0)*8192 +
         (receivedCode.charAt(28)=='1'?1:0)*4096 +
         (receivedCode.charAt(27)=='1'?1:0)*2048 +
         (receivedCode.charAt(26)=='1'?1:0)*1024 +
         (receivedCode.charAt(25)=='1'?1:0)*512 +
         (receivedCode.charAt(24)=='1'?1:0)*256 +
         (receivedCode.charAt(23)=='1'?1:0)*128 +
         (receivedCode.charAt(22)=='1'?1:0)*64 +
         (receivedCode.charAt(21)=='1'?1:0)*32 +
         (receivedCode.charAt(20)=='1'?1:0)*16 +
         (receivedCode.charAt(19)=='1'?1:0)*8 +
         (receivedCode.charAt(18)=='1'?1:0)*4 +
         (receivedCode.charAt(17)=='1'?1:0)*2 +
         (receivedCode.charAt(16)=='1'?1:0);
        rain = rain/5;
        lastReadMills = millis();
     
     }
     
     
         Serial.println("Wind Direction and Gust");
         Serial.print(windd);
         Serial.println("; ");
         Serial.print(gust *3.6);
         Serial.println("kmh; ");
         Serial.print(rain);
         Serial.println("mm; ");
         Serial.print(lastReadMills/1000);
         Serial.println("s; ");
         Serial.println(" ");
         
        }
}

String ReceiveCode()
{
String receivedCode = initialstring;

(...)}
Título: Re: Dúvida em programação Arduino
Enviado por: senso em 31 de Março de 2011, 19:15
O data in seria a string onde tens os teus dados, mas como já tens isso em inteiro, usando aquela coisa horrivel com string.charAt, não é horrivel de não ser feio, é horrivel por causa da estupideza de usarem strings no arduino um char[] não lhes chegava -.-
Em vez disto:
int num = atoi(data_in);
switch(num){

metes só switch(windd){
Meter, metes onde achares melhor dentro do loop, pode ser antes de imprimires aquelas coisas por serial.
Título: Re: Dúvida em programação Arduino
Enviado por: nadabro em 31 de Março de 2011, 20:28
Eu sei que o código é horrivel, estou a trabalhar com bits (1,0) escuso de ter Strings, que ocupam mt mais espaço.

Inclusive o código funciona mt bem quando recebo 6 pacotes de 36bits repetidos numa transmissão, mas se receber 2 diferentes repetidos 3x numa transmissão (ab+ab+ab), raramente consigo convert o "b" acho que o código é demasiado lento e não consegue converter.


Já tenho a funcionar, obrigado pela ajuda :)

-mudei "float windd" para "int winddr"
-inseri "char winddr"

alterei ligeiramente o código
Código: [Seleccione]
                  switch(windd){
 case 0: winddr = 'N';
               break;
 case 45: winddr = 'NE';
                 break;
 case 90: winddr = 'E';
                    break;
                   
 case 135: winddr = 'SE';
                     break;
 case 180: winddr = 'S';
                       break;
 case 225: winddr = 'SW';
                       break;
 case 270: winddr = 'W';
                       break;
 case 315: winddr = 'NW';
                   break;
}
Título: Re: Dúvida em programação Arduino
Enviado por: senso em 31 de Março de 2011, 20:59
Mas tu estas a usar strings -.-
Título: Re: Dúvida em programação Arduino
Enviado por: nadabro em 01 de Abril de 2011, 20:20
Eu sei que sim, mas vou alterar isso no futuro. Queria fazer o seguinte cálculo:

Recebo novos dados de "rain"  e queria subtrair esse valor com a transmissão anterior. O problema é que não sei como guardar os dados da anterior transmissão de forma que esses dados sejam actualizaveis apenas depois do cálculo (rain recente-anterior)..de forma a poder fazer o calculo a partir de novos dados.

Exemplo:

recente: 10
anterior: 5

Serial.print(rain recente)="10"
Serial.print(rain recente-anterior)="5"

...passado uns minutos

recente: 15
anterior: 10

Serial.print(rain recente)="15"
Serial.print(rain recente-anterior)="5


Não sei se estou a explicar bem o que desejo fazer..

Título: Re: Dúvida em programação Arduino
Enviado por: senso em 01 de Abril de 2011, 22:14
Usas uma variavel e metes if (rain_novo != rain_antigo) rain_antigo = rain_novo; acho que é isso que queres.
Título: Re: Dúvida em programação Arduino
Enviado por: nadabro em 09 de Abril de 2011, 18:35
Usas uma variavel e metes if (rain_novo != rain_antigo) rain_antigo = rain_novo; acho que é isso que queres.

Era isso mesmo que precisava :)

Tem dado imenso jeito, alem do calculo, tem permitido criar condições para ver se a última msg é correcta, etc etc..

Obrigado!