Introduction
The following arduino library was written to use the findings found during the Mapping RC Transmitter PWM signal to actual transmitter values article. All results were wrapped into a library for ease of use.
The RcReceiverSignal is an arduino library that allows one to read a signal sent from a Remote Controlled (RC) receiver.
Skip to the download section for quick download.
Purpose
The RcReceiverSignal library allows one to easily configure an input pin to read a PWM signal sent from a RC receiver by attaching a RcReceiverSignal instance to a pin connected the receiver and automatically monitor each pulse sent by the receiver.
It allows the main loop to retrieve the latest received pulse length (PWM) and convert the pulse length back to the actual transmitter signal value (ranging from -150% to 150%).
The library supports automatic PWM signal change detection. The library’s ability to convert a PWM value to the actual transmitter numeric value is based on empirical tests available at Mapping RC Transmitter PWM signal to actual transmitter values.
Library features
Possible use are:
- Allows one to get the latest PWM value sent from the RC receiver.
- Automatically handles interrupt protection.
- Automatic ISR handling. All required code automatically generated.
- Allows one to convert a pulse length (PWM) back to the original transmitter value.
- Supports multiple Transmitter/Receiver combination:
- Spektrum DX9 tx + Spektrum AR8000 rx
- Spektrum DX9 tx + Orange R620X rx
- Tactic TTX600 tx + Tactic TR624 rx
- CCPM Servo Tester
- Supports eRCaGuy_Timer2_Counter 0.5µs (or the native micros() function) for timing calculations.
Library dependencies
PinChangeInt
This library allows the arduino to attach interrupts on multiple pins.
eRCaGuy_Timer2_Counter
(optional)
This library configures the arduino’s timer2 to 0.5µs precision. It is used for a micros() function replacement and allows times calculations that are far more precise (8 times!) than the default’s 4µs resolution.
Usage
Use the DECLARE_RECEIVER_SIGNAL macro to declare an instance of RcReceiverSignal. ie:
1 2 |
DECLARE_RECEIVER_SIGNAL(receiver_aux1_handler); DECLARE_RECEIVER_SIGNAL(receiver_throttle_handler); |
Each macro will automatically declare the following:
- RcReceiverSignal receiver_aux1_handler;
- receiver_aux1_handler_setup() function.
- receiver_aux1_handler_pin_change() ISR function.
In the setup() function, you need to configure each instance by calling the receiver_aux1_handler_setup() function with the interrupt pin as argument. ie:
1 2 |
receiver_aux1_handler_setup(RECEIVER_AUX1_IN_PIN); receiver_throttle_handler_setup(RECEIVER_THROTTLE_IN_PIN); |
In the loop function, one can call the hasChanged() method to know if the PWM value has changed since the last call or call the getPwmValue() function to get the last PWM value observed by the RcReceiverSignal instance.
From a PWM value, one can call the getSignalValue() or getDeviceSignalValue() methods to convert a given PWM signal from a known device combination to a transmitter value (within -150% to +150%).
Demo
The following demo show how to use the library:
(download the
RcReceiverSignal v1.1.203 LedUpdate demo.ino (885 downloads)
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
// // RcReceiverSignal Library // LedUpdate example // Copyright (C) 2016 Antoine Beauchamp // The code & updates for the library can be found on http://end2endzone.com // // AUTHOR/LICENSE: // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 3.0 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License (LGPL-3.0) for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // // DISCLAIMER: // This software is furnished "as is", without technical support, and with no // warranty, express or implied, as to its usefulness for any purpose. // // PURPOSE: // The following example reads a PWM signal on pin 2. If the value is below the // center position, it turns ON the arduino's LED. If the value is close to the // center position, it blinks the arduino's LED. If the value is higher than the // center position, it turns OFF the arduino's LED. // // //RcReceiverSignal library has a dependency to PinChangeInt library. #include <PinChangeInt.h> // //This library allows one to have a micros() replacement function //which has a 1us resolution instead of 4usec. //For more information on this library, see the following: // http://electricrcaircraftguy.com/2014/02/Timer2Counter-more-precise-Arduino-micros-function.html // http://www.instructables.com/id/How-to-get-an-Arduino-micros-function-with-05us-pr/ // #include <eRCaGuy_Timer2_Counter.h> //that's the example's library! #include <RcReceiverSignal.h> //project's contants #define RECEIVER_AUX1_IN_PIN 2 // we could choose any pin #define LED_OUT_PIN 13 #define LED_MODE_ON 0 #define LED_MODE_OFF 1 #define LED_MODE_BLINK 2 #define LED_MODE_BLINK_TIME 100 //blinks every 100 ms #define PWM_CENTER_EPSILON 100 //defines the epsilon value which allows to detect "center" position //project's switches #define ENABLE_SERIAL_OUTPUT DECLARE_RECEIVER_SIGNAL(receiver_aux1_handler); char ledMode = LED_MODE_OFF; //initialize LED to OFF by default int ledState = LOW; //initialize LED to OFF by default unsigned long prevBlinkTime = 0; uint32_t timer2CounterWrapperFunction() { return timer2.get_count(); } void setup() { //configure Timer2 timer2.setup(); //this MUST be done before the other Timer2_Counter functions work; Note: since this messes up PWM outputs on pins 3 & 11, as well as //interferes with the tone() library (http://arduino.cc/en/reference/tone), you can always revert Timer2 back to normal by calling //timer2.unsetup() //configure RcReceiverSignal with an external time counter //eRCaGuy_Timer2_Counter lirary has 0.5us resolution. //The counter value must be divided by 2 to convert from 0.5us steps to 1us steps //which results in microseconds resolution. RcReceiverSignal::setExternalTimeCounter(&timer2CounterWrapperFunction, 1, 2); //link RcReceiverSignal to use PinChangeInt library RcReceiverSignal::setAttachInterruptFunction(&PCintPort::attachInterrupt); RcReceiverSignal::setPinStatePointer(&PCintPort::pinState); #ifdef ENABLE_SERIAL_OUTPUT Serial.begin(115200); Serial.println("ready"); #endif // initialize digital pin 13 as an output. pinMode(LED_OUT_PIN, OUTPUT); receiver_aux1_handler_setup(RECEIVER_AUX1_IN_PIN); } void blinkLed() { // See https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay // check to see if it's time to blink the LED; that is, if the // difference between the current time and last time you blinked // the LED is bigger than the interval at which you want to // blink the LED. unsigned long currentMillis = millis(); if (currentMillis - prevBlinkTime >= LED_MODE_BLINK_TIME) { // save the last time you blinked the LED prevBlinkTime = currentMillis; // if the LED is off turn it on and vice-versa: if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; } // set the LED with the ledState of the variable: digitalWrite(LED_OUT_PIN, ledState); } } void loop() { //update LED status if (ledMode == LED_MODE_ON) { ledState = HIGH; digitalWrite(LED_OUT_PIN, ledState); // turn the LED on (HIGH is the voltage level) } else if (ledMode == LED_MODE_OFF) { ledState = LOW; digitalWrite(LED_OUT_PIN, ledState); // turn the LED off by making the voltage LOW } else if (ledMode == LED_MODE_BLINK) { blinkLed(); } //detect when the receiver AUX1 value has changed if (receiver_aux1_handler.hasChanged()) { unsigned long pwmValue = receiver_aux1_handler.getPwmValue(); if (pwmValue < 1500-PWM_CENTER_EPSILON) { #ifdef ENABLE_SERIAL_OUTPUT if (ledMode != LED_MODE_ON) Serial.println("Setting LED to ON"); #endif ledMode = LED_MODE_ON; } else if (pwmValue > 1500+PWM_CENTER_EPSILON) { #ifdef ENABLE_SERIAL_OUTPUT if (ledMode != LED_MODE_OFF) Serial.println("Setting LED to OFF"); #endif ledMode = LED_MODE_OFF; } else { #ifdef ENABLE_SERIAL_OUTPUT if (ledMode != LED_MODE_BLINK) Serial.println("Setting LED to BLINK"); #endif ledMode = LED_MODE_BLINK; } } } |
License
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License (LGPL-3.0) for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
DISCLAIMER:
This software is furnished “as is”, without technical support, and with no warranty, express or implied, as to its usefulness for any purpose.
Download
You can download the RcReceiverSignal arduino library by clicking on the following link: