Hobby RC controller input help please..

Need help with slowing down fastLED library patterns via hobby RC controller please..

I have been having a heck of a time learning to program a simple double "Cylon" traveling dots pattern to slow down/speed up using the pw timing of a hobby RC receiver signal on pin2.

here's video to get an idea of what I'm trying to do

the code that is ran on the Uno Rev. 2 board is this..

the library for fastLED is here

http://fastled.io/

problem is that pulseIn eats up ~20uS's each time it is called.
so to have it run each time I draw a pair of dots slows it WAYYY down.
So in the code I had to run it every 7th LED it draws to help update the speed value, yet not update it via pulseIn too often.
I update it the 1st LED pair, the 7th, 14th, 22nd and 30th, then backwards until going forwards again..
so eight times for each full cycle of the pattern.
While this seems OK for use as it is, I'd rather have more variation of the speed and I know there must be a way to use interrupts to get the PW value vs. this slow way using pulseIn.

Well I tried using interrupts.
1st I tried to use PinChangeInt but I had issues with the library or something.. I had major errors I couldnt figure out. >:(
So I move on to trying attachInterrupt instead and used INT0/Pin 2 to read the PWM signals.

Here's the code

while I can get a good reading of the PW value's LOW signal using the serial monitor, I cannot seem to use the value 'pulse_time' to alter the delay value at the end of each pair of dots drawn without it locking up on me.
I tried to comment the code best I could to describe what it is doing.

can anyone please help show me what I need to do to use the attachInterrupt method properly here?
I really dont want to mess with PinChangeInt right now. I am happy with using INT0 and INT1 for two channels off my RC Receiver. One for throttle and the other for attitude(turn left/right).

I've been messing with it for two days now and simply not getting anywhere with it.. very frustrating.

I also posted this at the fastLED google+ community, but thought I'd try to get help here too.

Thanks in advance,
~Blaine

is there something wrong with where I put the interrupt?
am I accessing the ISR too often since the radio is always pulsing?

going crazy here... >:(

If you post your code in this Forum to save people having to go elsewhere it would be a big help. If the code is too long to include directly in your post you can add it as an attachment. But short code is much easier to figure out.

Never mind the LEDs for a while. Are you able to get the data values you want from your RC receiver in a simple program that just prints the values on the Serial Monitor?

If you can do that, can you extend that program to figure out how quickly you can get new values from the receiver?

...R

Hi Robin,

thanks for your advice.

I found the code button to paste it in here.

Someone mentioned a violation when I alter pulse_time (a value from the ISR) inside the loop ()

I’ll try again without this code in the loop()

pulse_time= pulse_time -20100;

if (pulse_time >800) {
pulse_time=800;}
pulse_time= pulse_time/8;
if (pulse_time <0) {
pulse_time=0;}

and only read pulse_time from the loop()
to see if that helps

~Blaine

#include <SD.h>

#include "FastLED.h"

// How many leds in your strip?
#define NUM_LEDS 60

// For led chips like Neopixels, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806, define both DATA_PIN and CLOCK_PIN
#define DATA_PIN 6
#define CLOCK_PIN 13
int rcPin = 2; // PWM signal arduino pin(prev code only)
int Speed = 0;    // Receiver channel 1 pwm value
// Define the array of leds
CRGB leds[NUM_LEDS];






//pin 2, INT0, is receiving PWM input
#define CHANNEL_1_PIN 2

//micros when the pin goes LOW
volatile unsigned long timer_start;

//difference between timer_start and micros() is the length of time that the pin 
//was HIGH - the PWM pulse length. 
volatile int pulse_time; 

//this is the time that the last interrupt occurred. 
//you can use this to determine if your receiver has a signal or not.
volatile int last_interrupt_time;

//calcSignal is the interrupt handler
//that will read the PW LOW length/time on pin 2
void calcSignal()
{
//record the interrupt time so that we can tell if the receiver has a signal from the transmitter
 last_interrupt_time = micros();

//if the pin has gone LOW, record the microseconds since the Arduino started up
//reading INT0 on Pin 2
 if(digitalRead(2) == LOW)
    {
        timer_start = micros();
    }
//otherwise, the pin has gone HIGH
    else
    {
        //only worry about this if the timer has actually started
        if(timer_start > 0)
        {
            //record the pulse time
            pulse_time = ((volatile int)micros() - timer_start);
            //restart the timer
            timer_start = 0;
        }
    }
}

//this is all normal arduino stuff
void setup()
{
   	FastLED.addLeds<NEOPIXEL,DATA_PIN>(leds, NUM_LEDS);
//REMOVED pinMode(rcPin, INPUT);

    timer_start = 0;
//here's the interrupt, obviously
//INT0 is on Pin 2.
    attachInterrupt(0, calcSignal, CHANGE);
    Serial.begin(115200);
}

void loop()
{
  // First slide the led in one direction
for(int i = 0; i < (NUM_LEDS / 2) - 1; i++) {
// Set the i'th led to red 

leds[i] = CRGB::DarkViolet ;
leds[NUM_LEDS - i -1] = CRGB::DarkViolet ;
// Show the leds
FastLED.show();

/*when PW raw time is viewed in serial monitor I get values average 20100
and 20900. below is formula to convert the numbers to a range of 0-100.
100 being low throttle and 0 for high/full throttle.
*/
pulse_time= pulse_time -20100;

if (pulse_time >800) {
   pulse_time=800;}
   pulse_time= pulse_time/8;
   if (pulse_time <0) {
   pulse_time=0;}
//print the value so I can monitor it
Serial.println(pulse_time);
//I get wildly jumping values in the monitor if I do not put this delay in
delay(25);

// now that we've shown the leds, reset the i'th led to black
leds[i] = CRGB::Black;
leds[NUM_LEDS - i -1] = CRGB::Black;
// Wait a little bit before we loop around and do it again
//delay time of 25 gives a medium slow pattern movement
//if I try to put the 'pulse_time' var in 25's place, it will not work
//and the serial monitor will lock up with only a few zero's showing
//the LED's will not move either. I think the UNO locks up :(
 delay(25);
}

  
// Now go in the other direction.  
for(int i = (NUM_LEDS / 2); i > 0; i--) {

// Set the i'th led to red 
leds[i] = CRGB::Red;
leds[NUM_LEDS - i -1] = CRGB::Red;
// Show the leds
FastLED.show();
pulse_time= pulse_time -20100;

if (pulse_time >800) {
   pulse_time=800;}
    pulse_time= pulse_time/8;
   if (pulse_time <0) {
   pulse_time=0;}
Serial.println(pulse_time);
delay(25);

// now that we've shown the leds, reset the i'th led to black
leds[i] = CRGB::Black;
leds[NUM_LEDS - i -1] = CRGB::Black;
// Wait a little bit before we loop around and do it again
 delay(25);
}

}