LeftBlinkSwitchState = digitalRead(LeftBlinkSwitch); //reads the switch value
...
////////Start Left Blinker Code//////
if(LeftBlinkSwitchState == HIGH) //if the left blinker switch is on, then...
{
analogWrite(LeftBlink, 225); //starts initial rapid blink
Here's my tentative solution... Use the Crossroads-diode solution for the switches. Have interrupts to determine switch-state changes. In the interrupt routine turn on/off flags indicating which switches are currently down. Have a main loop that blinks things. In the main loop, where you blink/unblink just turn on the things whose corresponding switches are on, and leave off the others. That way they all blink (the ones that are supposed to) and not only that, they blink together (unlike some gadgets I have here).
Okay, I'll have to do some research on this diode gate stuff, I'm still pretty new at all this.
The event manager seems promising, thanks for the link TeslaFan.
Reading through these suggestions I don't know if I can keep the initial rapid flash followed by pulse (blinker), or followed by steady-on (brake light). If I'm just going to use these interrupts and diodes and whatnot just to come back to plain old blinking, I'll just keep things simple and use the stock equipment. Can I keep my original flashing idea AND use these work-arounds?
I'd really like to keep the rapid flash since it is such a great attention getter (read: life saver).
"rapid flash" rapid is all relative. On/of 5 times a second vs 1 times a second is hardly rapid electronically.
Yet visually it may seem a world of difference, and depending on the viewing distance may blur into always on even.
Okay, I'll have to do some research on this diode gate stuff, I'm still pretty new at all this.
You really should look into implementing the 'Pin Change Interrupts' that are inherent to the ATmega chip used in the Arduino. Essentially any of the I/O pins on the chip can be configured to generate an interrupt when the level on that pin changes. These interrupts are not as configurable as the 'External Interrupts' used by the 'attachInterrupt' function but they do work nicely.
[EDIT:] I found some information on this at Trossen Robotics Community Database Error scroll down to the part headed 'Wait, I ran out of interrupts!'. Everything there applies equally to the ATmega328 so don't let the reference to the 168 put you off.
Okay, I think I'm starting to get it. I can have both flash speeds "running" in the background, but only call them when needed and if a time has gone by. I'll draw up a flowchart and post it to see if I can make this all make sense.
In looking into the Interrupts idea you suggested Floresta, I see that I cannot use delay() while inside the interrupt. I'm looking into a workaround, but it seems that if I use the interrupt method I can't do the blinking that I need. Unless there is another method to blink that I am not seeing?
I see that I cannot use delay() while inside the interrupt.
In general you never want to do very much inside any interrupt. What you should do is set some sort of flag to indicate that some condition has been detected and then exit the interrupt as quickly as possible. Your main program should check the flag and react to the detected condition as required.
So how is reacting to a flag any different than reacting to a physical button input? The Arduino will still be able to pump out only one set of LED instructions at a time whether it is triggered by a button or a flag, right? I need lights to react independent of each other, and continuously (overlapping).
I need the brake light to be able to come on and off regardless of whether a blinker is on, and visa versa.
Even with all these fancy tricks, what I'm understanding is that the Arduino will still only be able to react to one input at a time.
It reacts by noticing the input. That doesn't mean it can only do one thing afterwards.
Here's an example. You notice the cat is hungry. So you feed it once a day. You notice the garden needs watering. So you water it once a week. You notice the car needs washing. So you wash it once a month.
But that doesn't mean that if the car needs washing, you don't feed the cat.
As a person you build up in your brain a list of things that need doing from time to time. You may check that list every hour, or minute, or second even. And if the time is up to do something ("oh, time to water the garden") you do it.
Okay, that makes sense. Problem is, I need to weed the garden while washing the car. Or feed the cat while weeding the garden while washing the car, then stop feeding the cat while still washing the car, and then start feeding the cat again while STILL washing the car and weeding the garden.
Or wash the garden while feeding the car and weeding the cat, even.
It does me no good for my brake light to come on whenever it feels like it. I need my brake light to turn on immediately upon pressing the brake, even if my turn signal is on, and I'd prefer to have the attention grabbing rapid flash sequence fire at the start of either light coming on.
I understand now (I think) how I can have my brake light be turned on or off depending on what it's previous state was, and I think I can do the same with the blinking pattern for the blinkers, but I would have to omit the initial rapid-flash sequence Which, if that is the case, I'll just chuck the whole Arduino idea and go back to the stock system.
Or am I being a completely infuriating ass and not understanding something here?
As you go through the main loop, it flashes an LED quite fast.
Now put a condition on it:
void setup() {
pinMode (13,OUTPUT);
} //end of setup
void loop() {
if ((millis () & 0x7F) < 63 && indicator_button_down)
digitalWrite(13, HIGH); // only flash light if indicator button is on
else
digitalWrite(13, LOW);
}
The condition is what is set in the interrupt routine. And after that you could flash a different LED, at a different rate, depending on if another condition is set.
So in this way all the speeds of flashing are running in the background, but aren't actually being called until needed? Okay, I can see that. I have some "yea, but"s about it still, but I'll play with it first to see if I can answer my own questions before asking.
So in this way all the speeds of flashing are running in the background
In a way, yes.
Stop and think about it.
Once a LED is lit, or shut off, it stays in that state - you don't have to refresh it, and it stays in that state for the vast majority of the time.
The only time the processor is involved is at the transitions from on to off or vice versa, and these transitions take very little time; just long enough to toggle a variable and write to a port.
A microsecond or so, allowing for Arduino overheads.
You could do thousands of these transitions per second, and a human user would perceive all the operations as concurrent
Except if I were running a pulse width modulation, right? Yes, those thousands of transitions would be happening every second, but the processor would be stuck thinking about that transition and not much else. Or is that also so "slow" that other operations could still continue?
I guess the solution there would just be to drop the PWM pulsing of the brake light and go for normal on/off blink.
I think I'm slowly coming around to seeing how this is possible. Once I wrap my head around that then I should be able to program it in.
I don't think you have to PWM brake lights. My own tests show that much faster than around 50Hz is invisible (that is, too fast to see). And the processor clock is 16 MHz.
Except if I were running a pulse width modulation, right?
Even if you were running PWM, so yes, wrong.
The processor isn't involved in the PWM operation, beyond setting the registers - all the PWM is handled by logic, as a simple peripheral, just like the processor isn't sampling the serial input at 16 times the baud rate to find the initial edge and middle of a start bit.
Oh, cool then. I had assumed that the processor was handling all that, but if it's just throwing that bone to another component then we are in business. I'm still working in what I think is the right direction, so we'll see where I end up. Thanks for your help.
Huh? The interrupt could be used to detect the switch press, not to flash the LEDs. However if you go through the main loop fast enough a simple digitalRead should do it.