Tou aqui com umas duvidas.
O que pretendo é o seguinte.
Tenho 2 Arduinos. O 1º lê um certo valor de uma entrada analógica. Em seguida envia esse valor para o outro Arduino, que depois escreve o mesmo em um lcd. O meu problema esta na transmissão entre os dois.
No 1º
....
loop()
{
valor = analogRead(0);
Serial.println(valor);
}
Até aqui tudo bem e agora no segundo como faço o tratamento da informação?
Primeiro ligas o RX ao TX e vice-versa. Depois fazes isto no segundo:
void loop(){
char valor[5];
unsigned int fromOther = 0;
if (Serial.available() > 3) { //não é ideal...
for (int i = 0; i <5; i++) {
if ((valor[i] = Serial.read()) != '\n') {
valor[i] = '\0';
break; //sai deste for.
}//end if
}//end for
fromOther = atoi(valor);
}
}
Não sei o que se vai passar com os chips USB ainda ligados nos dois controladores...
Há uma maneira mais simples... sem teres de enviar dados em ASCII.
Como os dois arduinos estão ligados, por cabo nos pinos TX/RX -> RX/TX?
Presumo que já sabes como imprimir no LCD, então o que te falta é ler a serial?
se for isso, testa o abaixo:
String SerialBuffer = "";
void setup(){
SerialBuffer.reserve(200);
Serial1.begin(9600); //os dois devem ter o mesmo rate
}
void loop(){
if (Serial1.available() > 0){
while (Serial1.available() != 0) {
char inChar = (char)Serial1.read();
if (inChar == '\n') {
//Imprime no LCD a string do SerialBuffer
SerialBuffer = "";
}
else {
SerialBuffer += inChar; \\Add to buffer
}
}
}
}
Assim o primeiro arduino imprime uma linha na serial e o segundo recebe todos os bytes, armazena no buffer (string) e quando encontrar a quebra de linha você pega o conteúdo do buffer e imprime no LCD.
String , de todo evitavel sendo que o pretendido é apenas ler uns bytes da Serial
Usa apenas isso em ultimo recurso a tudo.
Nao sei se sabes mas isso e um objecto e nao um tipo de dados nativo do C!
fromOther = atoi(valor);
Visto ele querer colocar isso num LCD e o LCD apenas recebe strings se calhar aqui será desnecessario converter para int
String , de todo evitavel sendo que o pretendido é apenas ler uns bytes da Serial
Usa apenas isso em ultimo recurso a tudo.
Nao sei se sabes mas isso e um objecto e nao um tipo de dados nativo do C!
Olá HugoPT!
Estás correto! Eu uso o acima para alguns comandos e variáveis via serial, o uso de string nesse caso facilita a comparação, exemplo SerialBuffer == "IrSensor(99,99,99)".
Neste último caso, você sugere um char array no lugar de string?
Mortis:
Como os dois arduinos estão ligados, por cabo nos pinos TX/RX -> RX/TX?
Presumo que já sabes como imprimir no LCD, então o que te falta é ler a serial?
se for isso, testa o abaixo:
String SerialBuffer = "";
void setup(){
SerialBuffer.reserve(200);
Serial1.begin(9600); //os dois devem ter o mesmo rate
}
void loop(){
if (Serial1.available() > 0){
while (Serial1.available() != 0) {
char inChar = (char)Serial1.read();
if (inChar == '\n') {
//Imprime no LCD a string do SerialBuffer
SerialBuffer = "";
}
else {
SerialBuffer += inChar; \Add to buffer
}
}
}
}
Assim o primeiro arduino imprime uma linha na serial e o segundo recebe todos os bytes, armazena no buffer (string) e quando encontrar a quebra de linha você pega o conteúdo do buffer e imprime no LCD.
Sim estão ligados TX/RX -> RX/TX
Desculpem a minha ignorância mas sou novo nestas coisas...
Quanto ao codigo, Serial1 é por algum motivo em especial? As placas que estou a usar são Uno, não será apenas Serial?
Não existe uma maneira mais simples?
Por exemplo...
Arduino 1 lê valor de 975 na analógica 0
leituraa = analogRead(0);
envia para Arduino 2
Serial.println(leituturaa);
No Arduino 2 algo tipo do género
leiturab = Serial.read(); sendo o valor de "leituraa" igual a 975...
lcd.setCursor(0,0);
lcd.print(leiturab,1);
joaquim_lopes:
Quanto ao codigo, Serial1 é por algum motivo em especial? As placas que estou a usar são Uno, não será apenas Serial?
Perdoa-me, mas eu copiei partes do meu código e eu uso o Mega, que possui mais portas seriais.
Sobre ser novato, eu também sou, então não se preocupe! Mas logo mais deixaremos de ser
joaquim_lopes:
Arduino 1 lê valor de 975 na analógica 0
leituraa = analogRead(0);
envia para Arduino 2
Serial.println(leituturaa);
No Arduino 2 algo tipo do género
leiturab = Serial.read(); sendo o valor de "leituraa" igual a 975...
lcd.setCursor(0,0);
lcd.print(leiturab,1);
Isto é possível?
Bom, primeiro você precisa saber se tem dados na serial, então não tem como fugir do Serial.available()
O segundo o HugoPT já respondeu, você terá de passar pelo Serial.read() três vezes, uma para cada byte, logo não tem como fazer de forma diferente daquela que o bubulindo exemplificou.
Ok... depois de ler um pouco sobre o Serial... experimenta algo assim:
Arduino 1
void loop() {
unsigned int valor = 0;
valor = analogRead(A0);
Serial.write(valor >> 8);
Serial.write(valor);
Serial.println(); //importante
}
no Arduino 2
void loop() {
unsigned int value = 0;
if (Serial.available() >=3) {//dois bytes do int mais carriage return
value = (Serial.read()<<8) + Serial.read();
Serial.read();//skip \n
Serial.print("received ");
Serial.println(value);
}
}
Assim é melhor porque são sempre apenas enviados 2 bytes. Se enviares em ASCII podes enviar entre 2 a 5 bytes (ou 6 se olhares ao tamanho dum int) e isso é bem mais complicado de programar. Também é mais rápido...
Nota que não coloquei aqui protecções para sincronizar ambos os arduinos. Ou seja, têm de ser ligados ambos ao mesmo tempo para garantir que um está a ouvir o que o outro está a mandar, mas isso é simples de fazer colocando o Arduino 2 à espera do \n.
Esta é uma maneira mais simples e correcta de fazer isto.
Bom, abaixo como ficaram meus códigos, para o Joaquim Lopes pode ser um próximo passo, passar o valor de vários sensores e ou comandos entre os arduinos (?).
Eu executo uma série de comandos via bluetooth, esse é para eu gravar os valores de referencia para sensores IR de um seguidor de linhas, valores usados para aumentar ou reduzir a sensibilidade das condições.
Assim por uma vista de olhos rapida parece que está la tudo.
Ha algumas coisas que podem ser melhoradas a titulo de uma boa programaçao.
Vejamos aqui:
void ExecuteCommand(char Value[]){
Estas a passar um parametro com o Value[].Quando passas um array ele por si só é um ponteiro para a primeira posiçao do vector.Eu teria colocado ou esperar um ponteiro em vez de Value[]
Eu modificava para:
ExecuteCommand(char * Value)
Agora ha aqui outra questao. O vector que estas a passar é global o que poderá nao fazer muito sentido passa-lo como argumento na funçao...
Irá funcionar na mesma assim.
char Command[100];
strcpy(Command, Value);
Se passas o vector por parametro porque é que depois o copias para outro array dentro da funçao?
A idea é usalo la dentro nao copia-lo.
Assim comeste mais 100 bytes de RAM para nada.Faz uso dos ponteiros!
Hmm, acho que nos estamos a deixar levar por dois problemas diferentes.
O do Mortis em que uma pessoa comunica com o Arduino (já agora, tens um código extremamente complexo para algo tão simples) e o do joaquim em que dois arduinos comunicam entre si.
No problema do Mortis, os humanos preferem ASCII então a comunicação é feita assim e como tal tem um overhead maior e é mais complexo.
No caso do Joaquim é escusado colocar duas máquinas a falar linguagem de humanos (ASCII) já que elas se entendem melhor em binário e a programação é bem menos complexa como exemplifiquei em cima.
A única coisa que me preocupa é o efeito que o chip FTDI tem na comunicação... Alguém experimentou os dois códigos?
Se passas o vector por parametro porque é que depois o copias para outro array dentro da funçao?
A idea é usalo la dentro nao copia-lo.
Assim comeste mais 100 bytes de RAM para nada.Faz uso dos ponteiros!
HugoPT,
Eu copio o array porque após o strtok eu via apenas "SetSensorParams" exemplo:
Value passado "SetSensorParams(200,300,200)"
char *chpt = strtok(Value, "(");
O resultado era
chpt = "SetSensorParams"
Value = "SetSensorParams"
bubulindo:
Hmm, acho que nos estamos a deixar levar por dois problemas diferentes.
Desculpem-me, acho que me empolguei e não tinha a intenção de complicar =/
Por favor, voltemos ao problema do tópico:
bubulindo:
A única coisa que me preocupa é o efeito que o chip FTDI tem na comunicação... Alguém experimentou os dois códigos?
A qual efeito te referes?
joaquim_lopes:
Antes de mais obrigado a todos.
Tal como disse, sou novato nestas coisas e alguma linguagem passa-me ao lado...
mas vou testar os vários códigos e depois dou o meu feedback.
Joaquim, desculpa-me se compliquei muito para ti, o bubulindo esta correto, os códigos que coloco estão muito longe da linguagem de comunicação entre máquinas (estou habituado a programar para Windows :(), diga-nos o que ocorreu por ai e se podemos ajudar!
Malta após alguns teste eis o que consegui até agora.
No Arduino 1
loop()
{
val = analogRead(0);
Serial.write("T");
Serial.write(val);
delay(1500);
}
No Arduino 2
loop()
{
if ((incomingByte)=='T')
{
valor = Serial.read();
lcd.setCursor(0,1);
lcd.print(valor);
}
}
O que acontece é que isto funciona desde que o valor enviado (neste caso val) não seja superior a 255, caso isso aconteça o Arduino 2 lê outro valor
Por exemplo
O que acontece é que isto funciona desde que o valor enviado (neste caso val) não seja superior a 255, caso isso aconteça o Arduino 2 lê outro valor
Por exemplo
Arduino 1 - valor enviado -> Arduino 2 - Valor LCD
0 -> 0
1 -> 1
Logico o valor maximo de um byte é 255 no caso de ser unsigned !
Como escreves alem disso ele da a volta e recomeça de 0
Serial.write(val);
Voltamos a mesma questao.Nao consegues passar o valor todo num só byte!
O valor maximo que pode ser lido no ADC é 1023 ou seja necessitas de no minimo 4 bytes e talvez mais um para usar um caracter terminador