Two Arduinos an RC Monster truck and a 4channel long range link

Hi Guys

I decided to upgraded this Transmitter and RC MonsterTruck with some arduino extras, the build was seamless with little problems, the software however as you well know...
i've been debuggin this project for over a week trying to get it working and i have rewritten the code many times, i think that my problem might be that struggling for so long with the same problem might have made me blind to the solution, so I'm hoping someone has some new insight for me.

Here's the setup:
Tansmitter

Monster Truck

Close-up showing the components

Pretty coool huh... :smiley:

Transmitter:
The Transmitter is made up of an Arduino Mini and an Arduino UNO R3
The Arduino UNO is not connected at the moment as it is for display only

The Arduino Mini is connected to:
Pot X1 //Pin A0
Pot X2 //Pin A1
Pot Y1 //Pin A2
Pot Y2 //Pin A3
Switch 1 //Pin 8
Switch 2 //Pin 7
Switch 3 //Pin A7
Switch 4 //Pin A5
Switch 5 //Pin 5
Switch 6 //Pin 3
LED1 //Pin 2
LED2 //Pin 4
LED3 //Pin 13
-433MHz short range transmitter //Pin 11 Short range TX is NOT connected!!
http://www.seeedstudio.com/wiki/433Mhz_RF_link_kit
-433.92MHz long range transmitter //Pins 3, 5, 6, 9 Long range TX IS connected
http://www.seeedstudio.com/wiki/index.php?title=2KM_Long_Range_RF_link_kits_w/_encoder_and_decoder

and
The Arduino UNO is connected to:
-LCD Shield
-Serial Port

Monster Truck Receiver
The Monstertruck setup consists of only one Arduino Nano built onto a UNO type board layout so that it is compatible with motor shield

The Arduino Nano is connected to:
LED Pins //2, 3, 10, 13
-Monster Moto Shield //Pins 4, 5, 6, 7, 8, 9, A0, A1, A2, A3
-433.92MHz long range receiver //Pins 0, 1, A4, A5
http://www.seeedstudio.com/wiki/index.php?title=2KM_Long_Range_RF_link_kits_w/_encoder_and_decoder
-Servo //Pin 11

Ok so that's how it's set up, now i want to ask: "How do i do this?"
I've sucessfully transferred data between the two using VirtualWire as a test but i require the use of a Servo as well and THIS is where my problems come in...

I then tried Software Servo but could not get that working on Arduino IDE 1.0.2 (SoftwareServo compiling error digitalWrite was not declared blah blah...)

I then moved on to EasyTranster, then to SoftEasyTransfer then SoftwareSerial (Still no luck)

Then i tried writing super simple code directly to the transmitter pins ie: digitalWrite for two switches and AnalogWrite for one X and one Y axis, this also didn't work however the VT LED that is hardwired to the receiver does blink indicating that it is receiving something, just not passing the informtion along correctly i suspect...

Ok so with all that said, i can post the code as well if anyone is interested however i think it might be time i try a different approach to Radio Control with Arduino, if youu would like to know anything specific jusst ask

Any Suggestions and/or advice is most welcome
Thanking you all in advance

Best Regards
Renier

I'm a little confused by this entire description, all these processors and RF devices.
To me, it sounds like you got ahead of yourself, hooked up everything and tried to
get it all to work at the same time. The only way to do a project of this complexity
is one step at a time.

  • first, forget about the RF part and the extra controller boards.
  • go to the basics, use 1 controller with "wired link" between Arudino and PC,
    and get your sketches to work, including your servo code.
  • add whatever else you want, controllers or sensors, "except" the RF link.
  • once that's working, then go to using the RF link.

Also, if you're trying to download sketches to the Arduino using this lashup, forget it.
You can't do it. Also, I personally have not had good luck with the SoftSerial libraries,
so I connect the Arduino hardware UART [RX,TX pins] alternately between my PC via
USB, and my RF devices [XBee in this case].

Hi

Thanx for the quick reply

I started by building a small Tracked rover controlled by an Arduino Mini (picture attached below)
along with a Remote control powered by an Arduino UNO R3 and a Joystick shield, the 433MHz RC link that i used had only 1 data channed so Virtual wire & EasyTransferVirtualWire was the best suited for my needs, it worked perfectly.

After i had this working for a while i decided to add an LCD screen, since i had an LCD shield already i used that
i connected the remote control to the LCD shield+Arduino using Easy Transfer for starters over Serial port, and it worked nicely

so after that was all working (seperately) i decided to stick it all together with the Monster truck, added the motor shield, receiver and Arduino and uploaded VirtualWire and EasyTransferVirtualWire and Viola, it worked as well :slight_smile: so far so good...

and then i wanted to add a Servo... and everything started going wrong

so this is my most basic problem/question:
"how do i talk to a servo over RC control?"

See because with my first RF link with only one data line i could only use Virtual wire so that the information is wrapped up and sent at once.
Now i have an long range RF link with 4Channels so i was wondering if there might be a direct and dirty approach like such: Arduino-->4 TX pins-->Transmitter------------>>--------Receiver-->4RX pins-->Arduino
so that i whatever is written onto the TX pins is just spat out the other end without any delays, then the receiver can figure out the data...

i tried the following:
TX Code

char Sw1=8, Sw2=7, Sw3=A7, Sw4=A5, Sw5=12, Sw6=10;

  int X2;      //Right Joystick
  int Y1;      //Left Joystick
  int S1;      //Switch 1
  int S5;      //Switch 5
  
void setup()
{
  Serial.begin(9600);
  
  pinMode(A0, INPUT);      //X1
  pinMode(A1, INPUT);      //X2
  pinMode(A2, INPUT);      //Y1
  pinMode(A3, INPUT);      //Y2

  pinMode(3, OUTPUT);      //Set the Long Range TX Pin 3 as an output
  digitalWrite(3, HIGH);
  pinMode(5, OUTPUT);      //Set the Long Range TX Pin 2 as an output
  digitalWrite(5, HIGH);
  pinMode(6, OUTPUT);      //Set the Long Range TX Pin 1 as an output
  digitalWrite(6, HIGH);
  pinMode(9, OUTPUT);      //Set the Long Range TX Pin 0 as an output
  digitalWrite(9, HIGH);
  
  pinMode(Sw1, INPUT);      //Switch 1
  digitalWrite(8, HIGH);
  pinMode(Sw2, INPUT);      //Switch 2
  digitalWrite(7, HIGH);
  pinMode(Sw3, INPUT);      //Switch 3
  digitalWrite(A7, HIGH);
  pinMode(Sw4, INPUT);      //Switch 4
  digitalWrite(A5, HIGH);
  pinMode(Sw5, INPUT);      //Switch 5
  digitalWrite(12, HIGH);
  pinMode(Sw6, INPUT);      //Switch 6
  digitalWrite(10, HIGH);
  
  pinMode(4, OUTPUT);      //LED TX1
  digitalWrite(4, LOW);
  pinMode(2, OUTPUT);      //LED TX2
  digitalWrite(2, LOW);
  pinMode(13, OUTPUT);      //LED TX3
  digitalWrite(13, LOW);
  
}

void loop()
{
  X2 = analogRead(A1);
  Y1 = analogRead(A3);
  S1 = digitalRead(Sw1);
  S5 = digitalRead(Sw5);
      
  Serial.print(X2);
  Serial.print("  ");     
  Serial.print(Y1);
  Serial.print("  ");
  
  Serial.print(S1);
  Serial.print("  ");
  Serial.print(S5);
  Serial.print("  ");
  
  analogWrite(3, X2);      //D3 Transmitter pin
  analogWrite(5, Y1);      //D2 Transmitter pin
  digitalWrite(6, S1);      //D1 Transmitter pin
  digitalWrite(9, S5);      //D0 Transmitter pin
  
  digitalWrite(4, HIGH);
      digitalWrite(2, LOW);
      digitalWrite(13, LOW);
      delay(60);
      digitalWrite(4, LOW);
      digitalWrite(2, HIGH);
      digitalWrite(13, LOW);
      delay(60);
      digitalWrite(4, LOW);
      digitalWrite(2, LOW);
      digitalWrite(13, HIGH);
      delay(60);
      digitalWrite(4, LOW);
      digitalWrite(2, LOW);
      digitalWrite(13, LOW);
      delay(100);
  
}

RX Code

int X2;      //Right Joystick
  int Y1;      //Left Joystick
  int S1;      //Switch 1
  int S5;      //Switch 5
  
  int direction= 397;
  int steering= 361;
  int val = 0;
  int lights = 0;
  int drive = 0;

void setup()
{
  Serial.begin(9600);
  
  pinMode(2, OUTPUT);      //Lights
  pinMode(3, OUTPUT);      //Lights
  pinMode(10, OUTPUT);      //Lights
  pinMode(13, OUTPUT);      //Lights
  
  pinMode(1, INPUT);      //Lights D0
  pinMode(0, INPUT);      //Drive D1
  pinMode(A4, INPUT);      //D2 
  pinMode(A5, INPUT);      //D3 
  
}

void loop()
{
  X2 = analogRead(A5);      //D3
  Y1 = analogRead(A4);      //D2
  S1 = digitalRead(0);      //D1
  S5 = digitalRead(1);      //D0
  
  direction = Y1;    // FWD/REV
  steering = X2;   //CW/CCW
  lights = S1;
  drive = S5;
  
  Serial.print("  ");     
  Serial.print(X2);
  Serial.print("  ");
  Serial.print(Y1);
  Serial.print("  ");
  
  Serial.print(S1);
  Serial.print("  ");
  Serial.print(S5);
  Serial.print("  ");
  
    if (lights == 1){
    Serial.println("On");
    digitalWrite(2, HIGH);      //Lights
    digitalWrite(3, HIGH);      //Lights
    digitalWrite(10, HIGH);      //Lights
    digitalWrite(13, HIGH);      //Lights
  }
  
  if (lights == 0){
    Serial.println("Off");
    digitalWrite(2, LOW);      //Lights
    digitalWrite(3, LOW);      //Lights
    digitalWrite(10, LOW);      //Lights
    digitalWrite(13, LOW);      //Lights
    }
}

Nice try but it doesn't work.

So having had so much success untill now and facing this small but significant problem with RF and a servo, any advice on what approach to take further?

Thanking you in advance for the help :slight_smile:

Best Regards
Renier

Currently, you are sending binary data over 4 pins.

I think the problem is that you can only send "1"s or "0"s and you are trying to use analogwrite on your TX and analogread on your RX. I think you need to write your code to only use 1 or 0 as for sending and receiving data.

The other choice would be sending serial data over two pins and working out a protocol to parse the information. Such as TX sends "< X2-n, Y1-n, S1-n, S5-n >" to the RX. Rx then will have to separate the information into 4 variables.

  analogWrite(3, X2);      //D3 Transmitter pin
  analogWrite(5, Y1);      //D2 Transmitter pin
  digitalWrite(6, S1);      //D1 Transmitter pin
  digitalWrite(9, S5);      //D0 Transmitter pin
 X2 = analogRead(A5);      //D3 receiver pin
  Y1 = analogRead(A4);      //D2 receiver pin
  S1 = digitalRead(0);      //D1 receiver pin
  S5 = digitalRead(1);      //D0 receiver pin

I am not sure how much help I can be as I suspect we are doing very different things to accomplish the same end. I use a dedicated R/C receiver and transmitter, mine is a 2.4 spectrum but I have also used an old Airtronics fm unit, they work the same. It looks like you are hacking an existing receiver.

My components are

Mega
R/C receiver
ESC
Motor
Servo

Hook Up is

Mega to the receiver
servos to the mega
motor to an ESC
the ESC to the Mega.

The sticks on my R/C transmitter fire up the motor and turn the servo, I have an Uno and it would work the same way.

I will post this to your thread too and add some pictures.

Here is the code I used for the Throttle test, I need to dig up my test code that combines this with the servo for rotation

    // This sketch uses the servo library to arm the Hacker X-5 Pro ESC.
    // beauty works with Castle Creations just fine

    #include <Servo.h>
     
    Servo esc; // Define the ESC as a servo object
     
    int arm = 1000;    // defines pulse width of 1000 us
    int speedvalue = 1000; //should be throttle off
    int speedcalue2 = 1000; // should be throttle off
    int steady = 300;
    int initiate = 0;
    int escPin = 9;
      
   //  RC Reciever control
   
   int ch1; // Here's where we'll keep our channel values
   int current_throttle = 0;
   int Min_throttle = 0;
   
   // Led Stuff
   
    int led = 10;           // the pin that the LED is attached to
    int brightness = 0;    // how bright the LED is
    int pos;
 
     
    void setup()
    {
       // declare pin 10 to be an output for LED:
      pinMode(led, OUTPUT);
      pinMode(5, INPUT); // Throttle on our Receiver
      
      esc.attach(9); 
      esc.writeMicroseconds(arm); // This command sends a pulse train
                                  // from pin 9 that continues until
                                 // the pin is called to do something else.
     
     /*  Once armed the setup could also be used to specify the
         run speed of the motor. The commented out lines provide
         a 2 second delay between changes in speed.
      delay(2000);
      esc.writeMicroseconds(1200);
      delay(2000);
      esc.writeMicroseconds(1300);
      delay(2000);
      esc.writeMicroseconds(1400);
      delay(2000);
     */
     
   //   Enable to put in debugging lines
   //    Serial.begin(9600); // Pour a bowl of Serial
    }

    void loop()
    {
 
      /*
      Calls a sub to throttle up motor from 0 rpm to a steady running value.
      The if statement is used to run the throttle up once.
    */
      while (Min_throttle <= 10)
      {
        current_throttle = pulseIn(5, HIGH, 25000); // get current throttle val
        delay(3000); // give the operator a chance to do something
 
         // there is some bounce on my DX7 this 
         // low point is actually 1095 to 1098
         // 1100 works as a nice high point
 
        if (current_throttle <= 1100)
         {
           Min_throttle = Min_throttle + 1; 
           delay(1000);    // 1 second 
          }
          
          if (current_throttle != pulseIn(5, HIGH, 25000))
           {
            throttleUp();
            initiate = 1;
           }
      }
    
      esc.detach();  // Disengage ESC from pin

    } 
     
     
    //**************************************************
    // Currently a tad slow as I am only increasing by a factor
    // of 1 will have play with this to get the best 
    // speed for throttle up
    
    void throttleUp()
     {
  
      ch1 = pulseIn(5, HIGH, 25000); // Read the pulse width of 
      speedvalue = current_throttle;

      if (speedvalue < ch1)
      {
      for (int count = speedvalue; count < ch1; count++){
        Serial.println(speedvalue);
        digitalWrite(escPin, HIGH);
        esc.writeMicroseconds(speedvalue);
        digitalWrite(escPin, LOW);
        speedvalue = speedvalue + 1;
        delay(20);
      }
     }
      if (speedvalue > ch1)
      {
      for (int count = speedvalue; count > ch1; count--){
        digitalWrite(escPin, LOW);       
        esc.writeMicroseconds(speedvalue);
        speedvalue = speedvalue - 1;
        digitalWrite(escPin, LOW);
        delay(20);
      }
     }

    }

If you are using an all in one unit from the truck then you will have to figure out how it all works, I should add as a R/C helicopter/ plane guy I have spare r/c bits around.

The bits less receiver, I will wire it all up and grab the code and post up later today

Thanx alot!

I'm going to start playing around with that immediately, i see i will have to program my Transmitter to "talk the talk" of a standard transmitter, maybe this is a viable next step.

I'm currently using this 4Channel 433MHz link http://www.seeedstudio.com/wiki/index.php?title=2KM_Long_Range_RF_link_kits_w/_encoder_and_decoder
it has 4 dedicated channels on both TX and RX, so whatever you put in on TX will come out on the RX side.

I just stumbled accross a great website explaining how to read multiple RC channels from a standard Remote control in details http://rcarduino.blogspot.com/ so SO SO close to almost exactly what i need hahaha :wink:

I will keep on fiddling with the code.