/* rcTiming.ino -- JW, 30 November 2015 --
* Uses pin-change interrupts on A0-A4 to time RC pulses
*
* Ref: http://arduino.stackexchange.com/questions/18183/read-rc-receiver-channels-using-interrupt-instead-of-pulsein
*
*/
#include <Streaming.h>
static byte rcOld; // Prev. states of inputs
volatile unsigned long rcRises[4]; // times of prev. rising edges
volatile unsigned long rcTimes[4]; // recent pulse lengths
volatile unsigned int rcChange=0; // Change-counter
// Be sure to call setup_rcTiming() from setup()
void setup_rcTiming() {
rcOld = 0;
pinMode(A0, INPUT); // pin 14, A0, PC0, for pin-change interrupt
pinMode(A1, INPUT); // pin 15, A1, PC1, for pin-change interrupt
pinMode(A2, INPUT);
pinMode(A3, INPUT);
PCMSK1 |= 0x0F; // Four-bit mask for four channels
PCIFR |= 0x02; // clear pin-change interrupts if any
PCICR |= 0x02; // enable pin-change interrupts
}
// Define the service routine for PCI vector 1
ISR(PCINT1_vect) {
byte rcNew = PINC & 15; // Get low 4 bits, A0-A3
byte changes = rcNew^rcOld; // Notice changed bits
byte channel = 0;
unsigned long now = micros(); // micros() is ok in int routine
while (changes) {
if ((changes & 1)) { // Did current channel change?
if ((rcNew & (1<<channel))) { // Check rising edge
rcRises[channel] = now; // Is rising edge
} else { // Is falling edge
rcTimes[channel] = now-rcRises[channel];
}
}
changes >>= 1; // shift out the done bit
++channel;
++rcChange;
}
rcOld = rcNew; // Save new state
}
void setup() {
Serial.begin(115200);
Serial.println("Starting RC Timing Test");
setup_rcTiming();
}
void loop() {
unsigned long rcT[4]; // copy of recent pulse lengths
unsigned int rcN;
if (rcChange) {
// Data is subject to races if interrupted, so off interrupts
cli(); // Disable interrupts
rcN = rcChange;
rcChange = 0; // Zero the change counter
rcT[0] = rcTimes[0];
rcT[1] = rcTimes[1];
rcT[2] = rcTimes[2];
rcT[3] = rcTimes[3];
sei(); // reenable interrupts
Serial << "t=" << millis() << " " << rcT[0] << " " << rcT[1]
<< " " << rcT[2] << " " << rcT[3] << " " << rcN << endl;
}
sei(); // reenable interrupts
}
source: arduino uno - Read RC receiver channels using Interrupt instead of PulseIn - Arduino Stack Exchange
Arduino UNO R3 atmega328p
i am using this code in my project read pwm signal.Only one channel is needed so only pin A0 is used and rest are unused (A1-A3).The problem is that when there is no pwm signal it stores the previous value of pwm signal, while in project it needs to be go to zero when signal is not present.
secondly can i use pin 3 to read pwm.To do that what would be to change in above code?