Monday, April 11, 2016

RC Hobby Controllers and Arduino

Remote Control Arduino
Robots, cars, robot cars, and the sport needs some degree of remote control devices of all sorts. Most of the time, do it yourself, or some other XBee wireless technology to implement this test. Sometimes it is not a bad idea, but it is more often than not driven and somewhat frustrating way to see more from them. If you find yourself thinking, "I just put the stick RC car battery to push and move it, I remember the good old days."


Well, welcome back to the good old days.
RC transmitter / receiver combos, easy and cheap to seriously tricked out of the range, but the nice thing about them is that they are a standard, all of the staff makes them essentially interchangeable. It turns out that an RC receiver to connect your Arduino project is the same as connecting to a server, and as easy to code. In this tutorial, I will use your Arduino to interpret commands from a remote base in the RC will be, so you can control some of your favorite processed sketch of a simple four-wheeled robot!

That sounds great, but I've never touched an RC transmitter ...
It's no big deal, I'll walk you through it. Radio control transmitter and receiver, usually the model is used to drive a car or plane. A typical transmitter of control surfaces, wheels or joystick, as well as some would like a switch or dial. Each degree of freedom that the controller is assigned to a channel. In other words, since a joystick or a dial switch will cover one of the two channels (x and y) across. RC transmitter is usually somewhere between four and six of these channels.

Since most of the models of RC servos can be generalized as a fancy box, that's exactly what the receiver is set up to control. Server header in a row: they come in different shapes and sizes, they all share a common feature. These headers are lined up so that the servos in your model can be plugged directly into the receiver. Arduino, because it is the "Server Language" and explains how it can decide to use this handy you can plug in the receiver.

Let's Hook it up!
OK, that's the spirit! We have to get a feel for what looks like a transmitter input from the RC receiver will hook up a few channels. RC transmitter / receiver pair have six channels, but we'll just hook up three. We need these three digital input pins, as well as the receiver, it means the ability to 5V. Here's how I have mine hooked up to a diagram:
RC Hobby Controllers and Arduino
RC Hobby Controllers and Arduino
Note that the RC receiver upside-down, it's easy for me to flip my doll to trace. You can use the male-female jumper if you need to have them. If not, you get stuck with some men and women can use the jumper. I chose the digital pins that are pretty much arbitrary; Arduino that you want to use any of the digital inputs should be able to, but should correspond to the bottom of the code.

Now, upload a sketch and see the pins coming in. "Server" is the language that is really pushing out the RC receiver PWM, or pulse width modulation. Arduino is a convenient function to read the pulse and there is built-in to return to their length in milliseconds. PulseIn This function is called (). A simple sketch that I've written to print the serial input of the monitor receiver provisional Let's take a look at:


     
/*
 RC PulseIn Serial Read out
 By: Nick Poole
 SparkFun Electronics
 Date: 5
 License: CC-BY SA 3.0 - Creative commons share-alike 3.0
 use this code however you'd like, just keep this license and
 attribute. Let me know if you make hugely, awesome, great changes.
 */
 
int ch1; // Here's where we'll keep our channel values
int ch2;
int ch3;

void setup() {

  pinMode(5, INPUT); // Set our input pins as such
  pinMode(6, INPUT);
  pinMode(7, INPUT);

  Serial.begin(9600); // Pour a bowl of Serial

}

void loop() {

  ch1 = pulseIn(5, HIGH, 25000); // Read the pulse width of
  ch2 = pulseIn(6, HIGH, 25000); // each channel
  ch3 = pulseIn(7, HIGH, 25000);

  Serial.print("Channel 1:"); // Print the value of
  Serial.println(ch1); // each channel

  Serial.print("Channel 2:");
  Serial.println(ch2);

  Serial.print("Channel 3:");
  Serial.println(ch3);

  delay(100); // I put this here just to make the terminal
              // window happier
}


PulseIn () function takes three arguments: the first pin that is on your pulse; What you're looking for is a kind of second pulse; And the third is a time-out number, which is how long you're willing to wait for a pulse. What is the function of microsecond pulse length, and the way we read the incoming PWM as if we were going to a server. When you run this code, you should be spitting out onto some of the terminals. Perhaps you mean you do not have a lot of numbers, but they should be somewhere between 1000 and 2000 the number associated with what is really important is that when you move the control surface, it should not be changed. If you do not know what channels are in every part of the transmitter, this is a good way to find out: Just stick, push buttons, knobs to turn and flip the switch, and the swung note, which channels are affected.

Now we have these standards, we can work with them and all kinds of codes. This is my sketch after sketch below pulseIn () in the context of the changing values.

     
/*
 RC PulseIn Joystick
 By: Nick Poole
 SparkFun Electronics
 Date: 5
 License: CC-BY SA 3.0 - Creative commons share-alike 3.0
 use this code however you'd like, just keep this license and
 attribute. Let me know if you make hugely, awesome, great changes.
 */

int ch1; // Here's where we'll keep our channel values
int ch2;
int ch3;

void setup() {

pinMode(5, INPUT); // Set our input pins as such
pinMode(6, INPUT);
pinMode(7, INPUT);

Serial.begin(9600); // Pour a bowl of Serial

}

void loop() {
  
  ch1 = pulseIn(5, HIGH, 25000); // Read the pulse width of
  ch2 = pulseIn(6, HIGH, 25000); // each channel
  ch3 = pulseIn(7, HIGH, 25000);
  
  if(ch1>1000){Serial.println("Left Switch: Engaged");}
  if(ch1<1000){Serial.println("Left Switch: Disengaged");}
  /* I found that Ch1 was my left switch and that it
  floats around 900 in the off position and jumps to 
  around 1100 in the on position */

Serial.print("Right Stick X:"); // Ch3 was x-axis
Serial.println(map(ch3, 1000,2000,-500,500)); // center at 0

Serial.print("Right Stick Y:"); // Ch2 was y-axis
Serial.println(map(ch2, 1000,2000,-500,500)); // center at 0

Serial.println(); //make some room

delay(100);// I put this here just to make the terminal
           // window happier
}


Here you can see that I've figured out my transmitter, which controls channel control surface which, in plain English, and I have a few print statements that have written on the transmitter will be reflected in my work. You can extend the receiver for each channel, with Firmata to replace the sketch and your RC transmitter can control a Processing sketch, but I think I can give a good demonstration of the robot is to drive it around and slap this thing on . So let's get it!

Rig radio receiver robot?
I Ardumoto robot platform chassis and motor driver shield wizard for me to be selected for this project. Since it has only two wheels, differential steering and a good way to show that not everything is easy to mix. The first thing we do prototyping header, which we added to the header shield Ardumoto receiver to create a change in the slope of an impromptu "REMoto" If you're going to play:

RC Hobby Controllers and Arduino
RC Hobby Controllers and Arduino

I made three, six rows, because my six-channel transmitter and receiver, as long as you are running the server header on battery power and ground should not be necessary to connect the header. When you solder in mind that your receiver is going to descend on the upside in this sport, and wire it accordingly. How do you see the picture above, I should be able to visit one of these wired. Land row all together and bridge plug into the ground - and then each signal pin to a digital pin is broken out - with the same power range. This mode is not clear, but it works quite well. The robot chassis is connected with the receiver RC in our changing Ardumoto Shield and what looks like:

RC Hobby Controllers and Arduino
RC Hobby Controllers and Arduino

Not bad, right? It's almost time to drive these things because you are sure that the motor is connected properly and make sure to add a power supply (9V battery good for me). Just step left-right-left motor commands / steering commands to the server to translate is to write some code. I now give you code, and it'll explain below.


     
/*
 RC PulseIn Joystick Servo Control
 By: Nick Poole
 SparkFun Electronics
 Date: 5
 License: CC-BY SA 3.0 - Creative commons share-alike 3.0
 use this code however you'd like, just keep this license and
 attribute. Let me know if you make hugely, awesome, great changes.
 */

int ch1; // Here's where we'll keep our channel values
int ch2;
int ch3;

int move; // Forward/Back speed
int turn; // Turning Factor

int pwm_a = 3; //PWM control for motor outputs
int pwm_b = 11; //PWM control for motor outputs
int dir_a = 12; //direction control for motor outputs
int dir_b = 13; //direction control for motor outputs

void setup() {

pinMode(5, INPUT); // Set our input pins as such
pinMode(6, INPUT);
pinMode(7, INPUT);

Serial.begin(9600); // Pour a bowl of Serial (for debugging)

  pinMode(pwm_a, OUTPUT); //Set control pins to be outputs
  pinMode(pwm_b, OUTPUT);
  pinMode(dir_a, OUTPUT);
  pinMode(dir_b, OUTPUT);

  analogWrite(pwm_a, 0);
  analogWrite(pwm_b, 0);
}

void loop() {
  
  ch1 = pulseIn(4, HIGH, 25000); // Read the pulse width of
  ch2 = pulseIn(5, HIGH, 25000); // each channel
  ch3 = pulseIn(6, HIGH, 25000);
  /*
  if(ch1>1000){Serial.println("Left Switch: Engaged");}
  if(ch1<1000){Serial.println("Left Switch: Disengaged");}

Serial.print("Right Stick X:");
Serial.println(map(ch3, 1000,2000,-500,500));

Serial.print("Right Stick Y:");
Serial.println(map(ch2, 1000,2000,-500,500));

Serial.println();

delay(100);

clearAndHome();
*/

move = map(ch2, 1000,2000, -500, 500); //center over zero
move = constrain(move, -255, 255); //only pass values whose absolutes are
                                   //valid pwm values

/*What we're doing here is determining whether we want to move
forward or backward*/
if(move>0){digitalWrite(dir_a, 1);digitalWrite(dir_b, 1);};
if(move<0){digitalWrite(dir_a, 0);digitalWrite(dir_b, 0); move=abs(move);};

/*Here we're determining whether a left or a right turn is being 
executed*/
turn = map(ch1,1000,2000,-500,500);
turn = constrain(turn, -255, 255);

/*This is where we do some mixing, by subtracting our "turn" 
variable from the appropriate motor's speed we can execute
a turn in either direction*/
if(turn>0){analogWrite(pwm_b, move-turn); analogWrite(pwm_a, move);};
if(turn<0){turn=abs(turn); analogWrite(pwm_a, move-turn); analogWrite(pwm_b, move);};


Serial.print("move:"); //Serial debugging stuff
Serial.println(move);

Serial.print("turn:"); //Serial debugging stuff
Serial.println(turn);

Serial.print("move-turn:"); //Serial debugging stuff
Serial.println(move-turn);

Serial.println(); //Serial debugging stuff
Serial.println();
Serial.println();

}



OK, let me see if I can explain how the steering was on the sketch. What I've done is basically between -255 and 255 in a number of forward / back direction of my control stick is mapped, the former and the latter representing the full full speed ahead with representing the disadvantaged. Ardumoto slope from the communication, you have to break out of two different numbers: direction and speed. To do that, I check whether my number is positive. If so, I change the direction of 1. Both the motor is negative, then I just 0. I get the absolute value of that number, and I do not have to use it as a basic set of both motor commands for both the PWM value of the motor vehicle. I "The basic PWM value" because it is not actually the two motors, instead of a turn-rate is subtracted from one side gets sent.

It's my turn-rate and apply it to a number of I -255 and 255 control rod side-to-side direction of the map, with the former representing a full turn to the left and right of the latter representing a full roster. And that's the number I have, I know how to apply it to the motor. On the down side of this method is that we want to turn on the motor is slowing. This method is not a zero-turn radius, but it works reasonably well. I check to see whether my number is negative. If so, I turn to the left motor speed-rate minus the absolute value. If positive, the absolute value of the motor speed of the turn-rate minus.

There are obviously other ways to implement the differential steering; With a little more code you can send back the appropriate motor reverse and place. Also, this code does not steer you might expect when driving in reverse. However, this means you should start with radio control robot, and I hope that the next robot project you've been inspired to grab a hobby transmitter!

No comments:

Post a Comment