-1

I've written an ISR routine using an Arduino UNO wired to my RC receiver. The receiver gets orders through the gimbals in my transmitter and executes the ISR every time the gimbals are moved.

I was expecting that the ISR would NOT be called/executed if I did NOT touch the gimbals. Even when the gimbals are left untouched, the ISR is called/executed. What is actually triggering interrupts that keep calling the ISR??

//
// SKETCH TO TEST COMMANDS FROM FLYSKY FS-i6X RADIO CONTROL
//
// Define variables for channel numbers
//
#define CHA1 0 // CHA1 equals 0 (Channel 1 controls ROLL)
#define CHA2 1 // CHA2 equals 1 (Channel 2 controls PITCH)
#define CHA3 2 // CHA3 equals 2 (Channel 3 controls GAS/THROTTLE)
#define CHA4 3 // CHA4 equals 3 (Channel 4 controls YAW)
//
// Global variables 
//
volatile unsigned int pwmLength[4]; // PWM pulse durations on the receiver channels
volatile unsigned int interruptTime; // Time used in interrupt service routine (ISR) to identify beginning of ANY interrupt.
 // This is the time when we enter the ISR routine ANY time an interrupt is triggered.
volatile unsigned int pwmSignalStart[4]; // Array of start times of PWM signals at each of the receiver channels
volatile byte chaPreviousState[4]; // Array of states (HIGH or LOW) of each of the reception channels BEFORE an interrupt occurs.
 // Pin Levels in a digital pin can be HIGH or LOW. When reading or writing to a digital pin 
 // there are only two possible values a pin can be-set-to: HIGH and LOW. These are the same 
 // as true and false, as well as 1 and 0.
//
// Declaration of the prototypes of the functions used in the program. 
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void selectInterruptSources(); // function to configure the pins that trigger an interrupt
void showFlyskyPwmLength(); // function to displays in Serial Monitor durations of the PWM signals received via the RC receiver.
//
// SETUP() 
//
void setup(){
// Set data rate in bits per second (baud) 
 Serial.begin(115200,SERIAL_8N1); 
// Selection of pins used as interrupt sources
 selectInterruptSources();
}
//
// LOOP() 
//
void loop(){
 delay(250);
 showFlyskyPwmLength();
}
//
// This function manipulates registers PCICR and PCMSK0 so as to allow digital pins/terminals to trigger interrupts 
//
void selectInterruptSources(){
 PCICR |= (1 << PCIE0); // condensed writing of PCICR = PCICR | (1 << PCIE0); Hence, 0-bit of PCICR set to 1 
 PCMSK0 |= (1 << PCINT0); // Variable PCINT0 in iom328p.h is defined as equal to 0. Also, PCINT0 is bit 0 of register PCMSK0, 
 // so we need to toggle it to "1" in order to be able to receive an interrupt when a change of state 
 // occurs at "digital pin 8". So, 1 << PCINT0 left-shifts number 1 by 0. Then, the bitwise operation
 // PCMSK0 = PCMSK0 | (1 << PCINT0) sets bit 0 of PCMSK0 to 1.
 PCMSK0 |= (1 << PCINT1); // Variable PCINT1 in iom328p.h is defined as equal to 1. Also, PCINT1 is bit 1 of register PCMSK0, 
 // so we need to toggle it to "1" in order to be able to receive an interrupt when a change of state 
 // occurs at "digital pin 9". So, 1 << PCINT1 left-shifts number 1 by 1. Then, the bitwise operation
 // PCMSK0 = PCMSK0 | (1 << PCINT1) sets bit 1 of PCMSK0 to 1.
 PCMSK0 |= (1 << PCINT2); // Variable PCINT2 in iom328p.h is defined as equal to 2. Also, PCINT2 is bit 2 of register PCMSK0, 
 // so we need to toggle it to "1" in order to be able to receive an interrupt when a change of state 
 // occurs at "digital pin 10". So, 1 << PCINT2 left-shifts number 1 by 2. Then, the bitwise operation
 // PCMSK0 = PCMSK0 | (1 << PCINT2) sets bit 2 of PCMSK0 to 1.
 PCMSK0 |= (1 << PCINT3); // Variable PCINT3 in iom328p.h is defined as equal to 3. Also, PCINT3 is bit 3 of register PCMSK0, 
 // so we need to toggle it to "1" in order to be able to receive an interrupt when a change of state 
 // occurs at "digital pin 11". So, 1 << PCINT3 left-shifts number 1 by 3. Then, the bitwise operation
 // PCMSK0 = PCMSK0 | (1 << PCINT3) sets bit 3 of PCMSK0 to 1. 
}
ISR(PCINT0_vect) {
//
// Channel 1 of FS-iA10B receiver is connected to pin/terminal 8
//
 interruptTime = micros(); // Starts computing time from the time an interrupt is triggered
 if (PINB & B00000001){ // Check if pin 8 triggered interrupt, i.e., if pin 8 is HIGH, check if rising edge or falling edge
 if (chaPreviousState[CHA1] == LOW) { // Here we test if the previous state of pin 8 was "LOW", which means pin 8 made 
 // a rising edge, i.e., went from 0 to 1. So, we set the state of pin 8 to HIGH, and 
 // this becomes the previous state for next time an interrupt is triggered
 chaPreviousState[CHA1] = HIGH; 
 pwmSignalStart[CHA1] = interruptTime; // Record the time this rising edge occurs
 } 
 // Alternatively, if pin 8 is LOW and the previous state of pin 8 is HIGH
 } else if (chaPreviousState[CHA1] == HIGH) { // Previous state was HIGH, pin 8 went from "1" to "0", a falling edge
 chaPreviousState[CHA1] = LOW; // Previous state for next time interrupt is triggered is set to LOW
 // We can now compute the PWM pulse length
 pwmLength[CHA1] = interruptTime - pwmSignalStart[CHA1]; 
 }
//
// Channel 2 of FS-iA10B receiver is connected to pin/terminal 9
//
 if (PINB & B00000010){ // Check if pin 9 triggered interrupt, i.e., if pin 9 is HIGH, check if rising edge or falling edge
 if (chaPreviousState[CHA2] == LOW) { // Here we test if the previous state of pin 9 was "LOW", which means pin 9 made 
 // a rising edge, i.e., went from 0 to 1. So, we set the state of pin 9 to HIGH, and 
 // this becomes the previous state for next time an interrupt is triggered
 chaPreviousState[CHA2] = HIGH; 
 pwmSignalStart[CHA2] = interruptTime; // Record the time this rising edge occurs
 } 
 // Alternatively, if pin 9 is LOW and the previous state of pin 9 is HIGH
 } else if (chaPreviousState[CHA2] == HIGH) { // Previous state was HIGH, pin 9 went from "1" to "0", a falling edge
 chaPreviousState[CHA2] = LOW; // Previous state for next time interrupt is triggered is set to LOW
 // We can now compute the PWM pulse length
 pwmLength[CHA2] = interruptTime - pwmSignalStart[CHA2]; 
 }
//
// Channel 3 of FS-iA10B receiver is connected to pin/terminal 10
//
 if (PINB & B00000100){ // Check if pin 10 triggered interrupt, i.e., if pin 10 is HIGH, check if rising edge or falling edge
 if (chaPreviousState[CHA3] == LOW) { // Here we test if the previous state of pin 10 was "LOW", which means pin 10 made 
 // a rising edge, i.e., went from 0 to 1. So, we set the state of pin 10 to HIGH, and 
 // this becomes the previous state for next time an interrupt is triggered
 chaPreviousState[CHA3] = HIGH; 
 pwmSignalStart[CHA3] = interruptTime; // Record the time this rising edge occurs
 } 
 // Alternatively, if pin 10 is LOW and the previous state of pin 10 is HIGH
 } else if (chaPreviousState[CHA3] == HIGH) { // Previous state was HIGH, pin 10 went from "1" to "0", a falling edge
 chaPreviousState[CHA3] = LOW; // Previous state for next time interrupt is triggered is set to LOW
 // We can now compute the PWM pulse length
 pwmLength[CHA3] = interruptTime - pwmSignalStart[CHA3]; 
 }
//
// Channel 4 of FS-iA10B receiver is connected to pin/terminal 11
//
 if (PINB & B00001000){ // Check if pin 11 triggered interrupt, i.e., if pin 11 is HIGH, check if rising edge or falling edge
 if (chaPreviousState[CHA4] == LOW) { // Here we test if the previous state of pin 11 was "LOW", which means pin 11 made 
 // a rising edge, i.e., went from 0 to 1. So, we set the state of pin 11 to HIGH, and 
 // this becomes the previous state for next time an interrupt is triggered
 chaPreviousState[CHA4] = HIGH; 
 pwmSignalStart[CHA4] = interruptTime; // Record the time this rising edge occurs
 } 
 // Alternatively, if pin 11 is LOW and the previous state of pin 11 is HIGH
 } else if (chaPreviousState[CHA4] == HIGH) { // Previous state was HIGH, pin 11 went from "1" to "0", a falling edge
 chaPreviousState[CHA4] = LOW; // Previous state for next time interrupt is triggered is set to LOW
 // We can now compute the PWM pulse length
 pwmLength[CHA4] = interruptTime - pwmSignalStart[CHA4]; 
 }
}
//
// Prints to serial monitor the pulse durations/lengths received from channels 8, 9, 10, 11 via the radio receiver
//
void showFlyskyPwmLength() {
 Serial.print("Roll PWM Length: ");
 Serial.print(pwmLength[CHA1]);
 Serial.print("\u00B5s"); // Unicode code point \u00B5 for micro plus letter "s"
 
 Serial.print(" -> Pitch PWM Length: ");
 Serial.print(pwmLength[CHA2]);
 Serial.print("\u00B5s"); // Unicode code point \u00B5 for micro plus letter "s"
 
 Serial.print(" -> Gas PWM Length: ");
 Serial.print(pwmLength[CHA3]);
 Serial.print("\u00B5s"); // Unicode code point \u00B5 for micro plus letter "s"
 
 Serial.print(" -> Yaw PWM Length: ");
 Serial.print(pwmLength[CHA4]);
 Serial.print("\u00B5s"); // Unicode code point \u00B5 for micro plus letter "s"
 Serial.println("");
}

enter image description here

Juraj
18.3k4 gold badges31 silver badges49 bronze badges
asked Feb 25 at 19:15
1
  • 2
    the questions is not answerable until you tell us what are the signals at the connections and what code you are using ... also the question is not about the arduino until you add that info to your question Commented Feb 25 at 20:04

1 Answer 1

1

An RC receiver typically outputs one pulse per channel every 20 ms, whether you touch the controls or not. The length of the pulses depend on the position of the controls. Thus, you will have to time the received pulses on the Arduino in order to know what the controls are doing on the transmitter.

answered Feb 25 at 20:40
3
  • a hardware decoder could be used ... github.com/chiefenne/ATTINY85-RC-Receiver-Decoder Commented Feb 25 at 21:01
  • "you will have to time the received pulses on the Arduino in order to know what the controls are doing on the transmitter." How can I time the received pulses on the Arduino?? Commented Feb 25 at 21:05
  • @AlexA: with micros(). Commented Feb 25 at 21:34

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.