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
}
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...
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.
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???
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)...
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
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...
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...