Stumped with RC control

Im working on a project for a friend, he wanted a module that would accept a signal from an RC controller and play MP3 files (sound fx).

I built a setup that has an UNO accepting inputs from the receiver and connected to an MP3 playback module on another set of pins. The module triggers when the pin drops to low.

My problem is this is a cleaned up version of my original code.
We connected my testing Uno up and checked the signals being input
we had “resting” input of 1490-1496
our “LOW” input was 995-998
our “HIGH” input was over 2000

we are getting triggering ONLY with the LOW inputs, I kept adjusting the HIGH triggering all the way down to anything GREATER THAN 1500 with no success.

I have beat my head against the wall trying to figure out what is wrong. ANY help is greatly appreciated.
FYI I double checked ALL the Analog input pins AND all of the output pins and they are all working correctly.

Now for the meat, here is the code…

// constants won't change. They're used here to 
// set pin numbers:
 int rcCh1 = A0;     // the number of the rc control channel 1
 int rcCh2 = A1;     // the number of the rc control channel 2
 int rcCh3 = A2;     // the number of the rc control channel 3
 int rcCh4 = A3;     // the number of the rc control channel 4
 int rcCh5 = A4;     // the number of the rc control channel 5
 int rcCh6 = A5;     // the number of the rc control channel 1
const int mp3Pin1 =  13;      // the number of the MP3 ch1 pin
const int mp3Pin2 =  12;      // the number of the MP3 ch2 pin
const int mp3Pin3 =  11;     // the number of the MP3 ch3 pin
const int mp3Pin4 =  10;     // the number of the MP3 ch4 pin
const int mp3Pin5 =  9;     // the number of the MP3 ch5 pin
const int mp3Pin6 =  8;     // the number of the MP3 ch6 pin
int led = 7;
  

void setup() {
  // initialize the MP3 pins as outputs:
  pinMode(mp3Pin1, OUTPUT);
  pinMode(mp3Pin2, OUTPUT);
  pinMode(mp3Pin3, OUTPUT);
  pinMode(mp3Pin4, OUTPUT);  
   pinMode(mp3Pin5, OUTPUT);  
    pinMode(mp3Pin6, OUTPUT); 

          pinMode(led, OUTPUT); //led pin as output
  // initialize the rc channel pins as inputs:
   pinMode(A0, INPUT);
 pinMode(A1, INPUT);
 pinMode(A2, INPUT); // Set our input pins as such
pinMode(A3, INPUT);
pinMode(A4, INPUT);
 pinMode(A5, INPUT);
 
  // set all mp3 pins to high (on) due to grounding (off) triggers module:
 digitalWrite(mp3Pin1,HIGH);
 digitalWrite(mp3Pin2,HIGH);
 digitalWrite(mp3Pin3,HIGH);
 digitalWrite(mp3Pin4,HIGH);
  digitalWrite(mp3Pin5,HIGH);
   digitalWrite(mp3Pin6,HIGH);

 Serial.begin(9600); 
}

void loop(){
 rcCh1 = pulseIn(A0, HIGH, 25000); // Read the pulse width of 
 rcCh2 = pulseIn(A1, HIGH, 25000); // each channel
  rcCh3 = pulseIn(A2, HIGH, 25000);
  rcCh4 = pulseIn(A3, HIGH, 25000);
  rcCh5 = pulseIn(A4, HIGH, 25000);
  rcCh6 = pulseIn(A5, HIGH, 25000);
//************************************

  
  if (rcCh1<1050){     
    // turn LED on:    
    digitalWrite(mp3Pin1,LOW);  
     } 
  else if (rcCh2>=1800) {     
    // turn LED on:    
    digitalWrite(mp3Pin2,LOW);  
  } 
   else if (rcCh3<1050) {     
    // turn LED on:    
    digitalWrite(mp3Pin3,LOW); 
     }
     else if (rcCh4>=1800) {     
    // turn LED on:    
    digitalWrite(mp3Pin4,LOW);  
     } 
 
  else if (rcCh5<1050){     
    // turn LED on:    
    digitalWrite(mp3Pin5,LOW);  
     } 
     else if (rcCh6>=1800){    
        digitalWrite(mp3Pin6,LOW);  
      } 
   
  else {
    // turn LED off:
    digitalWrite(mp3Pin1,HIGH); 
    digitalWrite(mp3Pin2,HIGH);
    digitalWrite(mp3Pin3,HIGH); 
    digitalWrite(mp3Pin4,HIGH);
    digitalWrite(mp3Pin5,HIGH); 
    digitalWrite(mp3Pin6,HIGH);
  }
   
} [Code]

It will be much easier to help if you modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

Put some Serial.print() statements into your program so you can see the values that are being detected? Maybe they are not what you think they are.

This seems a very strange use for an RC system designed for controlling model planes and boats. Why not make a system specific for your friend’s needs using a pair of nRF24L01+ transceivers. Have a look at this Simple nRF24L01+ Tutorial. The nRF24L01+ modules are cheap and very effective.

…R

  if (rcCh1 < 1050) {
    digitalWrite(mp3Pin1, LOW);
  } else if (rcCh2 >= 1800) {
    digitalWrite(mp3Pin2, LOW);
  } else if (rcCh3 < 1050) {
    digitalWrite(mp3Pin3, LOW);
  } else if (rcCh4 >= 1800) {
    digitalWrite(mp3Pin4, LOW);
  } else if (rcCh5 < 1050) {
    digitalWrite(mp3Pin5, LOW);
  } else if (rcCh6 >= 1800) {
    digitalWrite(mp3Pin6, LOW);
  }else {
    digitalWrite(mp3Pin1, HIGH);
    digitalWrite(mp3Pin2, HIGH);
    digitalWrite(mp3Pin3, HIGH);
    digitalWrite(mp3Pin4, HIGH);
    digitalWrite(mp3Pin5, HIGH);
    digitalWrite(mp3Pin6, HIGH);
  }

When you have all of the if’s nested like that, only the first one that is ‘true’ will be executed. The outputs should all go HIGH only if rcCh1, rcCh3, and rcCh5 are high and rcCh2, rcCh4, and rcCh6 are low. Is that what you wanted?

Hi

It sounds suspiciously like your RC receiver is designed to drive servo motors.

Are all the outputs from it on 3 pin connectors (Gnd, +5V and Signal)?

If so you are not dealing with an analogue signal but a digital Pulse Width Modulated signal. The easiest way to confirm this is to hook the signal up to an oscilloscope. If you haven't got access to one you can pick up a cheap LCD based 'scope good enough for the job for £20-35 (US$28 - 50), look for something like the JYE DSO150.

Standard servo drive waveforms are 50Hz square waves (20ms cycle time) with an "on" time varying between 1ms for 0 degrees rotation and 2ms for 180 degrees rotation.

There are two ways to work with these signals:-

  1. put a resistor capacitor filter across the input signal to smooth out the wave form. Connect a 1k resistor between the receiver output and the arduino analog pin and a 100nF capacitor between the arduino pin and ground (don't forget to connect the receiver ground to the arduino ground) . You may have to experiment with the resistor and capacitor values somewhat to get reliable readings.

  2. Use the pulsein() function which will return you the length of the pulse in microseconds.

As I said at the beginning this is only speculation but it is what I would expect from a six channel R/C system.

Ian

The OP's sketch in the initial post IS using pulsein(). The problem is with how his pulse width comparisons are structured.

Steve

The project is an RC controlled robot. He wanted where when he has it do a certain control (head swivel, arm raise, etc) that a sound fx is triggered.

To comment about the nested "else if" the original code has them each separate with same effect, we are only getting the sounds to trigger on the "low" signal.

The system is set up to run servos, so I'm trying to get this to trigger off of the same signal. I based the opening of the code off of this
https://ryanboland.com/blog/reading-rc-receiver-values/

My buddy is a steampunk builder and fellow cosplayer, he came to me because I use Arduinos in my suits.
I'm very stumped on this because the signals are all showing and I test one channel at a time

Cl3ric:
I'm very stumped on this because the signals are all showing and I test one channel at a time

Have you a newer version of your program? If so please post it.

...R

Robin2:
Have you a newer version of your program? If so please post it.

...R

The testing uses the coding from the link I provided.

Cl3ric:
The testing uses the coding from the link I provided.

You already told us that. We want you to post the test version that you made from it.

Ok, here goes, sorry everyone, I’m new to the forums, I work 65+ hours a week and have no Internet at home so had to go somewhere with access.

Our situation is this…

circuit-
[RC receiver (6 channels out)] connects ch1-ch6 to A0-A5 on an [Arduino Uno] pins 8-13 connect to channel 1-6 on an [MP3 module]

my original code is

>

//Code created by Cl3ric (SP Tesla Cosplay) for Lance Mitchell
//Code created 11/2017
//Code uses public domain code and is authorized for public use if needed
//code created to connect an rc controller to an Arduino Uno to trigger MP3 files to play from a module

//rc controller sends signal to Analog pins (A2, A3, A4,A5) to cause trigger pins (8, 9, 10, 11) to ground (LOW) accordingly
//MP3 module triggers by having pins "ground", if using a different type of module adjust code accordingly
//MP3 pins are set to (HIGH) and sets to (LOW) to trigger, resets to (HIGH) after set amount of time (file time - 4 seconds [delay 4000])

// constants won't change. They're used here to 
// set pin numbers:
int rcCh1 = A0;     // the number of the rc control channel 1
int rcCh2 = A1;     // the number of the rc control channel 2
int rcCh3 = A2;     // the number of the rc control channel 3
int rcCh4 = A3;     // the number of the rc control channel 4
int rcCh5 = A4;     // the number of the rc control channel 5
int rcCh6 = A5;     // the number of the rc control channel 1
const int mp3Pin1 =  13;      // the number of the MP3 ch1 pin
const int mp3Pin2 =  12;      // the number of the MP3 ch2 pin
const int mp3Pin3 =  11;     // the number of the MP3 ch3 pin
const int mp3Pin4 =  10;     // the number of the MP3 ch4 pin
const int mp3Pin5 =  9;     // the number of the MP3 ch5 pin
const int mp3Pin6 =  8;     // the number of the MP3 ch6 pin
int led = 7;
 

// variables will change:
//int buttonState1 = 0;         // variable for reading the input1 status
//int buttonState2 = 0;         // variable for reading the input1 status
//int buttonState3 = 0;         // variable for reading the input1 status
//int buttonState4 = 0;         // variable for reading the input1 status

void setup() {
 // initialize the MP3 pins as outputs:
 pinMode(mp3Pin1, OUTPUT);
 pinMode(mp3Pin2, OUTPUT);
 pinMode(mp3Pin3, OUTPUT);
 pinMode(mp3Pin4, OUTPUT);  
  pinMode(mp3Pin5, OUTPUT);  
   pinMode(mp3Pin6, OUTPUT); 

         pinMode(led, OUTPUT); //led pin as output
 // initialize the rc channel pins as inputs:
  pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(A2, INPUT); // Set our input pins as such
pinMode(A3, INPUT);
pinMode(A4, INPUT);
pinMode(A5, INPUT);

 // set all mp3 pins to high (on) due to grounding (off) triggers module:
digitalWrite(mp3Pin1,HIGH);
digitalWrite(mp3Pin2,HIGH);
digitalWrite(mp3Pin3,HIGH);
digitalWrite(mp3Pin4,HIGH);
 digitalWrite(mp3Pin5,HIGH);
  digitalWrite(mp3Pin6,HIGH);

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

void loop(){
rcCh1 = pulseIn(A0, HIGH, 25000); // Read the pulse width of 
rcCh2 = pulseIn(A1, HIGH, 25000); // each channel
 rcCh3 = pulseIn(A2, HIGH, 25000);
 rcCh4 = pulseIn(A3, HIGH, 25000);
 rcCh5 = pulseIn(A4, HIGH, 25000);
 rcCh6 = pulseIn(A5, HIGH, 25000);
 
 if (rcCh1<1000){     
   // turn LED on:    
   digitalWrite(mp3Pin1,LOW);  
  
 } 
 else {
   // turn LED off:
   digitalWrite(mp3Pin1,HIGH); 
 }
//*****************************

 if (rcCh2>=1499) {     
   // turn LED on:    
   digitalWrite(mp3Pin2,LOW);  

 } 
 else {
   // turn LED off:
   digitalWrite(mp3Pin2,HIGH); 
 }
   //*****************************
   
 if (rcCh3<1050) {     
   // turn LED on:    
   digitalWrite(mp3Pin3,LOW);  
  
 }
 else {
   // turn LED off:
   digitalWrite(mp3Pin3,HIGH); 
 }
   //*****************************
   
 if (rcCh4>=1499) {     
   // turn LED on:    
   digitalWrite(mp3Pin4,LOW);  
   
 } 
 else {
   // turn LED off:
   digitalWrite(mp3Pin4,HIGH); 
 }
  if (rcCh5<1050){     
   // turn LED on:    
   digitalWrite(mp3Pin5,LOW);  
  
 } 
 else {
   // turn LED off:
   digitalWrite(mp3Pin5,HIGH); 
 }
  if (rcCh6>=1499){     
   // turn LED on:    
   digitalWrite(mp3Pin6,LOW);  
   
 } 
 else {
   // turn LED off:
   digitalWrite(mp3Pin6,HIGH); 
 }

}
[Code]

The cleaned up code is

//Code created by Cl3ric (SP Tesla Cosplay) for Lance Mitchell
//Code created 11/2017
//Code uses public domain code and is authorized for public use if needed
//code created to connect an rc controller to an Arduino Uno to trigger MP3 files to play from a module

//rc controller sends signal to Analog pins (A2, A3, A4,A5) to cause trigger pins (8, 9, 10, 11) to ground (LOW) accordingly
//MP3 module triggers by having pins "ground", if using a different type of module adjust code accordingly
//MP3 pins are set to (HIGH) and sets to (LOW) to trigger, resets to (HIGH) after set amount of time (file time - 4 seconds [delay 4000])


// constants won't change. They're used here to 
// set pin numbers:
int rcCh1 = A0;     // the number of the rc control channel 1
int rcCh2 = A1;     // the number of the rc control channel 2
int rcCh3 = A2;     // the number of the rc control channel 3
int rcCh4 = A3;     // the number of the rc control channel 4
int rcCh5 = A4;     // the number of the rc control channel 5
int rcCh6 = A5;     // the number of the rc control channel 1
const int mp3Pin1 =  13;      // the number of the MP3 ch1 pin
const int mp3Pin2 =  12;      // the number of the MP3 ch2 pin
const int mp3Pin3 =  11;     // the number of the MP3 ch3 pin
const int mp3Pin4 =  10;     // the number of the MP3 ch4 pin
const int mp3Pin5 =  9;     // the number of the MP3 ch5 pin
const int mp3Pin6 =  8;     // the number of the MP3 ch6 pin
int led = 7;
 
void setup() {
 // initialize the MP3 pins as outputs:
 pinMode(mp3Pin1, OUTPUT);
 pinMode(mp3Pin2, OUTPUT);
 pinMode(mp3Pin3, OUTPUT);
 pinMode(mp3Pin4, OUTPUT);  
  pinMode(mp3Pin5, OUTPUT);  
   pinMode(mp3Pin6, OUTPUT); 

         pinMode(led, OUTPUT); //led pin as output
 // initialize the rc channel pins as inputs:
  pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(A2, INPUT); // Set our input pins as such
pinMode(A3, INPUT);
pinMode(A4, INPUT);
pinMode(A5, INPUT);

 // set all mp3 pins to high (on) due to grounding (off) triggers module:
digitalWrite(mp3Pin1,HIGH);
digitalWrite(mp3Pin2,HIGH);
digitalWrite(mp3Pin3,HIGH);
digitalWrite(mp3Pin4,HIGH);
 digitalWrite(mp3Pin5,HIGH);
  digitalWrite(mp3Pin6,HIGH);

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

void loop(){
rcCh1 = pulseIn(A0, HIGH, 25000); // Read the pulse width of 
rcCh2 = pulseIn(A1, HIGH, 25000); // each channel
 rcCh3 = pulseIn(A2, HIGH, 25000);
 rcCh4 = pulseIn(A3, HIGH, 25000);
 rcCh5 = pulseIn(A4, HIGH, 25000);
 rcCh6 = pulseIn(A5, HIGH, 25000);
//************************************

 
 if (rcCh1<1000){     
   // turn LED on:    
   digitalWrite(mp3Pin1,LOW);  
    } 
 else if (rcCh2>=2000) {     
   // turn LED on:    
   digitalWrite(mp3Pin2,LOW);  
 } 
  else if (rcCh3<1050) {     
   // turn LED on:    
   digitalWrite(mp3Pin3,LOW); 
    }
    else if (rcCh4>=2000) {     
   // turn LED on:    
   digitalWrite(mp3Pin4,LOW);  
    } 

 else if (rcCh5<1050){     
   // turn LED on:    
   digitalWrite(mp3Pin5,LOW);  
    } 
    else if (rcCh6>=2000){    
       digitalWrite(mp3Pin6,LOW);  
     } 
  
 else {
   // turn LED off:
   digitalWrite(mp3Pin1,HIGH); 
   digitalWrite(mp3Pin2,HIGH);
   digitalWrite(mp3Pin3,HIGH); 
   digitalWrite(mp3Pin4,HIGH);
   digitalWrite(mp3Pin5,HIGH); 
   digitalWrite(mp3Pin6,HIGH);
 }   
}
[Code]

[/code]

Have you absorbed reply #2?

The testing code is

/*
 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.
 */

 // #Modified 11/2017 by Cl3ric
 
int ch1; // Here's where we'll keep our channel values


void setup() {

  pinMode(A2, INPUT); // Set our input pins as such   
  Serial.begin(9600); // Pour a bowl of Serial

}

void loop() {

  ch1 = pulseIn(A1, HIGH, 25000); // Read the pulse width of 

  Serial.print("Channel 1:"); // Print the value of 
  Serial.println(ch1);        // each channel
 
  delay(1000); // I put this here just to make the terminal 
              // window happier
}

I trimmed down the code to only read one channel at a time because having 4-6 channels flashing across the screen was confusing. with this we check each channel one at a time and can see the value change.

his switch has 3 positions up (high), middle (rest), and down (low)
our values were (h) 2000+, (r) 1490-1496, and (l) 995-998

Cl3ric:
his switch has 3 positions up (high), middle (rest), and down (low)
our values were (h) 2000+, (r) 1490-1496, and (l) 995-998

OK. You now know what to expect from the signal on A1. How do you want that signal to map to possible outputs?

johnwasser:
OK. You now know what to expect from the signal on A1. How do you want that signal to map to possible outputs?

Its supposed to work with when signal hits pins A0-A5 and meets the criteria its supposed to drop their assigned pins (13-8) to LOW to trigger the MP3 module.

Its only triggering on the "low" trigger signals but not on the "highs"

Hi,
Instead of using if statements,look at "switch..case"

https://www.arduino.cc/reference/en/language/structure/control-structure/switchcase/

The example here may be of help;

Tom.... :slight_smile:

We have SIX different inputs coming in, that's why I set it up with the original "if, else if" statements,
The program and setup "runs" except for triggering a for the high inputs.
I'll try a form with the switch statements and see what that gets me....

Hi,

Give each input a number 1,2,4,8,16,32

Then when you poll the inputs, you add all the values of the ON buttons.
Any combination of buttons ON will have a unique value.
Use the appropriate value to select which case.

eg, Buttons 1 and 6 = 1 + 32 = 33
You will only get 33 with that combination.

Thus way you have already got all combinations covered without long if statements.

Hope it helps.. Tom.. :slight_smile:

Cl3ric:
Its only triggering on the “low” trigger signals but not on the “highs”

Since you have six inputs and six outputs I’m going to assume you want the “high” and “low” readings to act the same.

    unsigned long pulseWidth = pulseIn(A0, HIGH, 25000);
    // Set the output pin HIGH if near the middle (resting) and LOW if away from the middle
    // Pulse width of 0 means "no pulse found" so default that to HIGH.
    digitalWrite(13, pulseWidth == 0 || (pulseWidth > 1300 && pulseWidth < 1700));

You can then use arrays and a loop to do all of the pins:

const byte PinCount = 6;
byte inputPins[PinCount] = {A0, A1, A2, A3, A4, A5};
byte OutputPins[PinCount] = {13, 12, 11, 10, 9, 8};
void setup() {
    for (byte i=0; i<PinCount; i++) {
        pinMode(InputPins[i], INPUT);
        pinMode(OutputPins[i], OUTPUT);
    }
}
void loop() {
    for (byte i=0; i,PinCount; i++) {
        unsigned long pulseWidth = pulseIn(InputPins[i], HIGH, 25000);
        // Set the output pin HIGH if near the middle (resting) and LOW if away from the middle
        // Pulse width of 0 means "no pulse found" so default that to HIGH.
        digitalWrite(OutputPins[i], pulseWidth == 0 || (pulseWidth > 1300 && pulseWidth < 1700));
    }
}

Thanks for the input everyone, I figured out my original and modified codes BOTH work correctly. He was setting adjustments while I was scanning the signals, so the code will actually be set as "ch1" low / "ch1" high, "ch3" low/ "ch3" high, and "ch5" low/ "ch5" high.

He was adjusting to have signal coming out each of the 6 channels when I only needed "high" or "low" signal triggers for 3 channels for 6 fx!
I felt like a goober!