Arduino Navigation Lights for R/C

All things Arduino!
Post Reply
Eric
Posts: 158
Joined: Fri Feb 21, 2014 4:52 pm

Arduino Navigation Lights for R/C

Post by Eric » Wed Dec 10, 2014 7:20 pm

Posting up the code for my Arduino R/C navigation lights. This should be good for just about any remote controlled project such as FPV, Quad copters, Helicopters, Cars, Boats, etc. Works good!

YouTube video soon!

Cheers.

Code: Select all

/**
 Erics DIY Aircraft Navigation Lights Project
My Youtube Channel  : http://www.youtube.com/user/Shadow5549
Website http://mkme.org

V1 Set up basic lighting
Changed Pins to support nano
Fixed flash sequence
 
 * Features:
 * Landing light controlled via an RC channel (can use a Y-harness on flaps or landing gear channel)
 * 2 fading anti-collision beacons
 * Double flash strobe

Adapted from : 
 * @author Harold Asbridge
 * @version 0.3
 * @date 2014-06-12

*/

// Landing light settings
#define LL_IRQ_NUMBER 0 // Interrupt number to use (0 = pin 2 on most boards)
#define LL_PIN_SERVO 2 // Servo input pin number - this needs to match whatever interrupt is used
#define LL_PIN_LIGHT 3 // Landing light output pin number
#define LL_SERVO_THRESHOLD 1500 // Servo signal threshold to turn on/off landing light (pulse width in microseconds, 1000 to 2000)
#define LL_SERVO_DEAD_ZONE 100 // Servo signal dead-zone size, eliminates flicker
#define LL_SERVO_REVERSED true   // Whether or not the servo channel is reversed

// Strobe settings
#define STB_PIN_LIGHT 4 // Pin number for strobe light output
#define STB_PIN_LIGHTB 8 // Pin number for strobe light output
#define STB_BLINK_INTERVAL 2000000 // Blink interval for strobe light in microseconds

// Anti-collision beacon settings
#define ACB1_PIN_LIGHT 5 // Pin number for anti-collision beacon 1
#define ACB2_PIN_LIGHT 6 // Pin number for anti-collision beacon 2
#define ACB_FADE_MIN 0 // Minimum fade level for beacon (0-255)
#define ACB_FADE_MAX 255 // Maximum fade level for beacon (0-255)
#define ACB_FADE_INTERVAL 4000 // Fade step interval, in microseconds (lower numbers = faster fade)


// Var declarations
volatile unsigned long servoPulseStartTime;
volatile int servoPulseWidth = 0;
boolean curLandingLight = false;

unsigned long lastFadeTime = 0;
unsigned long lastStrobeTime = 0;
int currentFade = ACB_FADE_MIN;
int fadeDirection = 1;

// Called on power on or reset
void setup()
{
  // Set up interrupt handler
  attachInterrupt(LL_IRQ_NUMBER, measureServoSignal, CHANGE);

  // Declare output pins
  pinMode(LL_PIN_LIGHT, OUTPUT);
  pinMode(STB_PIN_LIGHT, OUTPUT);
  pinMode(STB_PIN_LIGHTB, OUTPUT);
  pinMode(ACB1_PIN_LIGHT, OUTPUT);
  pinMode(ACB2_PIN_LIGHT, OUTPUT);
  
  
}

// Called continuouly
void loop()
{
  unsigned long currentTime = micros();
 

  // Check if the landing light should be turned on
  checkLandingLight();
  
  // Check if it's time to fade the anti-collision lights
  if ((currentTime - lastFadeTime) > ACB_FADE_INTERVAL) {
    doFade();
    lastFadeTime = currentTime;
  }

  // Check if it's time to blink the strobes
  if ((currentTime - lastStrobeTime) > STB_BLINK_INTERVAL) {
    doStrobe();
    lastStrobeTime = currentTime; 
  }
}

// Check servo signal, and decide to turn on/off the landing light
void checkLandingLight()
{
  // Modify threshold to prevent flicker
  int threshold = LL_SERVO_THRESHOLD;
  if (!curLandingLight) {
    // Light is not on, adjust threshold up
    threshold += LL_SERVO_DEAD_ZONE;
  } else {
    // Light is on, adjust threshold down
    threshold -= LL_SERVO_DEAD_ZONE;
  }

  // Check servo position
  if (servoPulseWidth >= threshold) {
    setLandingLight(true);
  } else {
    setLandingLight(false);
  }
}

// Turn on or off landing light
void setLandingLight(boolean state)
{
  float i;
  if (state && !curLandingLight) {
    digitalWrite(LL_PIN_LIGHT, HIGH);
  } else if (!state && curLandingLight) {
    digitalWrite(LL_PIN_LIGHT, LOW);
  }
  curLandingLight = state;
}

// Fade anti-collision LEDs
void doFade()
{
  currentFade += fadeDirection;
  if (currentFade == ACB_FADE_MAX || currentFade == ACB_FADE_MIN) {
    // If we hit the fade limit, flash the high beacon, and flip the fade direction
    if (fadeDirection == 1) {
      analogWrite(ACB1_PIN_LIGHT, 255);

    } else {
      analogWrite(ACB2_PIN_LIGHT, 255);
    }
    delay(50); 
    fadeDirection *= -1; 
  }

  analogWrite(ACB1_PIN_LIGHT, currentFade);
  analogWrite(ACB2_PIN_LIGHT, ACB_FADE_MAX - currentFade + ACB_FADE_MIN);
}

// Strobe double-blink
void doStrobe()
{
  digitalWrite(STB_PIN_LIGHT, HIGH);
  digitalWrite(STB_PIN_LIGHTB, HIGH);
  delay(50);
  digitalWrite(STB_PIN_LIGHT, LOW);
  digitalWrite(STB_PIN_LIGHTB, LOW);
  delay(50);
  digitalWrite(STB_PIN_LIGHT, HIGH);
  digitalWrite(STB_PIN_LIGHTB, HIGH);
  delay(50);
  digitalWrite(STB_PIN_LIGHT, LOW);
  digitalWrite(STB_PIN_LIGHTB, LOW);
}

// Measure servo PWM signal
void measureServoSignal()
{
  int pinState = digitalRead(LL_PIN_SERVO);
  if(pinState == HIGH) { 
    // Beginning of PWM pulse, mark time
    servoPulseStartTime = micros();
  } else {
    // End of PWM pulse, calculate pulse duration in mcs
    servoPulseWidth = (int)(micros() - servoPulseStartTime);

    // If servo channel is reversed, use the inverse
    if (LL_SERVO_REVERSED) {
      servoPulseWidth = (1000 - (servoPulseWidth - 1000)) + 1000;
    }
  }
}
I make videos and content on all things electronics, 3D prining and "Maker"
http://www.mkme.org
https://www.youtube.com/mkmeorg

fokkerschrauber
Posts: 1
Joined: Mon Jan 12, 2015 8:26 pm

Re: Arduino Navigation Lights for R/C

Post by fokkerschrauber » Mon Jan 12, 2015 8:50 pm

I've done little modifications on your useful sketch.
wrote the reason and which mod into the header

https://www.youtube.com/watch?v=LwMxF-aaeeY

Code: Select all

/**
Modified Version

 Erics DIY Aircraft Navigation Lights Project
My Youtube Channel  : http://www.youtube.com/user/Shadow5549
Website http://mkme.org

V1 Set up basic lighting
Changed Pins to support nano
Fixed flash sequence
 
 * Features:
 * Landing light controlled via an RC channel (can use a Y-harness on flaps or landing gear channel)
 ##* 2 fading anti-collision beacons
 * Double flash strobe  +single Flash Tail Strobe
 +Flashing Beacon 

Adapted from : 
 * @author Harold Asbridge
 * @version 0.3
 * @date 2014-06-12

*/

/**
  modified by fokkerschrauber (Austria)
  Modification:  Airbus Pattern
  Tail Strobe light added, flashes syncronized to "Wing Strobe Lights" but only with the first of the double flashes.
  And beacon is Flashing syncron together but not to Strobe.
  
  If You want other aicraft patterns i.e. Fokker 100/70 then no flashing light is syncronized
  Boeing Beacons are not syncronized, and Strobes are not double flashing
  
  Bombardier Dash 8 's Beacons are not flashing but fading
*/

// Landing light settings
#define LL_IRQ_NUMBER 0 // Interrupt number to use (0 = pin 2 on most boards)
#define LL_PIN_SERVO 2 // Servo input pin number - this needs to match whatever interrupt is used
#define LL_PIN_LIGHT 3 // Landing light output pin number
#define LL_SERVO_THRESHOLD 1500 // Servo signal threshold to turn on/off landing light (pulse width in microseconds, 1000 to 2000)
#define LL_SERVO_DEAD_ZONE 100 // Servo signal dead-zone size, eliminates flicker
#define LL_SERVO_REVERSED true   // Whether or not the servo channel is reversed

// Strobe settings
#define STB_PIN_LIGHT 4 // Pin number for strobe light output
#define STB_PIN_LIGHTB 8 // Pin number for strobe light output
#define STB_PIN_LIGHT_T 9  // Tail Strobe
#define STB_BLINK_INTERVAL 1000000 // Blink interval for strobe light in microseconds

// Anti-collision beacon settings
#define ACB1_PIN_LIGHT 5 // Pin number for anti-collision beacon 1
#define ACB2_PIN_LIGHT 6 // Pin number for anti-collision beacon 2
#define ACB_BLINK_INTERVAL 1500000
//#define ACB_FADE_MIN 0 // Minimum fade level for beacon (0-255)
//#define ACB_FADE_MAX 255 // Maximum fade level for beacon (0-255)
//#define ACB_FADE_INTERVAL 4000 // Fade step interval, in microseconds (lower numbers = faster fade)


// Var declarations
volatile unsigned long servoPulseStartTime;
volatile int servoPulseWidth = 0;
boolean curLandingLight = false;

//unsigned long lastFadeTime = 0;
unsigned long lastACBStrobeTime = 0;
unsigned long lastStrobeTime = 0;
//int currentFade = ACB_FADE_MIN;
//int fadeDirection = 1;

// Called on power on or reset
void setup()
{
  // Set up interrupt handler
  attachInterrupt(LL_IRQ_NUMBER, measureServoSignal, CHANGE);

  // Declare output pins
  pinMode(LL_PIN_LIGHT, OUTPUT);
  pinMode(STB_PIN_LIGHT, OUTPUT);
  pinMode(STB_PIN_LIGHTB, OUTPUT);
  pinMode(STB_PIN_LIGHT_T, OUTPUT);
  pinMode(ACB1_PIN_LIGHT, OUTPUT);
  pinMode(ACB2_PIN_LIGHT, OUTPUT);
  
}

// Called continuouly
void loop()
{
  unsigned long currentTime = micros();
  unsigned long currentACBTime = micros();
 

  // Check if the landing light should be turned on
  checkLandingLight();
  
  // Check if it's time to fade the anti-collision lights
  if ((currentACBTime - lastACBStrobeTime) > ACB_BLINK_INTERVAL) {
    doACBStrobe();
    lastACBStrobeTime = currentACBTime;
  }

  // Check if it's time to blink the strobes
  if ((currentTime - lastStrobeTime) > STB_BLINK_INTERVAL) {
    doStrobe();
    lastStrobeTime = currentTime; 
  }
}

// Check servo signal, and decide to turn on/off the landing light
void checkLandingLight()
{
  // Modify threshold to prevent flicker
  int threshold = LL_SERVO_THRESHOLD;
  if (!curLandingLight) {
    // Light is not on, adjust threshold up
    threshold += LL_SERVO_DEAD_ZONE;
  } else {
    // Light is on, adjust threshold down
    threshold -= LL_SERVO_DEAD_ZONE;
  }

  // Check servo position
  if (servoPulseWidth >= threshold) {
    setLandingLight(true);
  } else {
    setLandingLight(false);
  }
}

// Turn on or off landing light
void setLandingLight(boolean state)
{
  float i;
  if (state && !curLandingLight) {
    digitalWrite(LL_PIN_LIGHT, HIGH);
  } else if (!state && curLandingLight) {
    digitalWrite(LL_PIN_LIGHT, LOW);
  }
  curLandingLight = state;
}

// Fade anti-collision LEDs
//void doFade()
//{
//  currentFade += fadeDirection;
//  if (currentFade == ACB_FADE_MAX || currentFade == ACB_FADE_MIN) {
    // If we hit the fade limit, flash the high beacon, and flip the fade direction
//    if (fadeDirection == 1) {
//      analogWrite(ACB1_PIN_LIGHT, 255);

//    } else {
//      analogWrite(ACB2_PIN_LIGHT, 255);
//    }
//    delay(50); 
//    fadeDirection *= -1; 
//  }

//  analogWrite(ACB1_PIN_LIGHT, currentFade);
//  analogWrite(ACB2_PIN_LIGHT, ACB_FADE_MAX - currentFade + ACB_FADE_MIN);
//}

// Strobe double-blink
void doStrobe()
{
  digitalWrite(STB_PIN_LIGHT, HIGH);
  digitalWrite(STB_PIN_LIGHTB, HIGH);
  digitalWrite(STB_PIN_LIGHT_T, HIGH);
  delay(30);
  digitalWrite(STB_PIN_LIGHT, LOW);
  digitalWrite(STB_PIN_LIGHTB, LOW);
  digitalWrite(STB_PIN_LIGHT_T, LOW);
  delay(100);
  digitalWrite(STB_PIN_LIGHT, HIGH);
  digitalWrite(STB_PIN_LIGHTB, HIGH);
  delay(30);
  digitalWrite(STB_PIN_LIGHT, LOW);
  digitalWrite(STB_PIN_LIGHTB, LOW);
}

void doACBStrobe()
{
  digitalWrite(ACB1_PIN_LIGHT, HIGH);
  digitalWrite(ACB2_PIN_LIGHT, HIGH);
  delay(50);
  digitalWrite(ACB1_PIN_LIGHT, LOW);
  digitalWrite(ACB2_PIN_LIGHT, LOW);
  }
  
// Measure servo PWM signal
void measureServoSignal()
{
  int pinState = digitalRead(LL_PIN_SERVO);
  if(pinState == HIGH) { 
    // Beginning of PWM pulse, mark time
    servoPulseStartTime = micros();
  } else {
    // End of PWM pulse, calculate pulse duration in mcs
    servoPulseWidth = (int)(micros() - servoPulseStartTime);

    // If servo channel is reversed, use the inverse
    if (LL_SERVO_REVERSED) {
      servoPulseWidth = (1000 - (servoPulseWidth - 1000)) + 1000;
    }
  }
}

admin
Site Admin
Posts: 20
Joined: Thu Feb 20, 2014 3:01 am

Re: Arduino Navigation Lights for R/C

Post by admin » Wed Jan 03, 2018 5:35 pm

Code is now on GitHub as well here: https://github.com/MKme/ArduinoNavLights

Post Reply