Go Down

Topic: RC plane nav lights, problem with 'analogwrite' for beacon (Read 389 times) previous topic - next topic

gazz292

I'm building a radio controlled plane, and will be adding navigation lights:

2 wing tip strobes, double flash and out of sequence with each other,

A tail strobe that flashes about once a second,

A red anti collision light that mimicks a revolving light on the belly of the plane, this is to ramp up in brightness, flash at full brightness then ramp back down. simulating seeing the revolving light rotate and flash in your eyes.

Then the usual red and green wing tip lights and a white facing backwards, on constant,

And eventually landing lights that switch on when the flaps are deployed.. so the arduino will be monitoring the reciever... but thats for later, as i'm having a problem with the simulated revolving belly light running far too fast.


I've taken someone elses code originally written in 2011 which monitored the reciever, turned the nav lights on when a certian servo position was read, and turned the landing lights on when another servo position was read,
BUT i don't have the reciever yet, so can't test that.

So i stripped out the servo position monitoring portion of the code, and i have the strobes working exactly how i want,  but the revolving belly light just does not run slow enough to see the effect,  and i can't figure out how to slow it down.

This is the code i'm running now,

I believe i need to slow the timer down that the belly strobe runs on?

Code: [Select]
long currentTime = 0;


//Navigation Lights
int tailNavLight = 4;  //White constant on
int portNavLight = 5;  //Red constant on
int starboardNavLight = 6; //Green constant on


//Revolving Belly Light

int RevolvingLight = 3;  //Replicates revolving light  (analog)
int RevolvingLighteInterval = 0;
int RevolvingLightDirection = HIGH;

//WingTipStrobe Strobe 1
int WingTipStrobe1 = 7; //Flashes twice every second or so
long WingTipStrobeTimer1 = millis();
long WingTipStrobeInterval1 = 2000;
int WingTipStrobePhase1 = 1;

//WingTipStrobe Strobe 2
int WingTipStrobe2 = 8; //Flashes twice every second or so
long WingTipStrobeTimer2 = millis();
long WingTipStrobeInterval2 = 2100;
int WingTipStrobePhase2 = 1;

//Tail strobe
int TailStrobe = 9; //Flashes once a second or so
long TailStrobeTimer = millis();
long TailStrobeInterval = 2300;
int TailStrobePhase = 1;





void setup()
{

Serial.begin(115200);

  currentTime = millis();
  pinMode(portNavLight, OUTPUT);
  pinMode(starboardNavLight, OUTPUT);
  pinMode(WingTipStrobe1, OUTPUT);
  pinMode(WingTipStrobe2, OUTPUT);
  pinMode(TailStrobe, OUTPUT);
  pinMode(RevolvingLight, OUTPUT);
  pinMode(tailNavLight, OUTPUT);

  digitalWrite(portNavLight, HIGH);
  digitalWrite(starboardNavLight, HIGH);
  digitalWrite(tailNavLight, HIGH);

}



void loop()
{
  currentTime = millis();

//Belly Light
    {
      analogWrite(RevolvingLight, RevolvingLighteInterval);
      if (RevolvingLightDirection == HIGH)
        RevolvingLighteInterval = RevolvingLighteInterval + 5;
      else
        RevolvingLighteInterval = RevolvingLighteInterval - 5;
      if (RevolvingLighteInterval > 180 && RevolvingLightDirection == HIGH )
        RevolvingLighteInterval = 255; //Jump for the flash
      if (RevolvingLighteInterval > 220 && RevolvingLightDirection == LOW )
        RevolvingLighteInterval = 180; //Dump from the flash
   
      if (RevolvingLighteInterval == 255)
        RevolvingLightDirection = LOW;
      if (RevolvingLighteInterval == 0)
        RevolvingLightDirection = HIGH;
  {
        Serial.print("Revolving Light value: ");
        Serial.println(RevolvingLighteInterval);
      }
    }
   

    //White Strobe 1
    if(currentTime-WingTipStrobeTimer1 > WingTipStrobeInterval1 )
    {
      switch(WingTipStrobePhase1)
      {
      case 1:
        //strobe on first
        digitalWrite(WingTipStrobe1, HIGH);

        WingTipStrobeInterval1=50;
        WingTipStrobePhase1 = 2;
        break;
      case 2:
        //strobe off first cycle
        digitalWrite(WingTipStrobe1, LOW);
           
        WingTipStrobeInterval1=100;
        WingTipStrobePhase1 = 3;
        break;
      case 3:
        //strobe on second cycle
        digitalWrite(WingTipStrobe1, HIGH);
           
        WingTipStrobeInterval1=50;
        WingTipStrobePhase1 = 4;
        break;
      case 4:
        //strobe off second cycle
        digitalWrite(WingTipStrobe1, LOW);
         
        WingTipStrobeInterval1=2000;
        WingTipStrobePhase1 = 1;
        break;
      }
      WingTipStrobeTimer1=millis();
    }

    //White Strobe 2
    if(currentTime-WingTipStrobeTimer2 > WingTipStrobeInterval2 )
    {
      switch(WingTipStrobePhase2)
      {
      case 1:
        //strobe on first
        digitalWrite(WingTipStrobe2, HIGH);
        WingTipStrobeInterval2=50;
        WingTipStrobePhase2 = 2;
        break;
      case 2:
        //strobe off first cycle
        digitalWrite(WingTipStrobe2, LOW);
           
        WingTipStrobeInterval2=110;
        WingTipStrobePhase2 = 3;
        break;
      case 3:
        //strobe on second cycle
        digitalWrite(WingTipStrobe2, HIGH);           
        WingTipStrobeInterval2=50;
        WingTipStrobePhase2 = 4;
        break;
      case 4:
        //strobe off second cycle
        digitalWrite(WingTipStrobe2, LOW);
               
        WingTipStrobeInterval2=2300;
        WingTipStrobePhase2 = 1;
        break;
      }
      WingTipStrobeTimer2=millis();
    }

    //Tail Strobe
    if(currentTime-TailStrobeTimer > TailStrobeInterval )
    {
      switch(TailStrobePhase )
      {
      case 1:
        //strobe on 
        digitalWrite(TailStrobe, HIGH);
        TailStrobeInterval=70;
        TailStrobePhase = 2;
        break;
case 2:
        //strobe off
        digitalWrite(TailStrobe, LOW);
        TailStrobeInterval=1800;
        TailStrobePhase = 1;
        break;
      }
      TailStrobeTimer=millis();
    }



  }

groundFungus

#1
Mar 23, 2019, 07:36 pm Last Edit: Mar 23, 2019, 07:43 pm by groundFungus
Does the following code close to what you want?
Code: [Select]
//Belly Light
   {
      int bellyIncrement = 5;
      static unsigned long bellyTimer = 0;
      unsigned long bellyInterval = 50;
      if (currentTime - bellyTimer >= bellyInterval)
      {
         bellyTimer = currentTime;
         analogWrite(RevolvingLight, RevolvingLighteInterval);
         if (RevolvingLightDirection == HIGH)
            RevolvingLighteInterval = RevolvingLighteInterval + bellyIncrement;
         else
            RevolvingLighteInterval = RevolvingLighteInterval - bellyIncrement;
         if (RevolvingLighteInterval > 80 && RevolvingLightDirection == HIGH )
            RevolvingLighteInterval = 255; //Jump for the flash
         if (RevolvingLighteInterval > 120 && RevolvingLightDirection == LOW )
            RevolvingLighteInterval = 80; //Dump from the flash

         if (RevolvingLighteInterval == 255)
            RevolvingLightDirection = LOW;
         if (RevolvingLighteInterval == 0)
            RevolvingLightDirection = HIGH;
         {
            Serial.print("Revolving Light value: ");
            Serial.println(RevolvingLighteInterval);
         }
      }
   }


The millis() timer makes the fade slower and makes the flash long enough to see.  The fade speed is controlled with the bellyIncrement  variable, as well. 

gazz292

That's done the trick,  thankyou so much.

i can play with the numbers and get it exactly how i want it now :)

gazz292

Playing with using transistors (PNP) to power the led's now,

obviousely i have had to reverse the high and low states in the code for this, one problem i have, on initial power up of the arduino, all the lights turn on for about a second as it's booting.

atm it's ok, but i plan to be running the strobe led's with a good high power pulse of 4 or more times the current they can withstand being permanantly on... to get a brighter strobe effect, so having all leds turn on for even a second would kill the strobe led's pretty soon.


I'm using some PN2907 pnp transistors, the only transistors i can find right now, and i'm using the standard 1k resistor on the base (would NPN's be better?)

These transistors work fine for the strobes, nav lights, but not for the belly light,

I presume a 1k resistor is high/low enough to ensure saturation of the transistor, good for switching on and off, but not for a pwm signal?

Tho more likely i may have messed something up in the belly lights code trying to reverse it.



This is just for testing on the bread board, i am thinking of using some sort of transistor array for the final build just to keep the build small,
but i'm wary of using the standard darlington type transistor arrays due to how much current they will pull,

would fets be better?

The nav lights will be running at about 35mA (3 led's), the landing lights at about 70mA (3 leds) (that's their normal current as they are high brightness ones, 25 - 30 cd)
The belly light will run about 35mA (1 led)  and the strobes (3 leds) about 300mA each.

All at a steady 5 volts, this is from the main flight battery which is 11.1 volts, dropped to 5 volts by the motor controller, 5 amps is available but that also runs the reciever and servos.

groundFungus

#4
Mar 24, 2019, 05:49 pm Last Edit: Mar 24, 2019, 06:03 pm by groundFungus
Why PNP?  

I would use N channel logic level MOSFETs like the 2N7000 (for less than 200mA).  A 10K pull down resistor to ground from the gate will keep them turned off until setup() can run and the pinMode functions (and maybe digitalWrite(pin, LOW) can take effect.  Of course, you still need the proper current limit resistors.  The strobes (300mA) will need a different MOSFET.



gazz292

Thankyou

For some reason i'm struggeling with reversing the belly strobes code, maybe i just need to revers the high and low signals, but think i need to reverse things like the 255 for full on , 0, and thus the rest of the numbers.
i'll keep playing and hopefully get it.


Why pnp's... a lot of my stuff is still in storage 200 miles away from me... including the box of about 1000 different transistors it seems :(
for some reason i have a bag of at least 100 PN2907's with me tho... so using them just for now :)

I will order the exact components i need when i build this circuit, and will look for higher powered versions of the mosfets you mentioned,

BUT, i have yet to get the led's i will be using for the strobes (Nichia NSDW570GS-K1-P11.. they run at 70mA constant)
and they might be bright enough strobed at 140mA.

gazz292

I've just found a stash of some BFY51 transistors,  they are old, but npn's, so i'll play with them for now

groundFungus

 With bipolar transistors, don't forget the base resistor.

gazz292

That's the 1k resistor to the arduino pin isnt it?

groundFungus

#9
Mar 24, 2019, 07:44 pm Last Edit: Mar 24, 2019, 07:46 pm by groundFungus
Yes, the Arduino output pin to the base.

That may be enough to saturate the transistor, but I would go with a lower value.   The rule of thumb that I have seen is to have the base current 1/10th of the required collector current to ensure saturation.

gazz292

Gotya,  i'm pulling 4mA from each the arduino pins in my tests, so i have plenty to go higher there,

Switched to the NPN transistors, no need to reverse anything in the code now, and i no longer get all led's turning on hilst the arduino is booting up, so it's all working nice,

going to have to wait on orders to come in with the led's i will be using, and a reciever for my transmitter, then i can look into putting the code in to switch on the landing lights based on the flaps signal position,

But i'll switch over to mosfets for the final build, should i still use the 10k resistor between gate and source on the mosfets now?

groundFungus

#11
Mar 24, 2019, 09:35 pm Last Edit: Mar 24, 2019, 09:37 pm by groundFungus
Yes.  The reason for the pulldown resistor is that when the processor starts or is reset, all pins default to pinMode INPUT until setup() runs and changes the pinMode to OUTPUT.  While the pin is an INPUT the MOSFET gate is floating (state indeterminate).  It takes very little voltage to (partially) turn on the MOSFET and the floating pin can be high enough.  The resistor pulls the gate to ground so the volrage is near zero, but the resistor is a high enough value (like 10K and up) so that the pin can easily be pulled high once the pin is an OUTPUT.

gazz292

thankyou, that makes sense now,

now to find some higher current mosfets for the strobes,

So, i'll have,

3 x nav lights on all the time, each led pulls 35mA, 105mA total, so a single 2N7000 can drive them easilly,

3 x landing lights at 70mA each, thats 210mA,  TBH i imagine dropping them down to 65mA each i wouldnt notice the slightly lower brightness, so that can be another 2N7000 running those.

Then, the strobes, those will need a mosfet to each one of course, and i'm guessing i want to pulse them at 300mA,

The belly light, that will be a 35mA led, but i'm wondering if i can over run it a little as it's ramping up and down with a very short pulse of full power? 

Quick googling suggests the 'BS170' as a similar thing but with a 500mA capacity,

Do i need to worry about any figures in these mosfets, gate threshold voltage etc?  i'm switching 5 volts with 5 volts, so don't think i do

groundFungus

The biggest thing to watch in terms of picking a MOSFET (aside from current capacity) is the Vgs (gate-source voltage) that Rds(on) is specified at.  If the Vgs is less than or equal to 5V it means that the MOSFET can be fully turned on with 5V.  That makes the MOSFET a logic level device.

gazz292

ahh,

looking at the BS170 mosfet, it's got a max gate source voltage of -20 to +20 volts,

not sure if the following is imporrtiant..
max gate threshold voltage is 3v
min gate threshold voltage is 0.8v

Go Up