3
$\begingroup$

I have a 9 channel RF RX/TX and want to connect 3 motors to it. I am able to connect channel 1 with motor 1 but unable to connect channel 2 with motor 2 simultaneously with arduino.

Here is the code I am currently using:

int motor1Left = 7;// defines pin 5 as connected to the motor
int motor1Right= 9;// defines pin 6 as connected to the motor
int motor2Left = 22;// defines pin 7 as connected to the motor
int motor2Right = 26;// defines pin 8 as connected to the motor
int enable = 5;
int enable2 = 10;
int channel1 = 2; // defines the channels that are connected
int channel2 = 3;// to pins 9 and 10 of arduino respectively

int Channel1 ; // Used later to 
int Channel2 ; // store values

void  setup ()
{
  pinMode (motor1Left, OUTPUT);// initialises the motor pins
  pinMode (motor1Right, OUTPUT);
  pinMode (motor2Left, OUTPUT);
  pinMode (motor2Right, OUTPUT);// as outputs
  pinMode (channel1, INPUT);// initialises the channels
  pinMode (channel2, INPUT);// as inputs

  Serial.begin (9600); // Sets the baud rate to 9600 bps
}

void  loop ()
{
  Channel1 = (pulseIn (channel1, HIGH)); // Checks the value of channel1
  Serial.println (Channel1); //Prints the channels value on the serial monitor
  delay(1000);

  Channel2 = (pulseIn (channel2, HIGH)); // Checks the value of channel1
  Serial.println (Channel2); //Prints the channels value value on the serial monitor
  delay(1000);

  if (Channel1 > 1470 && Channel1 < 1500) /*These are the values that I got from my transmitter, which you may customize according to your transmitter values */
  {
    digitalWrite (motor1Left, LOW); // Sets both the
    digitalWrite (motor1Right, LOW);// motors to low
    analogWrite(enable, 100);  
  }

  if (Channel1 < 1460) // Checks if Channel1 is lesser than 1300
  {
    digitalWrite (motor1Left, HIGH);// Turns the left
    digitalWrite (motor1Right, LOW); // motor forward
    analogWrite(enable, 100);
  }

  if (Channel1 > 1510) // Checks if Channel1 is greater than 1500
  {
    digitalWrite (motor1Left, LOW);// Turns the right

    digitalWrite (motor1Right, HIGH);// motor forward
    analogWrite(enable, 70);
  }

  if (Channel2 > 1480 && Channel1 < 1500 )
  {
    digitalWrite (motor2Left, LOW);// Sets both the
    digitalWrite (motor2Right, LOW);// motors to low
    analogWrite (enable2, 100);
  }

  if (Channel2 < 1300) // Checks if Channel2 is lesser than 1300
  {
    digitalWrite (motor2Left, LOW);// Turns the left
    digitalWrite (motor2Right, HIGH);// motor backward
    analogWrite (enable2, 100);
  }

  if (Channel2 > 1500) // Checks if Channel2 is greater than 1500
  {
    digitalWrite (motor2Left, HIGH);// Turns the right
    digitalWrite (motor2Right, LOW);// motor backward
    analogWrite (enable2, 100);
  }
}
$\endgroup$
  • $\begingroup$ It looks like you have 4 motors (motor1 and motor2, each having a left and right) and 2 "enable" pins. Can you describe what a channel input is supposed to do to a motor? What is the layout of the motors? $\endgroup$ – Ian Apr 19 '13 at 16:16
  • 1
    $\begingroup$ It looks like you have introduced a delay of a second between channel1 and channel2. How would you expect it to simultaneously work then? $\endgroup$ – Naresh Apr 22 '13 at 6:23
  • $\begingroup$ Could you provide some sort of block diagram as to what you are trying to connect to what? What version of Arduino are you using? Also, what is the model (you could provide a link) to the RF transmitter you are using? When you say "simultaneously", I would assume you mean "relatively" the same time, since the program can only actually do one thing at a time. $\endgroup$ – Kurt E. Clothier Apr 22 '13 at 19:07
4
$\begingroup$

I'm assuming you have a standard 9-channel hobby RC transmitter (with the little joysticks you move with your fingers) and a corresponding 9-channel hobby RC receiver intended to go into a RC car or airplane with standard servo 3-pin headers (9 of them). And you have your Arduino, and a few motors you want to control with it.

Your program has better-than-average comments, but some are still mystifying, such as:

int motor1Left = 7;// defines pin 5 as connected to the motor

Really?

I would break this problem into (at least) two parts, try to get each part working independently, and then try to get everything working together.

One way to break it up into parts is to have an array something like

int pulseWidth[9];

I might write one program that only reads pulse widths from the RC receiver and prints them out the serial port. Then I might extend that program to store those pulse widths into that array, and then print out the values in that array. Then I might write a completely separate program that sets each value in that array to a different constant, and then uses the values in that array to control the motors. Only after I got both programs working would I combine them into one program.

Reading the pulse widths is definitely the trickiest part, but I hear that several people have gotten that to work adequately for them.

The two basic approaches to reading pulse widths that I've seen are:

  • (a) Get all the signals on one wire, sometimes called "the PPM stream" (i.e., if it uses a 4017 IC for splitting, attach the wire to the "CLK" pin 14; if it uses a 4015 IC for splitting, attach the wire to the "CLK" pin 9), and feed that one wire into a single Arduino input. Or,
  • (b) Feed each output pin that you care about to separate input pins on the Arduino. (It may help if you use an O'scope to figure out which order the "RC receiver" pulses those pins.)

Have you tried maybe running program listed at "RC Hobby Controllers and Arduino" without any changes at all? Does that much work on your hardware?

Other people connecting a hobby RC receiver to an Arduino include (in no particular order):

P.S.: often you get better answers to problems like this if you write all three parts: (1) what you want to happen, (2) the complete program listing, and (3) what actually happens when you run the program — "Motor 2 never moves, no matter how I move the control stick", or "Motor 2 always moves exactly like motor 1 moves", or whatever it is you actually observe.

You did great with part (2), but without (1) and (3) it's difficult for anyone to help you.

$\endgroup$
1
$\begingroup$

You cannot use the synchronous "pulseIn()" function to read multiple parallel inputs. In general, in embedded systems, you will end up writing a loop that runs as fast as possible, over and over, and does the following:

1) read inputs 2) calculate updates to state 3) write outputs

Ideally, this loop runs many thousands of times per second.

I'm assuming from context that by "RX/TX" you mean RC-hobby-radio-control PWM pulses. The problem you're having is reading the width of more than one pulse at the same time. There are two ways to approach this:

1) Each time through the loop, read both input pins. If a pin is high and was previously low, write the current time (in microseconds) to a variable tracking that pin. If the pin is low and was previously high, write the difference between current time, and the value in the tracking variable, to a variable tracking "last length for pin X."

2) Install pin change interrupt handlers for the input pins. Each time one of the pins change, run the algorithm above, from within the interrupt handler. Because of possible race conditions, you need to check both pins for each pin change interrupt.

You will note with both these approaches that precision is pretty crummy in the Arduino environment. There are a few reasons for this, including interrupts used to run the milliseconds timer, and significant overhead in the digitalRead() function as compared to reading ports directly. To get high-quality input, you may need to read ports directly (check the Atmega data sheets for how) and you may also want to poll all the way until the pulse goes low in the interrupt handler (beware that a second pin may go high while the first pin is already high.)

This may sound complex if you're new to programming microcontrollers, but it's really the kind of thing that's done every day by those who actual work with this. This is one of several reasons why you need a fair bit of education and experience to become a seasoned developer ;-)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.