Hello all,
I am new to the forum and working on some lights and a horn project on my cargo bike. I often have my daughter on the back so I need to be seen, and I want to be heard when needed.
So, I have a 12 v battery, 11 high power LEDs, a 12 v motorcycle horn and a push button. What I want is the lights to flash, I can handle that. But, when I push the handlebar mounted horn button, I intend to send a high to an input, want to run an interrupt and stop the LEDs, and sound the horn. I have a hand drawn schematic attached.
I intend to control all of the LEDs and the Horn externally through 4 TIP41C NPN transistors.
That all makes sense to me, I am just struggling w/ interrupts, could someone give me an example of the code to flash an LED, until a button is pushed and then all the LED outputs (low) and the horn (high)?
Drop the thoughts of messing with interrupts. Not needed at all.
The controller loops around almost a million times per second so any sensor being activated will be noticed.
Just sense the horn button as well as the others. Then the program will fix the reset.
#define HORN_READ_INTERVAL 50ul //mS time between horn button reads
#define FLASH_TGL_PERIOD 250ul //mS time between LED state toggles
const uint8_t pinButton = 2; //I horn button input
const uint8_t pinHorn = 8; //O horn control output
const uint8_t pinLED1 = 10; //O LED string 1 control
const uint8_t pinLED2 = 11; //O LED string 2 control
const uint8_t pinLED3 = 12; //O LED string 3 control
const uint8_t
grLEDpins[] = { pinLED1, pinLED2, pinLED3 };
bool
bHornFlag = false;
uint8_t
lastHorn;
void setup()
{
pinMode( pinButton, INPUT ); //set I/Os
pinMode( pinHorn, OUTPUT );
pinMode( pinLED1, OUTPUT );
pinMode( pinLED2, OUTPUT );
pinMode( pinLED3, OUTPUT );
lastHorn = digitalRead( pinButton ); //get current state of horn button as we are looking for state changes
}//setup
void loop()
{
ReadHornButton();
DoLEDFlash();
}//loop
void ReadHornButton( void )
{
static uint32_t
timeHorn;
uint32_t
timeNow = millis();
//time for a button check?
if( (timeNow - timeHorn) < HORN_READ_INTERVAL )
return;
timeHorn = timeNow;
//read the button
uint8_t nowHorn = digitalRead( pinButton );
//different from last read?
if( nowHorn != lastHorn )
{
//save as last
lastHorn = nowHorn;
//if HIGH button is pushed
if( nowHorn == HIGH )
{
//turn off the LEDs
for( uint8_t i=0; i<3; i++ )
digitalWrite( grLEDpins[i], LOW );
//turn on the horn
digitalWrite( pinHorn, HIGH );
//and set the flag
bHornFlag = true;
}//if
else
{
//button is released
//turn off the horn
digitalWrite( pinHorn, LOW );
//and clear the flag
bHornFlag = false;
}//else
}//if
}//ReadHornButton
void DoLEDFlash( void )
{
static bool
bFlashFlag = false;
static uint32_t
timeFlash;
uint32_t
timeNow = millis();
//time for an LED update?
if( (timeNow - timeFlash) < FLASH_TGL_PERIOD )
return;
//save this time for next toggle
timeFlash = timeNow;
//toggle the state flag
bFlashFlag ^= true;
//if the horn is not on right now...
if( bHornFlag == false )
{
//change the state of the LEDs to match the flash flag
for( uint8_t i=0; i<3; i++ )
digitalWrite( grLEDpins[i], (bFlashFlag == true) ? HIGH:LOW );
}//if
}//DoLEDFlash
Thanks Railroader and Blackfin. I appreciate both of your responses. I hadn't put it together that the nano is looping that fast, I incorrectly thought it was looping only at the speed required to pass through a loop.
Blackfin,
I uploaded the code you offered and it does the trick, uploaded, and flashes the LEDs, then, when I put a high on pin 2, the LED extinguish. Just as I wished. I was surprised though at how hot my transistors and resistors (the ones inline w/ the LEDs) get! When I hooked it up to the circuit w/ the horn and push the button, the LEDs extinguish but there is not enough power to sound the horn. Seems I have a short perhaps? I don't see how the code could create such heat.
Thank you
Ok, let me double check. I just tried it again on my bench and it is working and not getting hot. Must have been a short.
I will report once I get it back on the bike.
Thank you both again
As Railroader notes, horns -- even dinky motorcycle horns (motorcylist here so I can say that...) can consume a fair amount of current. On my Tuono the horn is on a circuit protected by a 15A fuse.
The TIP41C has a fairly low hfe parameter (maximum is about 75. You have 330-ohm base resistors giving a base current of something like 5V-0.7V/330 or 13mA from the MCU. The collector current at this base current is going to be pretty low. You'll likely find that the transistors are not "saturated" and are thus still fairly resistive. Since P = I^2xR, you're going to be dissipating power and producing heat from those transistors.
The absolute maximum base current for those is like 3-amps. With 13mA you're only just tickling them.
If the heating condition returns or whatever, I'd suggest changing to some N-channel MOSFETs. For example, the ON Semi FQP30N06L:
I put it back on the bike and it starts out ok. Power on, LEDs flash. When I pull 8 high, LEDs quit, but no horn (only a slight blip, not enough current). Meanwhile, I believe it is only the HORN transistor that is heating up. I swapped that one out, no change.
The horn I am using is just a cheap, motorcycle 12 volt 1.5 amp horn from amazon. The battery has been plenty strong to sound it loudly, I had this hooked up prior w/ just the horn.
I wondered about using MOSFETs rather than NPNs.
Thanks again, I will roll it around in my head for the night.....
I have ordered some of the MOSFETs listed above. WOuld you be able to help identify the ideal resistors needed for the new circuit? I have attached a new photo of my schematic w/ some more details about the LEDs.
Currently I have a 3W 3.9 ohm for the white LEDs and a 3W 2.7 for each of the amber and red LED circuits. Are these reasonable?
What should I use off the gates of the MOSFETs?
slackerz:
I have ordered some of the MOSFETs listed above. WOuld you be able to help identify the ideal resistors needed for the new circuit? I have attached a new photo of my schematic w/ some more details about the LEDs.
Currently I have a 3W 3.9 ohm for the white LEDs and a 3W 2.7 for each of the amber and red LED circuits. Are these reasonable?
What should I use off the gates of the MOSFETs?
Do you have any information (datasheets? manufacturer & partnumber?) for the various LEDs you're using?
Those resistors look fine. 3W on the amber and reds might be overkill (the Pd is something like 600mW I think) but better safe than sorry.
Speaking of safe: I'd add a fuse to the feed from the 12V motorcycle battery -- at or near the 12V battery -- to protect things in the event of a short or component failure. Max load looks to be ~3A so a 5A fuse would likely be appropriate.
thanks again guys.
I should have incorporated it in the drawing, but I do have a fuse off the battery, agree, don't want lights and horn to be safe and then cause an electrical fire! :o
Will 330 ohms be good for the MOSFETS?
And, thanks Railroader for the diode across the horn, I had wondered about that, I will look to add that in.
I was the designer of heavy, batteri powered fork lift trucks and they were equipped with old fashioned horns, like the old door bells. Sparkgenerators, and lots of current...
Suggest swap the pushbutton and 10k resistor over. Not having 5 V supply wires running around the place just slightly safer in case of accidental shorts, which are more likely to go to ground. Also enables use of internal pullup but considering the risk of interference pickup in this situation, I suspect an additional pullup and possibly even of a lower value will be desirable,
slackerz:
What value resistor would be good for a pullup?
We don't really know!
There are two considerations here. One is the quality of the pushbutton. Some "tact" buttons - the little ones using domed clicker plates - contain a lubricant which may absorb moisture and cause a current leakage, so you may need a lower pull-up value to counter this. Also, some contacts may require "wetting" due to oxide buildup.
The second concern is the possibility of interference pickup on longer wires, particularly due to transients from such things - as your horn! It is desirable that the two wires to the button be a pair, never separated along their route so that there are no open loops to inductively pick up impulses and presence of the ground tends to shield the signal wire from capacitive pickup.
So a lower resistance value tends to absorb such interference - in proportion. But a lower resistance also means more current when the switch is closed and you generally do not want your circuit drawing more current than necessary.
Interestingly, a capacitor - say 220 nF (0.22 µF) - across the switch can improve things by providing a "wetting current" impulse as the switch closes as per the Wikipedia description, and absorbing interference.
But there is no automatic specification for the pullup value. The internal pullup of the Arduino is about 47k so will pass 100 µA through the switch. 10k external would pass 500 µA and 4k7, 1 mA etc. 220 Ohms would pass 23 mA which may or may not be necessary.