Wednesday, May 21, 2014

Glory 3.0 (Code)

Here I left the code for the robot Glory 3.0. There are two codes, one for the robot and the other for the control base. Both codes were made using arduino IDE and using arduino tabs. You have to  instal two libraries for compiling the code, virtualwire and servotimer2. Here I left a zip with the code and the libraries.

Download here


Base Arduino Nano


Arduino_Nano_control

/*******************************************************
 *                Glory 3.0 Code                       *
 * This is the transmitter code.                       *
 *                                                     *
 * Author: Rodrigo Mompó Redoli                        *
 *         with Arduino comunity help                  *
 * Webpage: controlrobotics.rodrigomompo.com           *
 * Email: controlrobotics@rodrigomompo.com             *
 *******************************************************/
#include <LiquidCrystal.h> //Librarys
#include <VirtualWire.h> 

// Variables 
const int Sensor1Pin = A1; // Joystick pins
const int Sensor2Pin = A2;
const int Sensor3Pin = A3;
const int Sensor4Pin = A4; 
const int ledPin = 13;
int selectstatus= 0; 
int Menupag = 1;
int ModoCabeza = 0;
int Laserstatus = 0;
int reading = 0;
int Sensor1Data;
int Sensor2Data;
int Sensor3Data;
int Sensor4Data;
int fire;
long previousMillis;
long currentMillis;

char Sensor1CharMsg[30]; // String were all the varaibles will be stored
LiquidCrystal lcd(8,3,4,5,6,7); // define the pins for the lcd
void setup() {

 // LED 
 pinMode(ledPin,OUTPUT);
 
 // Sensor(s)
 pinMode(Sensor1Pin,INPUT);
 pinMode(Sensor2Pin,INPUT);
 pinMode(Sensor3Pin,INPUT);
 pinMode(Sensor4Pin,INPUT);
 
 pinMode(2,INPUT); // Fire botton 

 lcd.begin(16,2);   // Lcd
 lcd.setCursor(3,0);
 lcd.print("Glory 3.0");
  
 // for debuggin
  Serial.begin(9600); 
 
  // VirtualWire setup
  vw_setup(2000);  // Bits per sec

  delay(1000);
}

void loop() {

  // Read and store Sensor 1 data
  Sensor1Data = analogRead(Sensor1Pin);
  Sensor2Data = analogRead(Sensor2Pin);
  Sensor3Data = analogRead(Sensor3Pin);
  Sensor4Data = analogRead(Sensor4Pin);
  
 //This code is made  to prevent fire several bullets at the same time
currentMillis = millis();
  if(digitalRead(2)== 1 && currentMillis - previousMillis > 1000) {
 
    previousMillis = currentMillis;
  fire = 1;}
  else{fire = 0;}
  //Convert the variables into a string
  sprintf(Sensor1CharMsg, "%d,%d,%d,%d,%d,%d,%d,", Sensor1Data, Sensor2Data, Sensor3Data, Sensor4Data, ModoCabeza, Laserstatus, fire);

  
  //* DEBUG
  Serial.print("Sensor1 Integer: ");
  Serial.print("X");
  Serial.print(Sensor1Data);
  Serial.print("Y");
  Serial.print(Sensor2Data);
  Serial.print("X1");
  Serial.print(Sensor3Data);
  Serial.print("Y1");
  Serial.print(Sensor4Data);
  Serial.print("Sensor1Datamsg");
  Serial.print(Sensor1CharMsg);
  Serial.println("//");

  // END DEBUG*/
 
digitalWrite(13,LOW); // Turn on a light to show transmitting
 vw_send((uint8_t *)Sensor1CharMsg, strlen(Sensor1CharMsg));
 vw_wait_tx(); // Wait until the whole message is gone
  // Turn off a light after transmission
 delay(2);
digitalWrite(13,HIGH); // Turn off a light to show transmitting

reading = analogRead(0); // read the botons 
Serial.println(analogRead(0));// For debug
DisplayData();

} 
DisplayData
void DisplayData(){
// this code lets you select differents menus
  if(reading == 0){
    if(Menupag==3){}
    else{Menupag++;}
  }
  if(reading == 481){ 
    
    if(Menupag==1){}
    else{Menupag--;}
  }
 switch(Menupag){
   case 1:
   Menu1();
   break;
   case 2:
   Menu2();
   break;
   case 3:
   Menu3();
   break;

   
 }
}
Menu1
void Menu1(){
 // This code  display informatión about the movement of the robot 
  int variable =map(Sensor1Data,0,1023,0,3);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Direcion:");
  lcd.setCursor(10,0);
  switch( variable ){
   case 0:
   lcd.print("Atras");
   
   break;
   case 1:
   switch(map(Sensor2Data,0,1023,0,3)){
   case 0:
   lcd.print(" <== ");
   break;
   case 1:
   lcd.print("Stop");
   break;
   case 2:
   lcd.print(" ==> ");
   break;
   }
   
   break;
   case 2:
   lcd.print("Ade");
   break;
   case 3:
   lcd.print("Ade");
   break;
  }
  lcd.setCursor(0,1);
  lcd.print("X: ");
  lcd.print(Sensor1Data);
  lcd.print("  Y: ");
  lcd.print(Sensor2Data);
}
  
Menu2
void Menu2(){
 // this menu display information of the head of the robot
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("ModoCabeza: ");
  lcd.setCursor(11,0);
//This part of the code let's you to select diferent modes for the head
  if(reading == 722){
    switch(ModoCabeza){
     case 0:
     ModoCabeza = 1;
     break;
     case 1:
     ModoCabeza = 2;
     break;
     case 2:
     ModoCabeza = 0;
     break;
    }
  }

  switch(ModoCabeza){
    case 0:
    lcd.print("Movil");
    break;
    case 1:
    lcd.print(" Fijo");
    break;
    case 2:
    lcd.print("Ultra");
    break;
  }
  
  lcd.setCursor(0,1);
  lcd.print("X: ");
  lcd.print(Sensor4Data);
  lcd.print("  Y: ");
  lcd.print(Sensor3Data);
}  
Menu3
void Menu3(){
 // display the laser status and let you chage it
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Laser: ");
  lcd.setCursor(8,0);
  if(reading == 722){
    switch(Laserstatus){
     case 0:
     Laserstatus= 1;
     break;
     case 1:
     Laserstatus = 0;
     break;
    }
  }
  switch(Laserstatus){
    case 0:
    lcd.print("OFF");
    break;
    case 1:
    lcd.print("ON");
    break;
  }
 
}

Robot Glory 3.0 Arduino Mega


Arduino_Mega_en_robot
/*******************************************************
 *                Glory 3.0 Code                       *
 * This is the code that Glory runs. You need also     *
 * a robot controler with the transmitter code.        *
 *                                                     *
 * Author: Rodrigo Mompó Redoli                        *
 *         with Arduino comunity help                  *
 * Webpage: controlrobotics.rodrigomompo.com           *
 * Email: controlrobotics@rodrigomompo.com             *
 *******************************************************/
 
#include <VirtualWire.h>//Librarys
#include <ServoTimer2.h>// You can`t use VirtualWire and Servo library together,
// both use the same Arduino Timer. You nedd to use ServoTimer2.h that use Timer2 of the arduino.

// This code have extracts from differents tutorials on the web that I used long time ago, so I can remmeber the authors 
#define MOTOR1_DIR_PIN  4  // Dir 
#define MOTOR1_PWM   5 // CH2 Left Motor  
  
#define MOTOR2_DIR_PIN  7  // Dir 
#define MOTOR2_PWM   6 // CH3 Right Motor
  
#define MOTOR_DIR_FORWARD  0  
#define MOTOR_DIR_BACKWARD   1
//Variables for Pan/Tilt servomotors
int oneb; int previousoneb; int servo1x;
int twob; int previoustwob; int servo2x;
//Creating servo objects
ServoTimer2 one;
ServoTimer2 two;

// Values from RF
int Sensor1Data;
int Sensor2Data;
int Servo1;
int Servo2;
int ModoCabeza;
int Laser;
int finish;
//Pin for the laser
int Laserpin = 2;
int Canonpin = 3;
int sensorcanon = 8;
int firesensor;
long previousMillis;
long currentMillis;
// RF Transmission container
char Sensor1CharMsg[26]; 


void setup() {
  digitalWrite(Canonpin, HIGH);
  Serial.begin(9600);//For debuggin
  // Setup pins for motor 2  
   pinMode(MOTOR1_DIR_PIN,OUTPUT);   
   pinMode(MOTOR1_PWM,OUTPUT);  
     
  // Setup pins for motor 2  
   pinMode(MOTOR2_DIR_PIN,OUTPUT);  
   pinMode(MOTOR2_PWM,OUTPUT);
  // Sets the digital pins as output
  pinMode(13, OUTPUT);
  pinMode(Laserpin, OUTPUT);
  pinMode(Canonpin, OUTPUT);
  pinMode(sensorcanon, INPUT);

//Attach the servo to enable their use  
one.attach(9);
two.attach(10);
    
    // VirtualWire
    //(see controlrobotics.rodrigomompo.com for more information and tutorials) 
    vw_setup(2000);//Bits per second
    vw_set_rx_pin(11);//Set receiver Pin  
    // Start the receiver PLL running
    vw_rx_start(); 
Serial.print("Ready");//For debuggin

} // END void setup

void loop(){
 
TakingData();//Call a funtion that takes the data from RF 
    
//Control del laser 
if(Laser==1){digitalWrite(Laserpin,LOW);}
else{digitalWrite(Laserpin,HIGH);}

Serial.println(Laser);
MotorControl();//Control the robot motors
// For controling the cannon
currentMillis = millis();
  if(firesensor == 1 && currentMillis - previousMillis > 500) {
    
    previousMillis = currentMillis;
digitalWrite(Canonpin,LOW);
delay(10);
  fire();}

digitalWrite(Canonpin,HIGH);

Serial.print(digitalRead(sensorcanon));
PanTilt();//Loop for controling the Pan/Tilt Head
 
}
Cannon
// This loop runs until the sensor of the cannon it's activeted when a bullet has been shooted
void fire(){
while (digitalRead(sensorcanon) == 0){
digitalWrite(Canonpin,LOW);
 }
}
MotorControl
// This funtion Control the motors
// for moving the robot
void MotorControl(){
int speed1 = map(Sensor1Data,500,69,0,255); 
int speed2 = map(Sensor1Data,500,1023,0,255); 
int variable =map(Sensor2Data,0,1023,0,3);//Take Y coordinate
switch( variable ){
   case 0:
   // The robot go Backward 
   motorStart(1, MOTOR_DIR_BACKWARD);    
   setSpeed(1, 
    100);  
   motorStart(2, MOTOR_DIR_BACKWARD);        
   setSpeed(2, 100);  
   delay(2); 
   
   break;
   case 1:
   // In this case three new posibilities apeared
     switch(map(Sensor1Data,0,1023,0,3)){
     case 0:
      //Robot goes right
        motorStart(2, MOTOR_DIR_BACKWARD);     
          setSpeed(1, speed1);  
        motorStart(1, MOTOR_DIR_FORWARD);        
          setSpeed(2, speed1);
       delay(2); 
       break;
     case 1:
     //Robot stop
       motorStop(1);
       motorStop(2);
       break;
     case 2:
     //Robot goes left
      motorStart(2, MOTOR_DIR_FORWARD);    
         setSpeed(1,speed2);  
      motorStart(1, MOTOR_DIR_BACKWARD);        
         setSpeed(2,speed2 );  
       delay(2);
        break;
   }
   
   break;
   case 2:
  
  // The motor go Fordward
  motorStart(1, MOTOR_DIR_FORWARD);    
  setSpeed(1,100);  
  motorStart(2, MOTOR_DIR_FORWARD);        
  setSpeed(2, 100);  
  delay(2); 
   break;
  }
}
Motor_Control_Funtions
/*Here there are three funtions:
  setSpeed();
  motorStart();
  motorStop();
  
 All funtions are used for motor control 
*/


void setSpeed(char motor_num, char motor_speed)  
{  
   if (motor_num == 1)  
   {  
      analogWrite(MOTOR1_PWM, motor_speed);  
   }     
   else  
   {  
      analogWrite(MOTOR2_PWM, motor_speed);  
   }  
}  
  
void motorStart(char motor_num, byte direction)  
{  
    
   char pin_dir;  
    
     
   if (motor_num == 1)  
   {  
      pin_dir = MOTOR1_DIR_PIN ;  
       
   }     
   else  
   {  
      pin_dir = MOTOR2_DIR_PIN ;  
         
   }  
    
   switch (direction)  
   {  
     case MOTOR_DIR_FORWARD:  
     {  
       digitalWrite(pin_dir,LOW);  
                   
     }  
     break;   
            
     case MOTOR_DIR_BACKWARD:  
     {  
        digitalWrite(pin_dir,HIGH);  
                  
     }  
     break;           
   }  
}  
  
void motorStop(char motor_num)  
{  
   setSpeed(motor_num, 0);  
   if (motor_num == 1)  
   {  
     digitalWrite(MOTOR1_DIR_PIN ,HIGH);  
       
   }  
   else  
   {  
     digitalWrite(MOTOR2_DIR_PIN ,HIGH);  
          
   }  
}  
PanTilt
/*
This funtion control the head with 
the camera and the shootcanon*/

void PanTilt(){


 if(ModoCabeza== 0){  
 int onea = map(Servo1,950,0,2175,600);
 one.write(onea + 50);//vertical
 int twoa = map(Servo2,940,30,600,2000);
 two.write(twoa + 100);// horizontal
 previousoneb = onea;
 previoustwob = twoa;
 }

 if (ModoCabeza == 1){
   
   if(Servo1<350&&previousoneb<2300){oneb = previousoneb+10; one.write(oneb); previousoneb = oneb;}
   if(Servo1>550&& previousoneb>754){oneb = previousoneb-10; one.write(oneb); previousoneb = oneb;}
   if(Servo2<550&&previoustwob<2300) {twob = previoustwob+10; two.write(twob);previoustwob = twob;}
   if(Servo2>400&& previoustwob>754){twob = previoustwob-10; two.write(twob);previoustwob = twob;}
  
   delay(2);
   
 } 
 if (ModoCabeza == 2){
   
   if(Servo1<350&&previousoneb<2300){oneb = previousoneb+3; one.write(oneb); previousoneb = oneb;}
   if(Servo1>550&& previousoneb>754){oneb = previousoneb-3; one.write(oneb); previousoneb = oneb;}
   if(Servo2<550&&previoustwob<2300){twob = previoustwob+3; two.write(twob);previoustwob = twob;}
   if(Servo2>400&& previoustwob>754){twob = previoustwob-3; two.write(twob);previoustwob = twob;}
  

}
delay(10);

}

TakingData
/*This funtion take the data from the RF
and store it in diferent integres for controling 
the robot*/

void TakingData(){ 
 
  //For taking data from RF and store it 
     uint8_t buf[VW_MAX_MESSAGE_LEN];
     uint8_t buflen = VW_MAX_MESSAGE_LEN;
     
 //Taking the data from the control base
     if (vw_get_message(buf, &buflen)) 
     {
  int i; 
         digitalWrite(13,HIGH);
   
         // 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]);}
         
  //A funtion used for taking a string with all the data and convert it in differents number variables 
       sscanf(Sensor1CharMsg, "%d,%d,%d,%d,%d,%d,%d",&Sensor1Data, &Sensor2Data,&Servo1,&Servo2,&ModoCabeza,&Laser,&firesensor); // Convierte un string en un array
       Serial.print("Read"); //For debuggin
       Serial.print(Sensor1CharMsg); //For debuggin

       
    }

 delay(10);
 digitalWrite(13,LOW);  
}

Saturday, May 17, 2014

Glory 3.0, my first robot

After almost 8 month with out any updates because of my studies,I'm back with my robot Glory 3.0. I will update all the documentation and the information about the robot in the following days and some photos.

The reason of uploading this documentation is that the 22 of may, the robot will participate in "Robocampeones", a high-school competition where you have to present the robot with some documentation. I'm going to participate in the freedom event.

Robot History


 The robot started as a personal robot for improving my arduino skills. After 2 years working on it, a friend encourage me to present the robot in this competition in Madrid. So, I started to prepare the robot for the event. The robot has a pan/tilt camera, a shotgun and  is control by Rf. If you read my previous post, you will see the RF 433 Mhz tutorial. This code is used for control the robot through RF

 I will update more information tomorrow, thanks for reading and leave some comments. Please write your sugerence to this email controlrobotics@rodrigomompo.com

Saturday, November 16, 2013

BE MAKER, desde Cero hasta el Internet de las Cosas[Español]

Si eres nuevo en el mundillo de la electrónica y quieres empezar creando proyectos con Arduino, deberías empezar por un Starter Kit. La mayoría de ellos suelen ser caros y cuando finalizas tu aprendizaje sus componentes no son muy útiles en su mayoría.  Borderless Electronics acaba de desarrollar un nuevo Starter Kit llamado  BE MAKER.

BE BOARD
BE MAKER incluye 600 componentes distintos por solo 29$. Ademas incluye una guía completa, con vídeos, para aprender desde cero hasta el Internet de las cosas.Para completar el kit necesitaras una Arduino Leonardo, aunque también puedes comprar la BE BOARD, una Arduino Leonardo que solo cuesta 9$.

En mi opinión, deberías adquirir la BE SHIELD también. Esta shield permite seguir los tutoriales de forma más sencilla, usando menos cables.Ademas, la shield es muy útiles para proyectos futuros porque incluye un puerto  Ethernet y un zócalo para tarjetas microSD. La shield cuesta 15$, aunque si la compras con el pack te costara solo 10$. En el futuro subiré proyectos más avanzados usando la BE SHIELD porque permite realizar proyectos alucinantes sin mucho coste.  

BE SHIELD
Puesdes comprarlo y coloborar con el proyecto aquì http://igg.me/at/bemaker/x/5411932
Si quieres seguir tutoriales más complejos deberías primero aprender a usar el entorno arduino con este kit. En el caso de que sea un usuario más avanzado es una buena oportunidad para comprar un hardware extra a muy buen precio.

Friday, November 15, 2013

BE MAKER, from Zero to Internet of Things

If you are new on electronics and you want to start working with arduino, you should start with a starter Kit. Most kit's are quite expensive and then when you finish your lessons the kit become unuseful. Recently, Borderless Electronics had developed a new starter kit. This kit is called BE MAKER.

BE BOARD
BE MAKER includes 600 different's parts for only 29$. It also  includes a complete guide to learn from zero to Internet of Things, using videos. With the kit you would need an Arduino Leonardo or just buy the BE BOARD. The BE BOARD  works as an Arduino Leonardo but the board only cost 9$

In my opinion, you should buy the BE SHIELD too. The shield permits to use the kit's without using a lot of wires. Furthermore, the shield is very useful for future projects, because includes an Ethernet port and a SD Card holder. The shield costs about 15$,but  with some packages it only costs10$. I will update some tutorials using this shield because it will  allow me to prepare some coll stuff.

BE SHIELD
You can buy it and collaborate with the project here http://igg.me/at/bemaker/x/5411932
If you want to  go trough the advanced tutorials you should learn with this kit first. Also, If you are an advanced user, the kit is a big deal if you want
to have extra hardware.

Sunday, October 20, 2013

Tutorial: Battery charge indicator

If you have your own robot, you will see that you run out of battery at the worst moment. You can prevent this problem using a  Battery charge indicator. You only have to build an easy circuit that uses the integrated circuit LM339N. With this integrated circuit  you will have a Battery charge indicator with five different's levels of charge. Also, in this tutorial we will see how to prepare this circuit to connect it  on an Arduino.

This circuit is calculated for 7.2 volts batteries. That means that ONLY works with 7,2 volts. If you need a Battery charge indicator  for other batteries, you have to change the resistors. I can upload a post, if you ask for them on the comments.

Materials

  • LM339N
  • L7805CV
  • Variable Resistor 2KOhms
  • 3 X 220 Ohms Resistor
  • 8.2 KOhms Resistor
  • 4.7 KOhms Resistor
  • 4 leds (with diferent color will look better)

The circuit

Here is a diagram with all the connections that we had to made. I recommend to test it on a protoboard before make any soldering.

Setting up

Before using it we have to calibrate the Battery charge indicator. To calibrate we have to connect a full charge battery and move the variable resistor until all the led's are switched on. Then you have a practical Battery charge indicator! If you have  four led's on your battery is full charge and when all led's are off you have to change the batteries. 

Soldering and preparing for Arduino

Two circuits in the same board
In my case I have two independents  circuits on the same PCB. I also added a switch that permits to use the circuits with out powering the leds. Instead of that, you can connect four wires ( one per each led) to the arduino and print the battery status wherever you want. It just work like a switch, you can get 0 (led off) or 1 (led on).

Please leave a comment an subscribe for new tutorials. You can send your ideas or projects to controlrobotics@rodrigomompo.com

Tuesday, October 8, 2013

Sending floats using VirtualWire

We have a problem when we want to send floats using Virtual Wire.If you read the previous tutorials, and you tryed to send floats, you probably got ? .Arduino haven`t got enought power for using all functions with floats. Some functions like sscanf or sprintf are implanted but with out all the functions. You can send strings, ints but not floats because the hardware isn't enought powerfull to suport this part of the function.

 What can we  do?

Well, insted of sending floats we can convert the data into an string, send it and then, in the receiver, convert into a float again . This will be very easy using this function

dtostrf (double __val, signed char __width, unsigned char __prec, char *__s);

For more information: http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga060c998e77fb5fc0d3168b3ce8771d42

In the receiver when we get the string we have to use the following lines of code:

char floatbuf[32]; // make this at least big enough for the whole string
stringwithfloat.toCharArray(floatbuf, sizeof(floatbuf));
float f = atof(floatbuf);

Thursday, September 19, 2013

Tutorial: Arduino + Kit rf 433Mhz (Part4: Multiple variables)

In the final part of this tutorial we will see how to send multiple variables using virtual wire. Let's start then.

There are a lot of forms to send multiple variables trough virtual wire. However,if we want to send different types of data or just send some int's, we can do in the same way, with this code.

Transmitter

With Virtual Wire we can only send an string. So if we want to send other types of data, we need to convert this data into a string.

Fortunately, there are a function to do this. Here is the following  line of code that we have to add.

// Function sprintf
 sprintf(Stringtosend, "%d,%d,%d,%d,", Variable1, Variable2, Variable3, Variable4);
The funcion sprintf converts differents types of data into a string. The función works like this:
sprintf(Stringtosend, specifier of the type of data, data);

specifierOutputExample
d or iSigned decimal integer392
uUnsigned decimal integer7235
oUnsigned octal610
xUnsigned hexadecimal integer7fa
XUnsigned hexadecimal integer (uppercase)7FA
fDecimal floating point, lowercase392.65
FDecimal floating point, uppercase392.65
eScientific notation (mantissa/exponent), lowercase3.9265e+2
EScientific notation (mantissa/exponent), uppercase3.9265E+2
gUse the shortest representation: %e or %f392.65
GUse the shortest representation: %E or %F392.65
aHexadecimal floating point, lowercase-0xc.90fep-2
AHexadecimal floating point, uppercase-0XC.90FEP-2
cCharactera
sString of characterssample
pPointer addressb8000000
nNothing printed.
The corresponding argument must be a pointer to a signed int.
The number of characters written so far is stored in the pointed location.
%% followed by another % character will write a single % to the stream.%

In the table we see the different specifiers  for all the types of data. Using this funcion we can also send an integer and a floating point

sprintf(Stringtosend, "%d,%f,", integer, floatingpoint);

For more information you can see the C++ reference http://www.cplusplus.com/reference/cstdio/printf/

Transmitter Example 


/*.............................................................
Sending Multiple Variables Using VirtualWire. Transmitter
Author: Rodrigo Mompo Redoli
For controlrobotics.rodrigomompo.com
..............................................................*/
#include <VirtualWire.h>

int Sensor1Pin = A1;// The pins were sensor are attached
int Sensor2Pin = A2;
int Sensor3Pin = A3;
int Sensor4Pin = A4; 
int ledPin = 13;
int Sensor1Data;// The variable were the data from each sensor
int Sensor2Data;// will be stored 
int Sensor3Data;
int Sensor4Data;
char Sensor1CharMsg[21];// The string that we are going to send trought rf 

void setup() {

 // LED 
 pinMode(ledPin,OUTPUT);
 
 // Sensor(s)
 pinMode(Sensor1Pin,INPUT);
 pinMode(Sensor2Pin,INPUT);
 pinMode(Sensor3Pin,INPUT);
 pinMode(Sensor4Pin,INPUT);
 
 // VirtualWire setup
 vw_setup(2000); // Bits per sec
 vw_set_tx_pin(12);// Set the Tx pin. Default is 12

}

void loop() {
  
  // Read and store Sensor Data
  Sensor1Data = analogRead(Sensor1Pin);
  Sensor2Data = analogRead(Sensor2Pin);
  Sensor3Data = analogRead(Sensor3Pin);
  Sensor4Data = analogRead(Sensor4Pin);
  
  sprintf(Sensor1CharMsg, "%d,%d,%d,%d,", Sensor1Data, Sensor2Data, Sensor3Data, Sensor4Data);
 
 // Turn on a light to show transmitting
 vw_send((uint8_t *)Sensor1CharMsg, strlen(Sensor1CharMsg));
 vw_wait_tx(); // Wait until the whole message is gone
 // Turn off a light after transmission
 delay(40);

}

Receiver

Now we must be able to send an string and receive it. However ,with this string you can't do anything unless you discompose it and storage on differents variables.For this new challenge we are going to use another function.

 sscanf(StringReceived, "%d,%d,%d,%d",&Sensor1Data, &Sensor2Data,&SeensorData3,&SensorData4);

This function is the opposite of sprinft, and let´s you to storage the information on differents variables. Compile the  receiver code and add some cool things that use this data.

At the end of the code you should erase all the previous data from the string where the new string is storage, so you must call this function

 memset( StringReceived, 0, sizeof( StringReceived));// This line is for reset the StringReceived

Receiver Example

/*.............................................................
Sending Multiple Variables Using VirtualWire. Receiver
Author: Rodrigo Mompo Redoli
For controlrobotics.rodrigomompo.com
..............................................................*/
#include <VirtualWire.h>
 
// Sensors 
int Sensor1Data;
int Sensor2Data;
int SensorData3;
int SensorData4;
 
char StringReceived[22]; 
 
 
 
void setup() {
    // VirtualWire 
    // Initialise the IO and ISR
    // Required for DR3100
 
    // Bits per sec
    vw_setup(2000);
    vw_set_rx_pin(11);  
     
    // 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;
     
//Taking the data from the control base
    if (vw_get_message(buf, &buflen)) 
    {
 int i;
        // Message with a good checksum received, dump it. 
        for (i = 0; i < buflen; i++)
 {            
          // Fill Sensor1CharMsg Char array with corresponding 
          // chars from buffer.   
          StringReceived[i] = char(buf[i]);
 }
 
      sscanf(StringReceived, "%d,%d,%d,%d,%d,%d",&Sensor1Data, &Sensor2Data,&SensorData3,&SensorData4); // Converts a string to an array
         
        // Turn off light to and await next message 
        
    }
 
 memset( StringReceived, 0, sizeof( StringReceived));// This line is for reset the StringReceived
}
Please leave some comments, and send your ideas for new posts in this blog. Also, If you have a project you can publish it on my blog. Subscribe and add me to your Google plus circles.