How to send multiple data values from many potentiometers via RF links?

hello guys,
i need to know how to send multiple values in the same time from many potentiometer via RF links transmitter and receiver ?
for now let’s work with two potentiometer
here is the script for sending a character from arduino threw the transmitter to a receiver and we will go from here :

TX

//Transmitter

#include <VirtualWire.h>

void setup(){
  Serial.begin(9600);
  
  vw_set_tx_pin(3);
  vw_setup(2000);
}

void loop(){
  if(Serial.available()){
    char c = Serial.read();
    
    if(c == '1'){
      
      vw_send((uint8_t *)c, 1);
    
    }else if(c == '0'){
    
      vw_send((uint8_t *)c, 1);
    
    }
  }
}

RX

//Reicever

#include <VirtualWire.h>

void setup(){
  pinMode(2, OUTPUT);
  digitalWrite(2, LOW);
  Serial.begin(9600);
  
  vw_set_rx_pin(3);
  vw_setup(2000);
  vw_rx_start();
  
}

void loop(){
  
   uint8_t buflen = VW_MAX_MESSAGE_LEN;
   uint8_t buf[buflen];
   
   if(vw_get_message(buf, &buflen)){
     for(int i = 0; i < buflen; i++){
       if(buf[i] == '1'){
         digitalWrite(2, HIGH);
       }
       else if(buf[i] == '0'){
         digitalWrite(2, LOW);
       }
     }
   }
    
   
}

potentiometers script

int potPin1 = A0;    // Throttle
int potPin2 = A1;    // Brakes
int valThrottle = 0;  
int valBrakes = 0;

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

void loop() {
  valThrottle = analogRead(potPin1);  // read the value from the sensor
  valThrottle = map(valThrottle, 0, 55, 0, 255); 
  valThrottle = constrain(valThrottle, 0, 255);
  Serial.println(valThrottle);
  
  valBrakes = analogRead(potPin2);  // read the value from the sensor
  valBrakes = map(valBrakes, 1023, 977, 0, 255); 
  valBrakes = constrain(valBrakes, 0, 47);
  Serial.println(valBrakes);
  delay(200);
}

So, what does the code do? What is it supposed to do?

Nothing can actually be sent at the same time, there is always some delay. However, what you could do is use the sprintf() function. then on the receiving side, use strtok() to break the data up, back into its individual parts. output[15]; // Or large enough to hold all the characters

strtok(output, "%d, %d.", valThrottle, valBrakes);

groundfungus: So, what does the code do? What is it supposed to do?

the throttle pot has to send data threw the transmitter to receiver and on the receiver side it has to operate an L293D chip that controls a motor same for the brake, but for the brake when i tested it without the RF links, the throttle has to be working so the brakes works

HazardsMind: Nothing can actually be sent at the same time, there is always some delay. However, what you could do is use the sprintf() function. then on the receiving side, use strtok() to break the data up, back into its individual parts. output[15]; // Or large enough to hold all the characters

strtok(output, "%d, %d.", valThrottle, valBrakes);

can you give me please w small example in the codes so i can understand how to use these functions ?

Transmitter
[code]#include <VirtualWire.h>

char Array[20];
int X,Y,Z,State;

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
  vw_setup(2000);	 // Bits per sec
  vw_set_tx_pin(7); //RF sending pin Arduino Mega
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  digitalWrite(5, LOW); // RF ground
  digitalWrite(6,HIGH); // RF Vcc
}

void loop()
{ 
  X = analogRead(A2) / 4; // X raw data divided by 4 gives 0 - 255
  Y = analogRead(A1) / 4; // -------------------------------------
  Z = analogRead(A0) / 4; // -------------------------------------
  
  sprintf(Array, "%d,%d,%d.",X,Y,Z);
  vw_send((uint8_t*)Array, strlen(Array));
  vw_wait_tx(); 
}

Receiver

#include <VirtualWire.h>
char data[20];
void setup()
{
  Serial.begin(9600);	// Debugging only
  Serial.println("Receiving");
  pinMode(13,OUTPUT);
  // Initialise the IO and ISR
  //vw_set_ptt_inverted(true); // Required for DR3100
  vw_setup(2000);	 // Bits per sec
  vw_set_rx_pin(8);
  vw_rx_start();       // Start the receiver PLL running
}

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

  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    int i;
    //Serial.print("Got: ");
    for (i = 0; i < buflen; i++){
      data[i] = buf[i];
    }
    
    digitalWrite(13, HIGH); // Indicate data is being received
    int temp1 = atoi(strtok(data, ","));  // Look for a comma, the return the data before it.
    int temp2 = atoi(strtok(NULL, ",")); // same as above
    int temp3 = atoi(strtok(NULL, ".")); // Look for a period, then return data before it.
    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
}

[/code]

C string manipulation is a good bit of study.

getting started http://www.codingunit.com/c-tutorial-strings-and-string-library-functions

strtok; not the simplest of subjects, you HAVE to practice to understand. http://www.tutorialspoint.com/ansi_c/c_strtok.htm

atoi; ascii to integer, there is also ascii to long, and ascii to float. http://www.tutorialspoint.com/c_standard_library/c_function_atoi.htm

Personally I handle the separate characters as they come in but that takes understanding state machine coding. Why wait for the whole message before you start making sense of it?

Depending on your RF devices you may have messages buffered on the device and a complete wireless protocol with packets and retransmits built in and pretty much the next best things to simultaneous messages. XBee does, the real cheap RX/TX units do not.

Your word for today is through. When you get through this you will be a better coder.

@HazardsMind thanks a lot i will experiment with the codes and give a feedback :)

@GoForSmoke the links you gave seems awesome i needed this, so many thanks :)

Ok, note I gave you the wrong receiver code before, and I updated it.

HazardsMind:
Ok, note I gave you the wrong receiver code before, and I updated it.

ok i guess i got the updated not the wrong one so i didn’t knew what was the mistake but it’s ok seems i got the right

@HazardsMind why did you put 20 elements for the array ? why not 3 ?

Because you want to copy the contents of buf (uint8_t) into a char array. If you tried to use buf directly, it would give errors.
So you need to make sure you have enough space to copy the data. And data[ i ] = buf[ i ] is easy to understand. You could probably also use strcpy();

HazardsMind: Because you want to copy the contents of buf (uint8_t) into a char array. If you tried to use buf directly, it would give errors. So you need to make sure you have enough space to copy the data. And data[ i ] = buf[ i ] is easy to understand. You could probably also use strcpy();

ok thank you i will need to read more about this subject it's complicated

One more edit. Got rid of the char array and uneeded for loop and added “(char*)buf”. this should make things a little easier to understand.

#include <VirtualWire.h>

void setup()
{
  Serial.begin(9600);	// Debugging only
  Serial.println("Receiving");
  pinMode(13,OUTPUT);
  // Initialise the IO and ISR
  //vw_set_ptt_inverted(true); // Required for DR3100
  vw_setup(2000);	 // Bits per sec
  vw_set_rx_pin(8);
  vw_rx_start();       // Start the receiver PLL running
}

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

  if (vw_get_message(buf, &buflen)) // Non-blocking
  { 
    digitalWrite(13, HIGH); // Indicate data is being received
    int temp1 = atoi(strtok((char*)buf, ","));  // Look for a comma, the return the data before it.
    int temp2 = atoi(strtok(NULL, ",")); // same as above
    int temp3 = atoi(strtok(NULL, ".")); // Look for a period, then return data before it.
    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
}

firashelou:

HazardsMind: Because you want to copy the contents of buf (uint8_t) into a char array. If you tried to use buf directly, it would give errors. So you need to make sure you have enough space to copy the data. And data[ i ] = buf[ i ] is easy to understand. You could probably also use strcpy();

ok thank you i will need to read more about this subject it's complicated

Not as complicated as it might appear to you right now. You lack "literacy" and when you hit terms or practices you don't know it's like a wall. That's why you should find and go through tutorials and make small test programs to see if what you think is enough for that bit. I do those myself and sometimes post examples, just something inside setup() with no code in loop that sets up variables, does a command and prints results all simple and no doubt. If you're not sure of a command, make a test sketch and modify it until you are sure or know better -what- to ask.

uint8_t -- the t is for type (variable type), the u is for unsigned (0+ values only), the int is for integer and the 8 is for 8 bits. Arduino has another name for those, byte. A char is the signed version. You can print chars and you can 'cast' a byte to a char to print it or an array of it (bytes cast to char). Cast-ing is a C mini-subject. It is how to change the way the compiler uses variables. If you haven't then google on C variable tutorial and spend some time there or maybe pick it up out of the Arduino pages.

This is the Arduino Tutorials Page in the Learning section: http://arduino.cc/en/Tutorial/HomePage

See near the top it says "Learning Examples | Foundations | Hacking | Links". That link is the Examples part. The examples, btw, are all in your IDE through the File popdown menu. You also want to explore the Foundations link to pick up on basics.

Above that on the green-blue bar you see Buy Download Products Learning Reference Support Blog You are in Learning. When you get done with that (and web searched tutorials to help when you need) then go to the Reference link and explore what's there. And still you'll need tutorials, the Arduino site has not everything including C strings but instead shows Examples with C++ String objects which are better not used on Arduino.

ok thanks a lot guys for the great info :) will give a feed back while exploring with it

@HazardsMind i used the codes you gave me and made the script i need for application, and what is happening is this:
-first i am having an antenna problem or i can say transmission problem (hardware) because when the antenna are far from each other it doesnt work, but when i touch the antenna or make them near each other like a 2 mm distance it works,

  • second, it should turn the motor on, on the receiver side, but proportional to the throttle potentiometer from the transmitter side, in fact it is not ! it choose one value and goes with it and continue with it, and if the brakes potentiometer is sending data, it’s is not getting it and stop the motor

so what might be the problem in the codes ?
by the way i never used before the wait function, it will stop everything i guess until the message is totally send isn’t it ?

here are the codes :

transmitter :

//Transmitter
#include <VirtualWire.h>

char Array[3];
int potPin1 = A0;    // Throttle
int potPin2 = A1;    // Brakes
int valThrottle = 0;  
int valBrakes = 0;

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
  vw_setup(2000);	 // Bits per sec
  vw_set_tx_pin(10); //RF sending pin Arduino Mega
  
}

void loop()
{ 
  valThrottle = analogRead(potPin1);  // read the value from the sensor
  valThrottle = map(valThrottle, 0, 55, 0, 255); 
  valThrottle = constrain(valThrottle, 0, 255);
  
  valBrakes = analogRead(potPin2);  // read the value from the sensor
  valBrakes = map(valBrakes, 639, 0, 0, 255);  // this pot is broken
  valBrakes = constrain(valBrakes, 0, 47);
  
  sprintf(Array, "%d,%d,%d.",valThrottle, valBrakes);
  vw_send((uint8_t*)Array, strlen(Array));
  vw_wait_tx(); 
  Serial.println(Array);
}

receiver:

#include <VirtualWire.h>

int enablePin = 5;
int in1Pin = 4;
int in2Pin = 3;

void setup()
{
  Serial.begin(9600);	// Debugging only
  Serial.println("Receiving");
  pinMode(13,OUTPUT);
  // Initialise the IO and ISR
  //vw_set_ptt_inverted(true); // Required for DR3100
  vw_setup(2000);	 // Bits per sec
  vw_set_rx_pin(6);
  vw_rx_start();       // Start the receiver PLL running
  
  pinMode(in1Pin, OUTPUT);
  pinMode(in2Pin, OUTPUT);
  pinMode(enablePin, OUTPUT);
}

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

  if (vw_get_message(buf, &buflen)) // Non-blocking
  { 
    digitalWrite(13, HIGH); // Indicate data is being received
    int valBrakes = atoi(strtok((char*)buf, ","));  // Look for a comma, the return the data before it.
    
    
    int valThrottle = atoi(strtok(NULL, ",")); // same as above
    //int temp3 = atoi(strtok(NULL, ".")); // Look for a period, then return data before it.
    Serial.print(valBrakes); // X axis
    Serial.print(", ");
    Serial.print(valThrottle); // Y axis
    Serial.print(", ");
    //Serial.print(temp3); // Z axis
    Serial.println();
    
    setMotor(valThrottle, valBrakes);
  }
  else digitalWrite(13, LOW); // No data received
}

void setMotor(int throttle, int brake)
{
  int pedal ;
  if(throttle){
    pedal = throttle;
    analogWrite(enablePin, throttle);
  }else if (brake){
    pedal = brake;
    analogWrite(enablePin, brake);
  }
  
  digitalWrite(in1Pin, throttle);
  digitalWrite(in2Pin, brake);
}

The array value in the transmitter code is not big enough, to hold the string. valThrottle is 3 chars, the comma is another and valBreaks is 2 more char and the period is another char. (not sure if it includes the null terminator) but make the array size 10, and sprintf(Array,"%d,%d,%d.",valThrottle, valBrakes); has one too many "%d". It should just be sprintf(Array,"%d,%d.",valThrottle, valBrakes);

Added: these two are backwards. int valBrakes = atoi(strtok((char*)buf, ",")); int valThrottle = atoi(strtok(NULL, ",")); Your sending throttle data first, then the brakes.

What is the purpose for pedal?

first i am having an antenna problem or i can say transmission problem (hardware) because when the antenna are far from each other it doesnt work, but when i touch the antenna or make them near each other like a 2 mm distance it works,

Can you provide a link or a picture to your transmitter and receiver?

these are the pictures, as you can see a wire is attached to the receiver and the antenna is in contact with this wire
as for the transmitter, i am using this antenna that can be adjusted from an RC car remote

what do you mean about these are backwards ?

pedal actully has no purpose i will remove it later