• Welcome to LusoRobótica - Robótica em Português.
 

Telecontrolli + PWM ?

Started by almamater, 10 de November de 2010, 10:50

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

almamater

Olá, como o títlulo do tópico diz.. pode ser uma pergunta parva mas não sei se será possível, tenho os Módulos da Telecontrolli (Transmissor RT4 e Receptor RR3) e queria implementá-los num "robot" e controlar os DC Motors via RF...

De alguma forma é possível enviar valores PWM de um Arduino para outro usando estes módulos RF?


senso

Sim, envias numa string e depois fazes a leitura da string e tiras os valores, tens exemplos no playground do arduino.
Avr fanboy

almamater

Ah fixe!! uma string equivale ao valor ! não me lembrei de fazer assim.. eu testei os módulos da forma descrita no site Rogercom, em que basicamente envia Hight/Low através do decoder..

Vou ver então como fazer para enviar e receber a string pelo arduino :)

senso

Se são serial é só ligar o Tx e o Rx do arduino lá, depois é montar umas strings e usar o itoa para converter de valores numéricos para ascii, ou seja texto, e depois converter de string para valores numericos usando o atoi, procura por itoa avr e atoi avr no google que encontras logo o manual do avr-gcc e de como usar essas funções.
Avr fanboy

almamater

#4
Bom a nível de esquemas então não deve ser necessário usar os Encoders/Decoders e deve ser assim:

Transmissor:






Do lado do Transmissor envio usando um conversor Numeros -> Aschii
Do lado do Receptor uso String -> Números



Por exemplo, se quiser transmitir o valor 150, ele converte para o caracter "–" e o transmissor envia "1001 0110" é isto?


Sérgio_Sena

Convém implementar alguma forma de correcção de erros, para que os valores na recepção sejam fidedignos.

FEC, reed-solomon, são algumas das formas.

É claro que para experiências pode ser feito sem correcçao de erros... mas, para a informação ser bem transmitida, tens mesmo q usar correcção.
Cumprimentos,
Sérgio Sena

Electronic Gear for Musicians

Instagram

almamater

Quote from: asena on 10 de November de 2010, 17:37
Convém implementar alguma forma de correcção de erros, para que os valores na recepção sejam fidedignos.

FEC, reed-solomon, são algumas das formas.

É claro que para experiências pode ser feito sem correcçao de erros... mas, para a informação ser bem transmitida, tens mesmo q usar correcção.

agora é que se complicou  ::) mas vou ver as formas referidas de correcção :) nem sabia que era necessário héhé mas faz sentido

senso

Quote from: almamater on 10 de November de 2010, 13:18
Bom a nível de esquemas então não deve ser necessário usar os Encoders/Decoders e deve ser assim:

Transmissor:






Do lado do Transmissor envio usando um conversor Numeros -> Aschii
Do lado do Receptor uso String -> Números



Por exemplo, se quiser transmitir o valor 150, ele converte para o caracter "–" e o transmissor envia "1001 0110" é isto?


Usa o itoa! se vais simplesmente mandar um numero sem o converter mesmo para ascii vai-te saber mal porque os primeiros 32 caracteres ascii são caracteres de controlo e se os módulos tiverem alguns deles implementados pode não funcionar nada do que queres e depois não sabes porque,
A função itoa do avr-gcc é assim:
itoa(uint8_t pwm, char* buffer, 10);  //10 é a base que estamos a usar, 10 para decimal, 2 para binário, 16 para hexadecimal, para nos queremos a base 10
//Para usar, primeiro declarar um buffer para converter de int/char/uint8_t,  seja lá o tipo de variavel que for
char buffer[4];   //4 porque são 3 caracteres, um para cada numero mais um caracter para o terminador de string
uint8_t pwm=128;  //valor arbitrário do pwm
itoa(pwm, buffer, 10); //agora buffer tem o valor "128'/0' " /0 é o terminador de string
//Para enviar fazes
Serial.print(buffer); // E foi enviado

/*
** Para receber!!!!
*/
char receber[4];
uint8_t pwm_recebido = 0;
while(Serial.available()){
for(int i=0;i<4;i++){
  receber[i]=Serial.read(); }
}

pwm_recebido = atoi(receber);


E é basicamente isto, em principio com uns retoques funciona sem problemas, mas atenção que isso é código não compilado nem testado.
Avr fanboy

almamater

Obrigado pela explicação,

Em principio tenho de fazer então algo deste tipo, para conseguir depois no Arduino Receptor identificar se o valor de PWM é para a Frente, Trás, Esquerda ou Direita:


char buffer[4];   
uint8_t pwm=128; 

void setup()
{}

void loop(){
  //(...)
 
itoa(pwm, buffer, 10);

//Frente
Serial.print("F");
Serial.print(buffer);

//Trás
Serial.print("T");
Serial.print(buffer);


//Esquerda
Serial.print("E");
Serial.print(buffer);


//Direita
Serial.print("D");
Serial.print(buffer);
}


almamater

#9
Não consegui comunicar da maneira que referi acima, no receptor não recebia nada...

Neste momento andei a pesquisar e a ver umas coisas na web e consigo enviar e receber usando a library VirtualWire da seguinte forma:

EMISSOR:

// RF Link using VirtualWire to Transmit messages
// simplex (one-way) receiver with a 315MHz RF Link Transmitter module

#include <VirtualWire.h>  // you must download and install the VirtualWire.h to your hardware/libraries folder
#undef int
#undef abs
#undef double
#undef float
#undef round
void setup()
{
     // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for RF Link module
    vw_setup(2000);                 // Bits per sec
    vw_set_tx_pin(1);                // pin 1 is used as the transmit data out into the TX Link module, change this to suit your needs.
}

void loop()
{
    const char *msg = "ALMAMATER";       // this is your message to send

   vw_send((uint8_t *)msg, strlen(msg));
   vw_wait_tx();                                          // Wait for message to finish
   delay(200);
}


RECEPTOR:

// RF Link using VirtualWire to receive messages
// simplex (one-way) receiver with a 315MHz RF Link Receiver module


#include <VirtualWire.h>  // you must download and install the VirtualWire.h to your hardware/libraries folder
#undef int
#undef abs
#undef double
#undef float
#undef round
void setup()
{
    Serial.begin(9600);   

// Initialise the IO and ISR
   // vw_set_ptt_inverted(true);    // Required for RX Link Module
    vw_setup(2000);                   // Bits per sec
    vw_set_rx_pin(1);           // We will be receiving on pin 23 (Mega) ie the RX pin from the module connects to this pin.
    vw_rx_start();                      // Start the receiver
}

void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    if (vw_get_message(buf, &buflen)) // check to see if anything has been received
    {
    int i;
     // Message with a good checksum received.
       
    for (i = 0; i < buflen; i++)
    {
        Serial.print(buf[i]);  // the received data is stored in buffer
        }
    Serial.println("");
     }
}


RF com Arduino


Até aqui tudo ok! Depois andei a ver como enviar o valor de PWM juntamente com a instrução (Frente, Tras, Esquerda, Direita) e encontrei este código que parece perfeito para isto:


#include <VirtualWire.h>

typedef struct {
  byte command;
  char delim;
  char buffer [3];   //don't forget to account for the terminator.
}

packet_t;

void rfPacketOut(char commandChar,int data)
{
  packet_t packet; // initialize
  packet.command = commandChar; //"command char", buf[0] on receiving end
  packet.delim = '.'; // "delim char", buf[1] on receiving end
  itoa(data, packet.buffer, 10); // turns Integer to ASCII
  vw_send((uint8_t *)&packet, sizeof(packet));// Sends packet!
}

#undef int
#undef abs
#undef double
#undef float
#undef round

void setup()
{
    Serial.begin(9600);      // Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
//  vw_set_ptt_inverted(true); // Required for RF Link module DR3100
    vw_setup(2000);     // Bits per sec
    vw_set_tx_pin(1);   // pin 1 
     
}

void loop()
{
    int pwm_valor = 140;
    delay(10);

    rfPacketOut('A', pwm_valor); // sends "A.140" ?
    delay(900);
}



Devia de receber alguma coisa no receptor, mas não sei se estou a usar o código correcto.. usando o referido acima do RECEPTOR não aparece nada, tenho de alterar alguma coisa no código do receptor?

senso

Como é que o Virtual wire funciona se é um serial emulado e mais sujeito a erros do que o serial nativo do arduino, provavelmente tinhas ai o Rx trocado com o Tx ou algo assim parecido.
Avr fanboy

almamater

Quote from: senso on 13 de November de 2010, 14:48
Como é que o Virtual wire funciona se é um serial emulado e mais sujeito a erros do que o serial nativo do arduino, provavelmente tinhas ai o Rx trocado com o Tx ou algo assim parecido.


;D héhé funciona.. meti um vídeo no post anterior que mostra o resultado! mas só consigo enviar a frase

almamater

Quote from: senso on 13 de November de 2010, 14:48
Como é que o Virtual wire funciona se é um serial emulado e mais sujeito a erros do que o serial nativo do arduino, provavelmente tinhas ai o Rx trocado com o Tx ou algo assim parecido.

Bom, tentei mais vez sem usar a library VirtualWire e não recebo nada a não ser um caracter estranho no serial monitor..

Para envio tenho como teste:

char buffer[4];   
uint8_t pwm=128;

void setup() {
Serial.begin(9600);
}

void loop()
{
itoa(pwm, buffer, 10);
Serial.println("E");
Serial.println(buffer);
delay(3000);
}


A receber tenho:

char receber[10];
uint8_t pwm_recebido = 0;

void setup() {
Serial.begin(9600);
}

void loop()
{
if (Serial.available() > 0) {
for(int i=0;i<5;i++){
receber[i]=Serial.read(); }
pwm_recebido = atoi(receber);
Serial.println(pwm_recebido);
}
}



e no receptor ao abrir o Serial Monitor do Arduino a janela não pára de receber coisas (acrescenta linhas) mas não aprecenta nenhuma informação a não ser um caracter de x em x tempo estranho. Será que está a apanhar alguma coisa do meu Router e o caracter diz repeito ao Arduino Emissor!?


senso

Não devias usar println, porque ele manda caracteres extra que simbolizam a mudança de linha, esses caracteres podem ser o New Line e/ou Carriage Return.
Avr fanboy

zordlyon

Quote from: senso on 13 de November de 2010, 21:34
Não devias usar println, porque ele manda caracteres extra que simbolizam a mudança de linha, esses caracteres podem ser o New Line e/ou Carriage Return.

podes sempre fazer

str[strlen-1]='\0';
e depois faz o println, julgo que assim não irá mandar caracteres extra para além do terminador...

Cumprimentos..
Cumprimentos,
André Carvalho.