Connecting Processing to 2 Arduinos using RF Modules (DC fan and Servo control)

Hey Guys,

I have this uni project that i am stuck at.
I am trying to make a wireless connection between 2 arduinos using an RF module, to control a servo and a DC fan simultaneously, so one arduino is the transmiter (TX) and the other is the reciever(RX) connected to the servo and the dc fan.

I have managed to make them work with the serial monitor commands, but because the interface would be a bit crude, i want to use processing to control the Transmitter arduino with a nicer interface.

I have tried 2 main combinations of scripts: the 1st used virtualwire library and the 2nd one uses RCSwitch library. I get no error messages.

In both cases there are problems:(otherwise i wouldnt be posting this right?)

in the 1st one: 01 (attached as _My VersionServoFan_Doesntwork.rar)

When a command is issued to be sent by the transmiter, it blocks (i have put a comand to light up a led before sending and to unlight it after it is done sending) in the sending process. Theres is no response from the reciever.

in the 2nd one: (attached as 04_RCSwitch.rar)

The reciever arduino responds well but the sending of a message takes like 2-3sec. which is not bad for what i managed to achieve. This i tested with leds. So when i attached at servo it also worked fine.
However, when i attach a DC motor (to tell him to go and then stop), i cannot send any other commands. It wont respond to the brake command, and the servo does not react. In fact, (again, i use leds to check if its receiving anything) it simply does not recieve anything else, it is just blocked.

I have been looking into this for a while, but i just can’t seem to get it to work. If any of you could help me, that would be really amazing.

Maybe rf modules are no good for something like this, maybe it is processing’s fault. The weird thing is, that the 2 arduinos work fine by their own, so does processing connected to one arduino. However, when i try to integrate the whole thing it just doenst want to work.

Any help will be welcomed!

04_RCSwitch.zip (3.07 KB)

01_My VersionServoFan_Doesntwork.zip (2.98 KB)

Please post your code using code tags (top row 7 icons from right). I, for one, will not download code. What is connected to the PC to receive RF?

Perhaps your DC motor disturbs RF connection or the supply voltage. A separate power source for motors is always a good idea.

Then test what happens if you manually switch the motor on - does it affect the RF communication?

groundfungus here are the codes:

The 1st one:

Processing code: uses an interface to send a simple message (like just a ‘1’ or a ‘2’) to the arduino transmitter

import processing.serial.*;

Serial myPort;  // Create object from Serial class

void setup() 
{
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);
}

void draw() {
 if (keyPressed){
   if(key=='1'||key=='1'){
     fill(0); //blck
     myPort.write (49);
     delay (10);
 }
 
   if(key=='2'||key=='2'){
     fill(1); //blck
     myPort.write (50);
     delay (10);
 }
 
   if(key=='3'||key=='3'){
     fill(2); //blck
     myPort.write (51);
     delay (10);
 } 
 
    if(key=='4'||key=='4'){
     fill(3); //blck
     myPort.write (52);
     delay (10);
 } 

    if(key=='5'||key=='5'){
     fill(4); //blck
     myPort.write (53);
     delay (10);
 }  
 
}else  {
    fill(255); //white
}
rect (25, 25, 50, 50);
}

Arduino transmitter code: Receives a simple message from processing using a serial connection, reads it (using if/else) and sends the corresponding bit to the reciever arduino

//This is the transmitter, that recieves from Processing and sends to the other arduino

int myData = 0;
int const ledpin1 =13;

#include <VirtualWire.h>

void setup() {

  Serial.begin(9600); 
  Serial.println("setup");   // Initialise the IO and ISR
    vw_set_tx_pin(7);        // Transmitter at Digital Pin 7
    
  // set the digital pin for the led as output
  pinMode(ledpin1,OUTPUT);
 
}//close setup

void loop() {
  
if(Serial.available() >0){  
  
  myData =Serial.read();
  
    if(myData == '1'){
    digitalWrite(ledpin1, HIGH);
    Serial.print(myData);
        
    char *msg2 = "a";
    vw_send((uint8_t *)msg2, strlen(msg2));//send byte to the receiver
    vw_wait_tx(); // Wait until the whole message is gone
    
    digitalWrite(ledpin1, LOW);
    
  }
    
    if(myData == '2'){
    digitalWrite(ledpin1, HIGH);
    Serial.print(myData);
    
    char *msg2 = "s";
    vw_send((uint8_t *)msg2, strlen(msg2));//send byte to the receiver
    vw_wait_tx(); // Wait until the whole message is gone
    
    digitalWrite(ledpin1, LOW);
    
    }
    
    if(myData == '3'){
    digitalWrite(ledpin1, HIGH);
    Serial.print(myData);
    
    char *msg2 = "1";
    vw_send((uint8_t *)msg2, strlen(msg2));//send byte to the receiver
    vw_wait_tx(); // Wait until the whole message is gone
    
    digitalWrite(ledpin1, LOW);
    
    }
    
    if(myData == '4'){
    digitalWrite(ledpin1, HIGH);
    Serial.print(myData);
    
    char *msg2 = "2";
    vw_send((uint8_t *)msg2, strlen(msg2));//send byte to the receiver
    vw_wait_tx(); // Wait until the whole message is gone
    
    digitalWrite(ledpin1, LOW);
    
  
    }
 
    if(myData == '5'){
    digitalWrite(ledpin1, HIGH);
    Serial.print(myData);
    
    char *msg2 = "0";
    vw_send((uint8_t *)msg2, strlen(msg2));//send byte to the receiver
    vw_wait_tx(); // Wait until the whole message is gone
    
    digitalWrite(ledpin1, LOW);

    } 
  }
}

Arduino Reciever Code: this one recieves the bit from the transmiter and controls the servo and the dc fan (using an arduino motorshield: (http://www.instructables.com/id/Arduino-Motor-Shield-Tutorial/?lang=pt&ALLSTEPS), that simplifies the hardware setup)

// RECIEVER CODE
//
//Serial port COM6, the second one after the phone jack. 
//
//Servo library doesnt work, so SerrvoTimer2 is used. With this library only ms work with the write ()
//command. Values of ms range from 544 to 2400
//
//DC Motor commands do not work but servo does. I did not understand the reason yet. Maybe theres a conflict
//between the libraries.
//
//DC MOTOR CONTROL
//Using the Motor Shield, the pins will be as follow 
//
//Function	  Channel A	  Channel B
//Direction	  Digital 12	  Digital 13
//Speed (PWM)	  Digital 3	  Digital 11
//Brake	          Digital 9	  Digital 8
//Current Sensing Analog 0	  Analog 1


  #include <VirtualWire.h>
  #include <ServoTimer2.h>

ServoTimer2 servoMain; // Define our Servo


void setup()
{
    Serial.begin(9600);	// Debugging only
    Serial.println("setup");
    // Initialise the IO and ISR
    vw_setup(2000);	 // Bits per sec
    vw_set_rx_pin(7);//Receiver at Digital Pin 7
    vw_rx_start();// Start the receiver PLL running

//SERVO SETUP
    servoMain.attach(5); // servo on digital pin 5

//DC MOTOR SETUP on Channel A

  pinMode(12, OUTPUT); //Initiates Motor Channel A pin
  pinMode(9, OUTPUT); //Initiates Brake Channel A pin
  
 
}//close setup

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;

        digitalWrite(13, true); // Flash a light to show received good message
	// Message with a good checksum received, dump it.
	
	for (i = 0; i < buflen; i++)
	{
	    Serial.print(buf[i]);

        //Servo commands
        if(buf[i] == 'a')
        {
          servoMain.write(1250);//Selects smell a
        }
        if(buf[i] == 's')
        {
          servoMain.write(2100);//Selects smell s
        }
        
        //DC Fan commands
        if(buf[i] == '1')
        {
	  halfPower();
          
        }
        if(buf[i] == '2')
        {
          fullPower();
        }
        if(buf[i] == '0')
        {
          brake();
          
        }
        }//close for loop
	
        digitalWrite(13, false);

   }//close main if
}//close loop
//you can print the data entered when debugging by adding Serial.println

////////////////////////////////////////////////////////////////////////////////////////

void halfPower()
{
 
  digitalWrite(12, HIGH); //Establishes Forward direction of Channel A
  digitalWrite(9, LOW);   //Disengage the Brake for Channel A
  analogWrite(3, 200);   //Spins the motor on Channel A at 70% power
  }
  
void fullPower()
{
 
  digitalWrite(12, HIGH); //Establishes BackWard direction of Channel A
  digitalWrite(9, LOW);   //Disengage the Brake for Channel A
  analogWrite(3, 255);   //Spins the motor on Channel A at Full power
  }
  
void brake()
{
  digitalWrite(9, HIGH);   //Engages the Brake for Channel A
  }
//End Of Code

So like i said, this version uses the virtualwire library for the rf module. What happens when i issue a command in processing is that the system just looks like it jams, and the reciever part doesnt seem to recieve anything.

groundfungus these are the codes for the 2nd version

Processing code(pretty much looks the same, with tiny diferences):

import processing.serial.*;

Serial myPort;  // Create object from Serial class

void setup() 
{
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);
}

void draw() {
 if (keyPressed){
   
   if(key=='1'||key=='1'){
     fill(0); //blck
     
     myPort.write ('1');
     delay (10);
 }
 
   if(key=='2'||key=='2'){
     fill(1); //blck
     
     myPort.write ('2');
     delay (10);

 }
  
   if(key=='3'||key=='3'){
     fill(1); //blck
     
     myPort.write ('3');
     delay (10);

 }
   if(key=='4'||key=='4'){
     fill(1); //blck
     
     myPort.write ('4');
     delay (10);

 }
    if(key=='0'||key=='0'){
     fill(1); //blck
     
     myPort.write ('0');
     delay (10);

 }
else  {
    fill(255); //white
}
rect (25, 25, 50, 50);

}

}

Arduino Transmitter code:

#include <RCSwitch.h>

//This is the transmitter, that recieves from Processing and sends to the other arduino
char myData; //Variable to manage the if else
int const ledpin = 4; //This pin will have a led attached so i can check if this module
                      //is recieving data from processing and transmitting to the other arduino

//Prepares the RCSwitch libray
RCSwitch mySwitch = RCSwitch();



void setup() {

  Serial.begin(9600); 

  // set the digital pin for the led as output
  pinMode(ledpin,OUTPUT);
 
  //Enable pin 10 to transmit data
  mySwitch.enableTransmit(10);
  delay(50);
  
}//close setup


void loop() {
  
  if(Serial.available() >0){ //if data is available to read  
  
  myData =Serial.read(); //read it and store it myData
  
    if(myData == '1'){
    digitalWrite(ledpin, HIGH); //light the led
    mySwitch.send(1, 24);  //send signal
    digitalWrite(ledpin, LOW); //kill the led1
  
    }
    
    if(myData == '2'){
    digitalWrite(ledpin, HIGH); //light the led
    mySwitch.send(2, 24); //send signal
    digitalWrite(ledpin, LOW); //kill the led
    
    }
    
    if(myData == '3'){
    digitalWrite(ledpin, HIGH); //light the led
    mySwitch.send(3, 24); //send signal
    digitalWrite(ledpin, LOW); //kill the led
    
    }
    
    if(myData == '4'){
    digitalWrite(ledpin, HIGH); //light the led
    mySwitch.send(4, 24); //send signal
    digitalWrite(ledpin, LOW); //kill the led
    
    }
    
    if(myData == '0'){
    digitalWrite(ledpin, HIGH); //light the led
    mySwitch.send(0, 24); //send signal
    digitalWrite(ledpin, LOW); //kill the led
    
    }
  }
}

And finally, the arduino reciever code:

#include <RCSwitch.h>
#include <ServoTimer2.h>

ServoTimer2 servoMain; // Define our Servo

RCSwitch mySwitch = RCSwitch();

int ledpin2 = 10; //This pin will have a led attached so i can check if this module is recieving


int value = -1;


void setup()
{
   //Serial.begin(9600);// Debugging only, this could be removed
   //delay(50); //delay stabilizes the signal
   
   pinMode (ledpin2, OUTPUT); //Set the digital outs as outputs for the leds
   
   
   mySwitch.enableReceive(0); //Define the receiver as 0 which is equivelent to pin 2
   
   servoMain.attach(5); // servo on digital pin 5
   
   //DC fan setup
   pinMode(12, OUTPUT); //Initiates Motor Channel A pin
   pinMode(9, OUTPUT); //Initiates Brake Channel A pin
 
}//close setup

void loop()

  {
   
   if (mySwitch.available()) { //When signal is available
  
   value = mySwitch.getReceivedValue(); //Reads the status and saves it in value int
 
     if (value == 0) {
          //Serial.println("Unknown Value"); //Again, debugging only
         
     }   

//------------------------------------------------------

     if(value ==1){  
        //Serial.println(mySwitch.getReceivedValue()); //debug
        digitalWrite(ledpin2, HIGH);
        servoMain.write(1250);//Selects smell 1
        delay (1000);
        digitalWrite(ledpin2, LOW);
        delay (1000);
        
      }
       
       
    if(value ==2){  
        //Serial.println(mySwitch.getReceivedValue());  //debug
        digitalWrite(ledpin2, HIGH);
        servoMain.write(2100);//Selects smell 2
        delay(1000);
        digitalWrite(ledpin2, L4OW);
        delay(1000);
        
      }
 
    if(value ==3){ //HALF POWER  
        //Serial.println(mySwitch.getReceivedValue());  //debug
        digitalWrite(ledpin2, HIGH);
        
        halfPower();
  
        delay(1000);
        digitalWrite(ledpin2, LOW);
        delay(1000);
     
      }
      
      if(value ==4){  //FULL POWER
        //Serial.println(mySwitch.getReceivedValue());  //debug
        digitalWrite(ledpin2, HIGH);
        
        fullPower();
        
        delay(1000);
        digitalWrite(ledpin2, LOW);
        delay(1000);
     
      }
      
      if(value ==0){  //BRAKE
        //Serial.println(mySwitch.getReceivedValue());  //debug
        digitalWrite(ledpin2, HIGH);
        
        
        brake();
        
        delay(1000);
        digitalWrite(ledpin2, LOW);
        delay(1000);
     
      }
 mySwitch.resetAvailable();
       
    } //Close the if of mySwitch.available

} //Close void loop

/////////////////////////////////////////

void halfPower()
{
 
  digitalWrite(12, HIGH); //Establishes Forward direction of Channel A
  digitalWrite(9, LOW);   //Disengage the Brake for Channel A
  analogWrite(3, 200);   //Spins the motor on Channel A at 70% power
  }
  
void fullPower()
{
 
  digitalWrite(12, HIGH); //Establishes BackWard direction of Channel A
  digitalWrite(9, LOW);   //Disengage the Brake for Channel A
  analogWrite(3, 255);   //Spins the motor on Channel A at Full power
  }
  
void brake()
{
  digitalWrite(9, HIGH);   //Engages the Brake for Channel A
  }

So like i said, for just controlling the servo this code works. When the dc motor is included it jams like i explained on the first post.
However, the sending of the message takes a while until it is finished

DrDiettrich: Perhaps your DC motor disturbs RF connection or the supply voltage. A separate power source for motors is always a good idea.

Then test what happens if you manually switch the motor on - does it affect the RF communication?

Ok i just learned this response feature on forums, im new in these things.

You might have a point there DrDiettrich but the weird thing is that when i used virtual wire without processing there was no absolutely no problem with lack of power. So it leads me to thing that the problem is with processing. However, i did not test the RCSwitch library without the processing part, so maybe that could be related to the issue. Is it possible that the kind of library may have an effect on the current that goes to the dc fan? Also that is what the motorshield is design to do right? to make several motors work at the same time.

Anyways, i'd like to thank both of you groundfungus and DrDiettrich for your help. I really need this to work otherwise my graduation this summer is at stake, and thats more money i have to pay on tuition. So you're help is very valuable! ;)

I am not familiar with the libraries that you are using, but based on your description I’ll hazard a guess.

When the dc motor is included it jams like i explained on the first post.

The servo library that comes with the IDE takes over Timer 1 (which is why you used timer2 version) So analogWrite is not available on pins 9 (OC1A) and 10 (OC1B). Timer2 uses pin 3 (OC2B) so analogWrite may be disabled for that pin. Can you try a different PWM pin for speed control (not 11, OC2A)?