I've written two pieces of codes that uses VirtualWire to transport a 0-1023 integer, VirtualWire_Interger_TX and RX. This code works as far as I can tell without any problems.
But when I tried to combine the RX part with another piece of code my Arduino just started hanging after a few serial messages. From googling around a bit I've seen that there is some sort of problem with the string library at the moment and basically I wonder if I should bother with this problem or just wait to have the issue fixed in an update?
From looking at the Serial Monitor output and comparing to the working example it seems that the hangs are caused when calculating the Sensor1Data/potVal to a color.
Wireless_RGB_LED_Controller (causes Arduino to hang after 5-20 messages)
/*
RGB LED controller
4 modes: off, color select, color pulse and random cycle/pulse
By Markus Ulfberg 2009-05-19
Updated to Version 2 - 2010-01-13 (Not publicly released)
Updated to Version 3 - 2011-12-14
Thanks to: Ladyada, Tom Igoe and
everyone at the Arduino forum for excellent
tutorials and everyday help.
TODO:
1. Use millis for debounce instead of delay.
*/
#include <VirtualWire.h>
// LED's
int ledPin = 13;
// Define and set sensors to zero
int Sensor1Data = 0;
int potVal = 0;
// RF Transmission container
char Sensor1CharMsg[4];
// set the ledPins
int ledRed = 10;
int ledGreen = 9;
int ledBlue = 6;
// LED Power variables
byte redPwr = 0;
byte greenPwr = 0;
byte bluePwr = 0;
void setup()
{
// sets the digital pin as output
pinMode(ledPin, OUTPUT);
// VirtualWire
// Initialise the IO and ISR
// Required for DR3100
vw_set_ptt_inverted(true);
// Bits per sec
vw_setup(2000);
// Start the receiver PLL running
vw_rx_start();
pinMode(ledRed, OUTPUT);
pinMode(ledGreen, OUTPUT);
pinMode(ledBlue, OUTPUT);
// serial for debugging purposes only
Serial.begin(9600);
}
void loop()
{
dataRX();
colorControl();
// DEBUG
Serial.print("Sensor 1: ");
Serial.print(Sensor1Data);
Serial.print(" redPwr: ");
Serial.print(redPwr, DEC);
Serial.print(" greenPwr: ");
Serial.print(greenPwr, DEC);
Serial.print(" bluePwr: ");
Serial.println(bluePwr, DEC);
// End debug
// END DEBUG
} // END loop()
void dataRX()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
// Non-blocking
if (vw_get_message(buf, &buflen))
{
int i;
// Turn on a light to show received good message
digitalWrite(13, true);
// Message with a good checksum received, dump it.
for (i = 0; i < buflen; i++)
{
// Fill Sensor1CharMsg Char array with corresponding
// chars from buffer.
Sensor1CharMsg[i] = char(buf[i]);
}
// Null terminate the char array
// This needs to be done otherwise problems will occur
// when the incoming messages has less digits than the
// one before.
Sensor1CharMsg[buflen] = '\0';
// Convert Sensor1CharMsg Char array to integer
Sensor1Data = atoi(Sensor1CharMsg);
// Turn off light to and await next message
digitalWrite(13, false);
}
delay(500);
}
// lightMode 1
void colorControl() {
// read the potentiometer position
potVal = Sensor1Data;
// RED > ORANGE > YELLOW
if (potVal > 0 && potVal < 170) {
redPwr = 255;
bluePwr = 0;
greenPwr = map(potVal, 0, 170, 0, 255);
}
// YELLOW > LIME?? > GREEN
if (potVal > 170 && potVal < 341) {
greenPwr = 255;
bluePwr = 0;
redPwr = map(potVal, 341, 170, 0, 255);
}
// GREEN > TURQOUISE
if (potVal > 341 && potVal < 511) {
greenPwr = 255;
redPwr = 0;
bluePwr = map(potVal, 341, 511, 0, 255);
}
// TURQOUISE > BLUE
if (potVal > 511 && potVal < 682) {
bluePwr = 255;
redPwr = 0;
greenPwr = map(potVal, 682, 511, 0, 255);
}
// BLUE > PURPLE
if (potVal > 682 && potVal < 852) {
bluePwr = 255;
greenPwr = 0;
redPwr = map(potVal, 682, 852, 0, 255);
}
// PURPLE > RED
if (Sensor1Data > 852 && potVal < 1023) {
redPwr = 255;
greenPwr = 0;
bluePwr = map(potVal, 1023, 852, 0, 255);
}
// Display colors
colorDisplay();
}
// Displays the colors when called from other functions
void colorDisplay() {
analogWrite(ledRed, redPwr);
analogWrite(ledGreen, greenPwr);
analogWrite(ledBlue, bluePwr);
}
VirtualWire_Integer_RX (works)
/*
Sensor Receiver
By Markus Ulfberg 2012-07-06
Gets a sensor reading 0-1023 in a char array
from RF Transmitter unit via VirtualWire
converts char array back to integer
*/
#include <VirtualWire.h>
// LED's
int ledPin = 13;
// Sensors
int Sensor1Data;
// RF Transmission container
char Sensor1CharMsg[4];
void setup() {
Serial.begin(9600);
// sets the digital pin as output
pinMode(ledPin, OUTPUT);
// VirtualWire
// Initialise the IO and ISR
// Required for DR3100
vw_set_ptt_inverted(true);
// Bits per sec
vw_setup(2000);
// Start the receiver PLL running
vw_rx_start();
} // END void setup
void loop(){
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
// Non-blocking
if (vw_get_message(buf, &buflen))
{
int i;
// Turn on a light to show received good message
digitalWrite(13, true);
// Message with a good checksum received, dump it.
for (i = 0; i < buflen; i++)
{
// Fill Sensor1CharMsg Char array with corresponding
// chars from buffer.
Sensor1CharMsg[i] = char(buf[i]);
}
// Null terminate the char array
// This needs to be done otherwise problems will occur
// when the incoming messages has less digits than the
// one before.
Sensor1CharMsg[buflen] = '\0';
// Convert Sensor1CharMsg Char array to integer
Sensor1Data = atoi(Sensor1CharMsg);
// DEBUG
Serial.print("Sensor 1: ");
Serial.println(Sensor1Data);
// END DEBUG
// Turn off light to and await next message
digitalWrite(13, false);
}
}
VirtualWire_Interger_TX (works)
/*
Sensor Transmitter
By Markus Ulfberg 2012-07-06
Takes a sensor reading 0-1023
converts it to a char array and sends
to RF receiver unit via VirtualWire
*/
#include <VirtualWire.h>
// LED's
const int ledPin = 13;
// Sensors
const int Sensor1Pin = A2;
// const int Sensor2Pin = 3;
int Sensor1Data;
//int Sensor2Data;
char Sensor1CharMsg[4];
void setup() {
// PinModes
// LED
pinMode(ledPin,OUTPUT);
// Sensor(s)
pinMode(Sensor1Pin,INPUT);
// for debugging
Serial.begin(9600);
// VirtualWire setup
vw_setup(2000); // Bits per sec
}
void loop() {
// Read and store Sensor 1 data
Sensor1Data = analogRead(Sensor1Pin);
// Convert integer data to Char array directly
itoa(Sensor1Data,Sensor1CharMsg,10);
/*
// DEBUG
Serial.print("Sensor1 Integer: ");
Serial.print(Sensor1Data);
Serial.print(" Sensor1 CharMsg: ");
Serial.print(Sensor1CharMsg);
Serial.println(" ");
delay(1000);
// END DEBUG
*/
digitalWrite(13, true); // Turn on a light to show transmitting
vw_send((uint8_t *)Sensor1CharMsg, strlen(Sensor1CharMsg));
vw_wait_tx(); // Wait until the whole message is gone
digitalWrite(13, false); // Turn off a light after transmission
delay(200);
} // END void loop...