Go Down

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

groundFungus

#15
Mar 25, 2019, 02:26 am Last Edit: Mar 25, 2019, 02:42 am by groundFungus
Quote
RDS(ON)Static Drain-Source On-Resistance   VGS = 10V, ID = 200mA  All  1.2  5Ω
This is the line from the data sheet that specifies the Rds(on).  Notice that the Vgs where the on resistance is measured is 10V.  That means that this particular MOSFET is not logic level and will not fully turn on with a 5V gate signal.

The gate threshold voltage are the voltages where the MOSFET turns off.  Not really relevant in a switching scenario cause the gate will be at 5V (5V Arduino) or 0V.

gazz292

Dang, i seem to be drawing a blank,

Searching for the BS170, people are saying it is a logic level devise,

Then people are talking about mosfets that can carry 50 amps or so,  way overkill for what i need,

Is there a basic simple mosfet that can handle 500mA at 5 volts, turned on and off by a 5v signal.

Buying from RS components as i'm getting the led's from them too, but their mosfet search tool doesnt seem to have one for the VGS part

gazz292

Gonna get some ZVN4206A mosfets, 

they have a rds(on) of 1.5 ohms, VGS = 5x, ID = 500mA

gazz292

I've added in the parts of the sketch for the landing lights being ccontrolled by servo position, i think i have it working fine (used another arduino running a servo sketch that was sweeping up and down... untill i get my new reciever and can test this properly)

Can someone have a quick look at me sketch and point out any errors or things likely to cause me issues please, or if there's a better way to do things etc.

Code: [Select]
//Read PPM from one channel and use to switch to NavLights on

int LightSwitch = 4;  //turns on Landing lights.  Rc channel 6
unsigned int LightSwitchValue;
long currentTime = 0;


//Navigation Lights
int tailNavLight = 12;  //White constant on facing rearwards
int starboardNavLight = 11; //Green constant on
int portNavLight = 10;  //Red constant on

//Revolving Belly Light
int RevolvingLight = 9;  //Replicates revolving light  (analog)
int RevolvingLightInterval = 0;
int RevolvingLightDirection = HIGH;

//LandingLights
int LandingLight = 8;  //White Turns on with switch



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

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

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


//On Arduino LED
int ledPin = 13;
int ledState = LOW;

//Debugging here
boolean debug = true;  //turn on to see debug messages in serial monitor


void setup()
{
  Serial.begin(115200);

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

  pinMode(ledPin, OUTPUT);

  //Turn on NavLights
  digitalWrite(portNavLight, HIGH);
  digitalWrite(starboardNavLight, HIGH);
  digitalWrite(tailNavLight, HIGH);
}


void LandingLightsOn()
{
  digitalWrite(LandingLight, HIGH);
}
void LandingLightsOff()
{
  digitalWrite(LandingLight, LOW);
}
void pulse()
{
  LightSwitchValue = pulseIn(LightSwitch, HIGH); //times out in 20000 uS
  //  LandingGearSwitchValue = pulseIn(LandingGearSwitch, HIGH, 20000) //times out in 20000 uS
  //Adjust these values for your receiver



  if (LightSwitchValue > 1400) //landing lights on
  {
    LandingLightsOn();
    if (debug)
      Serial.println("Landing Lights On");
  }
  if (LightSwitchValue < 1200) //landing lights off
  {
    LandingLightsOff();
    if (debug)
      Serial.println("Landing Lights off");
  }

}

void loop()
{

  pulse();  //Check Radio Receiver position.
  currentTime = millis();

  {
    //Revolving Belly Light
    {
      int revolvingIncrement = 5;
      static unsigned long revolvingTimer = 0;
      unsigned long revolvingInterval = 90;
      if (currentTime - revolvingTimer >= revolvingInterval)
      {
        revolvingTimer = currentTime;
        analogWrite(RevolvingLight, RevolvingLightInterval);
        if (RevolvingLightDirection == HIGH)
          RevolvingLightInterval = RevolvingLightInterval + revolvingIncrement;
        else
          RevolvingLightInterval = RevolvingLightInterval - revolvingIncrement;
        if (RevolvingLightInterval > 80 && RevolvingLightDirection == HIGH )
          RevolvingLightInterval = 255; //Jump for the flash
        if (RevolvingLightInterval > 200 && RevolvingLightDirection == LOW )
          RevolvingLightInterval = 80; //Dump from the flash

        if (RevolvingLightInterval == 255)
          RevolvingLightDirection = LOW;
        if (RevolvingLightInterval == 5)
          RevolvingLightDirection = HIGH;
      }
    }


    //WingTip 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();
    }

    //WingTip 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 cyclerevolving
          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

#19
Mar 26, 2019, 10:22 am Last Edit: Mar 26, 2019, 10:26 am by groundFungus
Code: [Select]
int tailNavLight = 12;
If you use:
Code: [Select]
const byte tailNavLight = 12;
for your pins you save 2 bytes of SRAM for each pin.  And if you accidentally try to change the pin number in the code the compiler will throw an error.

Code: [Select]
int RevolvingLightDirection = HIGH;
Storing a boolean in an int data type wastes a byte of SRAM.

Code: [Select]
long WingTipStrobeTimer1 = millis();
long WingTipStrobeInterval1 = 2000;

millis() data type is unsigned long.  Any variable dealing with millis() timing should be unsigned long.

Code: [Select]
LightSwitchValue = pulseIn(LightSwitch, HIGH); //times out in 20000 uS
This is a bit nit picky, but your comments should be accurate.  Without the third (timeout) parameter the default timeout is 1 second.

gazz292

Thankyou,

I'll change the pins from int  to const byte,

Do i do the same with the revolving light bit?

i.e. go from :
int RevolvingLightDirection = HIGH;
to
const byte RevolvingLightDirection = HIGH;


How do i do an unsigned long thing to the mili's statements?

Sorry about the commenting bit,  that part of the code originally was:
  LightSwitchValue = pulseIn(LightSwitch, HIGH, 20000); //times out in 20000 uS

but i found that when the nav lights were off... in the serial viewer it was cycling on/off/on/off all the time,

when the nav lights were on... it was steady 'nav lights on' repeated over till it changed to off, and went back to on/off/on/off etc (it might have been the other way round.. i.e. cycling when they were off, not when on)

groundFungus

#21
Mar 26, 2019, 05:11 pm Last Edit: Mar 26, 2019, 05:12 pm by groundFungus
Code: [Select]
i.e. go from :
int RevolvingLightDirection = HIGH;
to
const byte RevolvingLightDirection = HIGH;

No, you don't want to use the const (constant) modifier for anything that you will want to be able to change later.  The const modifier makes sense for a pin cause you will never change the pin number associated with the variable.
And the data type for RevolvingLightDirection can be boolean cause it can only have the value LOW or HIGH.
Code: [Select]
boolean RevolvingLightDirection = HIGH;

Quote
How do i do an unsigned long thing to the mili's statements?
Just change the long to unsigned long
Code: [Select]

long currentTime = 0;
long WingTipStrobeTimer1 = millis();
long WingTipStrobeInterval1 = 2000;

to:
Code: [Select]

unsigned long currentTime = 0;
unsigned long WingTipStrobeTimer1 = millis();
unsigned long WingTipStrobeInterval1 = 2000;

And so on for any timing variable declarations.

Quote
Sorry about the commenting bit,  that part of the code originally was:
No problem.  Like I said a bit of nitpicking.

Here is a good tutorial on data types that may be of interest.

gazz292

Thankyou for all you help,

i've re-written the code the way you suggested, it all works nicely,

My mosfets and the white led's arrived today,  so i breadboarded them up, the led's run at 70mA for constant on, and i pulsed them at 350mA with no problems (left the setup running for a few hours, will likely run 20 minutes max at a time in the plane)

Everything is running cold.




only slight issue i've noticed, if the input pin is floating the arduino sometimes runs really slow, so the 50mS flash for the strobes turns into 1 second flashes and so on.

Hopefully that won't be an issue when it's connected up in the plane, the input pin will be connected to the reciever, and that will be on anytime the planes battery is plugged in.

But i'm wondering if i should have some sort of watchdog timer in the code, but not sure how to do that or how fast it could react... something that will shut the strobes down if they are on for more than 50mS?? as that's all i'm worried about, the led's getting 350mA constant.

gazz292

Is the 180 oum resistor to the gate of the MOSFETs sort of universal?

Of do they need changing depending on the current passing through the MOSFETs from source to drain, like the base resistor on a transistor needs adjusting to ensure it,s fully saturated when driving leds?

groundFungus

#24
Apr 13, 2019, 07:47 pm Last Edit: Apr 13, 2019, 07:47 pm by groundFungus
Quote
Of do they need changing depending on the current passing through the MOSFETs from source to drain, like the base resistor on a transistor needs adjusting to ensure it,s fully saturated when driving leds?
The 180 Ohm resistor is to limit the current out of the Arduino output and into the gate while the gate capacitance charges.  A MOSFET is a voltage controlled device* so the current into the base is virtually 0 once the gate capacitance is charged.  The need for the resistor is a topic of debate.  I go with the more conservative side and include it.   Do a Google for "mosfet gate resistor?" for lots of discussion.

*BJT transistors are current controlled.

gazz292

Thakyou,

it was just something i was thinking about after i built the circuit.. i'm having a little issue with the led current limiting resistors running hot... when i breadboard the circuit using through hole 2n7002 mosfets, everything runs cool,

but on the pcb i made, the led current limiting resistors are running at upto 50 degrees C... with 5.5 volts in, 3.4 volt drop led's, and 70mA current to them.

I'm using 2N7002KT1G surface mount mosfets, and 0805 size, 0.125w 180 ohm and 10k resistors at the mosfets, 
then 0.6 watt through hole resistors for the led's,   and i've checked and checked and can't see or measure any shorts on the pcb, or on the wires from the pcb to the led's in the plane.

The strobe and belly beacon led's resistors are running cool... but they are not being run constantly like the others are.

groundFungus

With the current limit resistors dropping 2.1V (5.5 - 3.4) at 70mA the power dissipated is 147mW so the 0.6W (?*) resistors should not be hot.  What is the resistor value?

* I have not heard of 0.6W through hole resistors.

gazz292

#27
Apr 15, 2019, 02:28 am Last Edit: Apr 15, 2019, 03:13 am by gazz292 Reason: url's
25 ohm... i've just realised the white led's have a 3.7 forward voltage.
Led's i bought from RS Components


i'm not sure on the 0.6w resistor rating either,  they are the physical size of standard quarter watt resistors i think.
Resistors i bought from RS Components

I am thinking that maybe i am getting the culmitive heating of all the resistors on the small pcb adding up... the mosfet shield i made is not much larger than an arduino pro micro (33mm x 18mm) and maybe i should move the resistors (at least for the constant on led's) off the board and inline with the led wiring in the plane, and possibly go to maybe 1 watt resistors, or 2 of the ones im using now in paralell (i'd need 2 x 12 ohm resistors then i believe?)

On the breadboard circuit, the led's 25 ohm resistor is sitting at 40 degrees C, and it's pulling exactly 70mA according to my multimeter and bench psu,




Go Up