Here is a modification of the interrupt sketch for the multiplexer logic (I have indicated where you need to add the code that will write the two pins gating the multiplexer to select the current channel.
A difficulty with the output of your receiver is that there is no way of knowing when the next channels pulse will start. We overcome this by waiting until we detect the end of the previous frames pulse before capturing the pulse width and moving on to the next channel.
This is implemented using a 'Ready' flag that is toggled on an off on successive pulses and ensuring that the measurement only happens every other trailing edge. Another flag is used to indicate that enough pulses have been detected to ensure that all channel data is correct.
here is the logic:
In setup, channel is set to 1 and Ready flag and DataAvailable flags to set to false
When the first falling edge is detected Ready will be toggled so it will be set to true
When the rising edge is detected and Ready is true then the measurement proper starts
When a falling edge is detected and the Ready flag is true then the measurement ends,
the channel is incremented. If the channel count after incrementing is greater than the number of channels then the DataAvailable flag is set true and pulse data can be accessed
The ready flag will be reset back to false because it is toggled on every trailing edge.
I hope that is clear enough for you to think about a PulseIn version if you prefer that route.
#define icpPin 8 // this interrupt handler must use pin 8
#define TICKS_PER_uS 2 // number of timer ticks per microsecond
#define MAX_CHANNELS 3 // maximum number of channels we want
volatile unsigned int Pulses[ MAX_CHANNELS + 1]; // array holding channel pulses width value in microseconds
volatile uint8_t Channel; // number of channels detected so far in the frame (first channel is 1)
boolean DataAvailable; // set to true when we have received data for all channels
boolean Ready; // true when we are ready to detect the leading edge of a channel
// here is the logic of how this code works :
// to start, channel is set to 1 and ready to false and the DataAvailable flag is false
// when a negative edge is detected ready is set to true
// when a positive edge is detected and ready is true then the measurement starts
// when a negative edge is detected and the ready flag is true then the measurement ends, the ready flag is reset back to false
// and the channel is incremented. If the channel count after incrementing is greater than the number of channels then
// the DataAvailable flag is set true and pulse data can be accessed
ISR(TIMER1_CAPT_vect){
if( !bit_is_set(TCCR1B ,ICES1)){ // was falling edge detected ?
if(Ready ) {
Pulses[Channel] = ICR1 / TICKS_PER_uS; // store pulse length as microsoeconds
if(++Channel > MAX_CHANNELS)
Channel = 1; //reset the channel counter to 1
// Add code here to gate the multiplexer to the current channel
}
Ready = !Ready; //toggle the ready flag
}
else { // rising edge was detected
TCNT1 = 0; // reset the counter
}
TCCR1B ^= _BV(ICES1); // toggle bit value to trigger on the other edge
}
void setup() // run once, when the sketch starts
{
Serial.begin(9600);
pinMode(icpPin,INPUT);
Channel = 1;
Ready = false;
DataAvailable = false;
TCCR1A = 0x00; // COM1A1=0, COM1A0=0 => Disconnect Pin OC1 from Timer/Counter 1 -- PWM11=0,PWM10=0 => PWM Operation disabled
TCCR1B = 0x02; // 16MHz clock with prescaler means TCNT1 increments every .5 uS (cs11 bit set
TIMSK1 = _BV(ICIE1); // enable input capture interrupt for timer 1
}
int GetChannelPulseWidth( uint8_t channel) {
// this is the access function for channel data
int result;
if( DataAvailable && (channel > 0) && (channel <= MAX_CHANNELS) ) {
cli(); //disable interrupts
result = Pulses[channel] ;
sei(); // enable interrupts
}
else
result = 0; // return 0 if no valid pulse is available
return result;
}
void loop() // run over and over again
{
int pulsewidth;
// print the decoder state
if(DataAvailable == false)
Serial.println("The decoder has not detected all channels ");
else
Serial.println("The the channel data is valid");
// now print the channel pulse widths
// they should be 0 if the state is not ready
for ( int i =1; i <=4; i++ ){ // print the status of the first four channels
Serial.print("Channel ");
Serial.print(i);
Serial.print(" has width ");
pulsewidth = GetChannelPulseWidth(i);
Serial.println(pulsewidth);
}
delay(100); // update 10 times a second
}