Is there someone out there who can explain how the Virtual Wire commands work? I have reviewed many posts and EVERY SINGLE ONE OF THEM is the result of not understanding how the character arrays and the unsigned 8 bit integers and coding of information works. I have also reviewed all the YouTube tutorials and found no help there either. At the very least, someone could point out some useful links as I've searched everything in this forum and found NOTHING helpful. If someone is going to invent a library to make things easier, they should at least explain it. For example, what is that uint8_t * about? (Especially the *). And what does &buffer do? Can someone provide examples of sending real data (from sensors) along with limitations on number of bytes? THANK YOU!
I can't fully explain, but here's the transmit part of the code in loop I have running in a remote control:
// go read the keypad
char key = keypad.getKey(); // reading the keypad
if(key) // same as if(key != NO_KEY)- did something change?
{
msg[0]=key; // load the array with the key character
// msg[1]=NULL; // Rx side seems to work without this
digitalWrite(ledPin, true); // Flash a light to show transmitting
vw_send((uint8_t *)msg, strlen(msg)); // send the character out
// Serial.println(key); // for debugging only
vw_wait_tx(); // Wait until the whole message is gone
msg[0] can be 27 bytes (37?), that is clearly explained at the virtualwire download site - a function of how much data can be sent, with synchronization bytes and Manchester encoding/decoding at the 16 MHz clock speed.
Here's my receive code from loop:
// look for wireless input
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
int i;
digitalWrite(ledPin, LOW); // Turn on LED to show working a message
// Debug statements, no longer needed:
// Message with a good checksum received, dump it.
//Serial.println("Got: "); // Show on PC for debugging
// for (i = 0; i < buflen; i++)
// {
//Serial.print(byte(buf[i]));
// }
//Serial.println(""); // spaces it out for the monitor
switch ( buf[0] )
{ // switch on the first byte in the array for now
// 16 case statements follow, one for each button press on the remote
}
Ok then.
"uint8_t * " means "unsigned 8 bit int ", * means it's a pointer. In this case it is type casting a char array to an unsigned 8 bit int pointer.
A simple transmitter code, that transmits data from an accelerometer to a receiving Arduino.
#include <VirtualWire.h>
char Array[20]; // create an array large enough to hold the string of data
int X,Y,Z; // Accelerometer variables
void setup()
{
Serial.begin(9600); // Debugging only
Serial.println("Sending"); // Debugging only
// Initialise the IO and ISR
//vw_set_ptt_inverted(true); // Required for DR3100 ** NOT NEEDED UNLESS USING DR3100 MODULE **
vw_setup(2000); // Bits per sec **Baud Rate** Max is 4000, but you may lose data
vw_set_tx_pin(33); //RF sending pin
pinMode(37, OUTPUT);
pinMode(35, OUTPUT);
pinMode(53, OUTPUT);
digitalWrite(37, LOW); // RF ground
digitalWrite(35,HIGH); // RF Vcc
digitalWrite(53,HIGH); // accelormeter Vcc
pinMode(13, INPUT); //accel Z
pinMode(14, INPUT); //accel Y
pinMode(15, INPUT); //accel X
}
void loop()
{
X = analogRead(15) / 4; // X raw data to 0 - 1023 ** Divided by 4 to give range of 0 - 255**
Y = analogRead(14) / 4; // Y raw data to 0 - 1023 ------------------------------------------
Z = analogRead(13) / 4; // Z raw data to 0 - 1023 ------------------------------------------
sprintf(Array, "%d,%d,%d ",X,Y,Z); // sprintf("storage location array" , "How the data is grouped and stringed together", "the data variables to be stringed and sent")
//Example data: "205,10,46 "
vw_send((uint8_t*)Array, strlen(Array));
// strlen counts the number of characters in the array,
//and sets how many times "vw_send" needs to go through the array to send everything in it.
vw_wait_tx(); // wait until all data is sent
}
Now the receiving end.
#include <VirtualWire.h>
void setup()
{
Serial.begin(9600); // Debugging only
Serial.println("Receiving");
pinMode(13,OUTPUT); // Arduino onboard LED, pin 13
// Initialise the IO and ISR
//vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2000); // Bits per sec **Must match transmitter baud rate**
vw_set_rx_pin(8); // data pin, pin 8 on arduino
vw_rx_start(); // Start the receiver PLL running
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN]; // The max message length is 30 chars, but after the NULL terminator and two other bytes ( not sure which) the actual max length is 27 char.
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
//Data received: "205,10,46 "
digitalWrite(13, HIGH); // Indicate data is being received
int temp1 = atoi(strtok(buf, ",")); // reads the buf array until it finds a comma "," then stores the data before the comma in temp1
// temp1 = 205 ** Notice no comma, that because strtok reads everything before the comma
int temp2 = atoi(trtok(NULL,",")); // NULL tells strtok to pick up where it found the last condition IE the comma.
//temp2 = 10
int temp3 = atoi(strtok(NULL," "));// Now strtok is looking for a blank space indicated by " ", and like the previous two, it will store the last bit of data in temp3
// temp3 = 46
Serial.print(temp1); // X axis
Serial.print(", ");
Serial.print(temp2); // Y axis
Serial.print(", ");
Serial.print(temp3); // Z axis
Serial.println();
}
else digitalWrite(13, LOW); // No data received
}
Darn, Crossroads beat me to it.
#include <VirtualWire.h>
int CS_ObjTemp; // variables set in the GetTemperature() function
int CS_AmbTemp;
char buf[30]; // the buffer to hold the message
byte packetnum = 0; // a packet number for diagnostic purposes
void setup() {
vw_setup(1000); // set up VirtualWire, 1000 bps
}
void loop() {
GetTemperature(); // Sets two variables
// the following line writes the string to be sent. It will look like
// P10 S -10 A 17
sprintf(buf,"P%d S %d A %d :\n" ,packetnum, CS_ObjTemp, CS_AmbTemp);
send(buf); // calls the send function with buf (buf is a pointer to the string above)
packetnum++; // increment packet number for next packet.
delay(5000); // wait 5 seconds... lather, rinse, repeat
}
void send (char *message){ // accepts the char pointer, which is locally called message
vw_send((uint8_t *)message, strlen(message)); // sends the message
vw_wait_tx(); // waits for the transmission to finish
}
&buffer is the address of buffer. In my case, I didn't need to use the &, because buf is already the address of the char array I am sending.
HI HazardsMind !
Your example is very ilustrative.
I tried tocompile the receiver code and I got the following compile error :
sketch_nov02c.ino: In function 'void loop()':
sketch_nov02c:26: error: invalid conversion from 'uint8_t*' to 'char*'
sketch_nov02c:26: error: initializing argument 1 of 'char* strtok(char*, const char*)'
sketch_nov02c:26: error: invalid conversion from 'char*' to 'int'
sketch_nov02c:28: error: invalid conversion from 'char*' to 'int'
sketch_nov02c:30: error: invalid conversion from 'char*' to 'int'
line: 26 int temp1 = strtok(buf, ","); // reads the buf array until it finds a comma "," then stores the data before the comma in temp1
could you give some help on this ?
int temp1 = strtok( (char*) buf, ",");
Try that.
int temp1 = strtok( (char*) buf, ",");
Try that.
strtok() returns a char *. Storing a pointer to char in an int is a bad idea.
Your right, atoi should be in there too.
int Temp1= atoi(strtok((char*)buf, ","));
Why look in the forums or ytube when you have the playground?
Mark