RF + PWM

Bom dia amigos "Arduinautas", td bem com vcs?

Estou com uma dúvida quanto o uso do PWM com módulo de RF no arduino. (Usando a biblioteca VirtualWire).
Eu quero ligar um LED RGB de alta potência com o Arduino, cujo os comandos sejam recebidos pelo módulo RF. Se eu ligo ou desligo as portas com digitalWrite(), o arduino recebe as informações sem problema e as executa, porém se eu uso analogWrite() para poder mudar a intensidade das cores, o Arduino para de receber futuras informações pelo RF Receiver, ou seja, quando eu ligo o PWM (em qualquer pino) o arduino deixa de receber os comandos por RF.

Segue partes importantes dos Sketches:

Receptor

void setup()   {
  Serial.begin(9600);
  vw_set_rx_pin(9); // Define o pino 5 do Arduino como entrada do pino de dados do receptor
  vw_setup(2000);   // Bits por segundo
  vw_rx_start();    // Inicializa o receptor
  
  pinMode(r, OUTPUT);
  pinMode(g, OUTPUT);
  pinMode(b, OUTPUT);

  delay(2000);
}
 
void loop()
{
  uint8_t message[VW_MAX_MESSAGE_LEN];   
  uint8_t msgLength = VW_MAX_MESSAGE_LEN;
  if (vw_get_message(message, &msgLength))
  {
    String comando = "";
    Serial.print("Recebido: ");
    for (int i = 0; i < msgLength; i++)
    {
      comando = comando + char(message[i]);
    }
    acao (comando);
    Serial.println();
    Serial.println("Continuacao 3");
  }
}

void acao (String cmd)
{
  Serial.println(cmd);
  for(byte i = 0; i < 5; i++)
  {
    comandos[i] = cmd.substring(i*3, (i*3)+3).toInt();
    Serial.print(comandos[i]);
    Serial.print (" - ");
  }
    switch (comandos[0])
    {
      case(0):
        digitalWrite(r, 0);
        digitalWrite(g, 0);
        digitalWrite(b, 0);
        break;
      case(1):
        digitalWrite(r, 1);
        digitalWrite(g, 1);
        digitalWrite(b, 1);
        break;
      case(2)
        analogWrite(r, comandos[1]);
        analogWrite(g, comandos[2]);
        analogWrite(b, comandos[3]);
        break;
    }
  }
}

Emissor

void setup()
{
  Serial.begin(9600);
  vw_set_tx_pin(8); //Define o pino 8 do Arduino como pino de dados do transmissor
  vw_setup(2000);   // Bits per sec
}

void loop()
{
  char data[30];
  byte numero;
  if (Serial.available() > 0)
  {
    numero = Serial.readBytesUntil (13, data, 20);
    data[numero] = 0;
    Serial.print("Enviado : ");
    Serial.print(data);
    Serial.print(" - Caracteres : ");
    Serial.println(strlen(data));
    send(data);  //Envia a mensagem para a rotina que envia os dados via RF
  } 
}

void send (char *message)
{
  vw_send((uint8_t *)message, strlen(message));
  vw_wait_tx(); // Aguarda o envio de dados
}

Alguma ideia???

Grande abraço...

Não tenho bem a certeza, mas há uma coisa que não gosto (logo à primeira vista) no seu código. Trata-se da utilização da função digitalWrite():

A documentação diz que esta função recebe como segundo parâmetro ( o value), um de dois valores (HIGH ou LOW). No entanto no seu caso está a fazer isto de forma diferente. Está a introduzir 0 e 1. Para valores diferente de LIGADO e DESLIGADO deve usar a função analogWrite(), conforme está a fazer.
Outra coisa que não sei se está a considerar é que o analogWrite() NÃO PODE SER LIGADO EM QUALQUER PINO. Os pinos em que pode ser usado dependem da placa que está a utilizar. Dê uma vista de olhos às especificações da placa que está a utilizar, para mais informações:

Convinha ter colocado as primeira linhas onde define os pinos para se poder verificar isso. Por exemplo, o pino 9 que define como pino para a recepção é um dos pinos que pode ser utilizado para o PWM/analogWrite().

PWM: 3, 5, 6, 9, 10, and 11. Provide 8-bit PWM output with the analogWrite() function.

A mim parece-me bastante coincidência, por isso começaria por definir este pino num local diferente dos indicados como PWM "capable".

luisilva:
Não tenho bem a certeza, mas há uma coisa que não gosto (logo à primeira vista) no seu código. Trata-se da utilização da função digitalWrite():
digitalWrite() - Arduino Reference

A documentação diz que esta função recebe como segundo parâmetro ( o value), um de dois valores (HIGH ou LOW). No entanto no seu caso está a fazer isto de forma diferente. Está a introduzir 0 e 1. Para valores diferente de LIGADO e DESLIGADO deve usar a função analogWrite(), conforme está a fazer.

Blz luisilva, então, HIGH = 1 = TRUE e LOW = 0 = FALSE.. São apenas sinonimos bit 0 para estado baixo (LOW) e o bit 1 para estado alto (HIGH)...

luisilva:
Outra coisa que não sei se está a considerar é que o analogWrite() NÃO PODE SER LIGADO EM QUALQUER PINO. Os pinos em que pode ser usado dependem da placa que está a utilizar. Dê uma vista de olhos às especificações da placa que está a utilizar, para mais informações:
http://arduino.cc/en/Main/Products

Convinha ter colocado as primeira linhas onde define os pinos para se poder verificar isso. Por exemplo, o pino 9 que define como pino para a recepção é um dos pinos que pode ser utilizado para o PWM/analogWrite().

PWM: 3, 5, 6, 9, 10, and 11. Provide 8-bit PWM output with the analogWrite() function.

Estou considerando, sim... Tanto é que testei os pinos 3, 5, 6, 9, 10 e 11, ou seja, ja tentei em todos...

Quando, do Emissor, eu envio o código "001" ele liga as 3 cores do led (corretamente), quando eu envio o comando "000" ele desliga os leds (corretamente), quando eu envio o comando, por exemplo "002100150200" (PWM para o pino R em 100, no pino G 150 e no pino B 200) ele liga o PWM nestas intensidades (corretamente), mas ele para de receber futuros comandos...

OU seja, depois que eu ligo o PWM ele deixa de ouvir o Receiver...

Alguma ideia do que possa ser.....

Não é dito nada acerca disto:

luisilva:

PWM: 3, 5, 6, 9, 10, and 11. Provide 8-bit PWM output with the analogWrite() function.

A mim parece-me bastante coincidência, por isso começaria por definir este pino num local diferente dos indicados como PWM "capable".

Não custa nada e esta questão fica descartada.

Agora já é dito uma coisa que pode dar mais alguma luz sobre o problema:

carlosad1981:
OU seja, depois que eu ligo o PWM ele deixa de ouvir o Receiver...

Pelo menos para mim a, isto não tinha ficado claro no primeiro post. Isto quer dizer que ele a dada altura recebe e depois deixa de receber. Teste a situação descrita em cima e depois diga alguma coisa.

String comando = "";
Serial.print("Recebido: ");
for (int i = 0; i < msgLength; i++)
{
comando = comando + char(message*);*

  • }[/quote]*
    Que tal livrares-te do objecto String e usares apenas vectores de chars

luisilva:
Não é dito nada acerca disto:

luisilva:

PWM: 3, 5, 6, 9, 10, and 11. Provide 8-bit PWM output with the analogWrite() function.

A mim parece-me bastante coincidência, por isso começaria por definir este pino num local diferente dos indicados como PWM "capable".

Não custa nada e esta questão fica descartada.

Então, eu ja testei em vários pinos do arduino, tanto os 3 pinos do LED em portas PWM diferentes como também o pino Data do receiver... Em todos os testes tive o mesmo problema.

luisilva:
Agora já é dito uma coisa que pode dar mais alguma luz sobre o problema:

carlosad1981:
OU seja, depois que eu ligo o PWM ele deixa de ouvir o Receiver...

Pelo menos para mim a, isto não tinha ficado claro no primeiro post. Isto quer dizer que ele a dada altura recebe e depois deixa de receber. Teste a situação descrita em cima e depois diga alguma coisa.

Desculpe-me não ter expressado-me corretamente antes. Resumindo o problema... O receiver funciona corretamente enquanto eu não ligar o pwm, depois que eu ligo o pwm (qualquer porta) o receiver fica "surdo"...

HugoPT:

String comando = "";
Serial.print("Recebido: ");
for (int i = 0; i < msgLength; i++)
{
comando = comando + char(message*);*

  • }[/quote]*
    Que tal librares-te do objecto String e usares apenas vectores de chars
    [/quote]
    Blz hugo???
    Então cara, eu ja passei pra String() justamente por eu não saber trabalhar com char. Eu sei que isso iria otimizar o código e tmb diminuir o uso da memória necessária, mas a otimização deixarei para depois que eu conseguir resolver o problema do RF "surdo"... hehehe Valeu...
    Alguma ideia???

Sem ver os pinos nao da para ter a certeza...

Mas o PWM e gerado por um timer... e essa comunicacao RF usa um timer para o fazer. Pode acontecer que o timer usado seja o mesmo e por isso a comunicacao RF nao funcione pois tens o PWM a funcionar.

Mete o codigo completo do arduino que controla a luminosidade.

bubulindo:
Sem ver os pinos nao da para ter a certeza...

Mas o PWM e gerado por um timer... e essa comunicacao RF usa um timer para o fazer. Pode acontecer que o timer usado seja o mesmo e por isso a comunicacao RF nao funcione pois tens o PWM a funcionar.

Mete o codigo completo do arduino que controla a luminosidade.

Blz bubulindo?

Cara, os códigos estão no primeiro post (parte do Receptor)...

Valeu!

Como previsto:

**Caution:**Virtual wire takes over Arduino Timer1, and this will affect the PWM capabilities of the digital pins 9 and 10.

in http://www.airspayce.com/mikem/arduino/VirtualWire.pdf

ponto 4.0.

Nao faco ideia do que sao as variaveis r,g e b...

bubulindo:
Como previsto:

**Caution:**Virtual wire takes over Arduino Timer1, and this will affect the PWM capabilities of the digital pins 9 and 10.

in http://www.airspayce.com/mikem/arduino/VirtualWire.pdf

ponto 4.0.

Nao faco ideia do que sao as variaveis r,g e b...

opa, blz bubulindo ??
r = RED, g = GREEN e b = BLUE (cores dos leds RGB).
Estou usando uma fita Led RGB semelhante a esta: http://www.ebay.com/itm/5050-SMD-Waterproof-RGB-5M-300LED-Flexible-Strip-Light-24-44-KEY-IR-12V-5A-Power-/371123795680?pt=AU_Lighting_Fans&var=&hash=item5668b3b6e0

O problema é que eu nem estou usando estes pinos para o PWM... Estou usando os pinos 3(r), 5(g) e 6(b)... O problema é exatamente o mesmo. Acho que o virtual Wire não entra em conflito apenas nos pinos 9 e 10, mas sim em todos os pinos PWM, pois é só acionar o PWM em qualquer pino do arduino que o Receprot RF433mhz para de funcionar...

Por isto eu ava querendo usar o Transceiver nRF24L01 2,4GHz (espero que ele não entre em conflito com o PWM... hehehe

Grande abraço...

Para garantir que a comunicacao e feita de forma correcta... nao me espantava que a biblioteca do RF desligue os timers (desligando assim o PWM). Mas isso so vendo o interior da biblioteca.

Ja agora, e como mais ninguem falou disso... ja testaste o teu protocolo como deve ser?? Ja pensaste que pode ser um problema do protocolo que estas a usar?

bubulindo:
Ja agora, e como mais ninguem falou disso... ja testaste o teu protocolo como deve ser?? Ja pensaste que pode ser um problema do protocolo que estas a usar?

Blz bubulindo? Cara, na realidade eu não sei, eu não sei nem alterar as configurações do protocolo, visto que estou usando conforme o exemplo da própria biblioteca...

Grande abraço...

Desculpa... expressei-me mal.

Nao e o protocolo RF.

Tu mandas um comando dum Arduino para o outro. Ja pensaste que podem ser esses comandos que podem estar a falhar?

Ja verificaste que os comandos enviados funcionam sempre?

bubulindo:
Tu mandas um comando dum Arduino para o outro. Ja pensaste que podem ser esses comandos que podem estar a falhar?

Ja verificaste que os comandos enviados funcionam sempre?

Sim, sempre recebe (enquanto não ligo o PWM)

PWM desligado -> rf funcionando
PWM ligado -> rf não funcionando
PWM desligado novamente -> rf volta a funcionar... SEMPRE ASSIM.

Já desisti de usar o RF 433Mhz...

Qual é o pino que neste momento está o RF?

luisilva:
Qual é o pino que neste momento está o RF?

Opa, blz luisilva?
Cara, eu ja desmontei o circuito, mas lembro-me que eu testei o RF em várias portas. A porta 9, 10, 8 e 6 se não me engano... Todas exatamente com o mesmo problema.

O PWM eu tmb testei todas as portas: 3, 5, 6, 9, 10, 11... tmb todas com o mesmo problema... Por isso desisti de usar o RF 422mhz e comprei pelo ebay alguns módulos nRF 24L01. Agora só esperando chegar... :wink:

Grande abraço...