This is the first and only code I've ever written so please be gentle. It was written to provide Bi-color (red/green) LED and two tone audible alerts of battery condition. The idea is to conserve as much power as possible.
Known Bug - If an LED is lit when the battery state changes it will stay lit while the other LED blinks. I don't know how to trap this.
Issue - I couldn't get away from delay() completely while using tone(). The code works but I don't know if this is causing the LED bug.
Please advise on what the LED bug might be and/or on how to clean this up, particularly on how to get rid of delay() in the beep function.
/*DTI sketch version 5.0.1
Control code for:
- Bi-color power LED indication
- Transmitter selection
- Audible alerts of transmitter position
- Audible low battery alert
- Alert cancel and Alert off functions
Created By Kirk Sceviour
08 Feb 2015
*/
boolean battchange = false; //remains false until PG indicates a change in battery status
boolean powergood = true; //power supply is good
boolean discard = false; //discard any generated audible alert
boolean noalerts = false; //alerts are selected on
#define ALERTOFF 13
#define CANCEL 12
#define TXSEL 8
#define redLED 10
#define greenLED 9
#define AUDTONE 6
#define SWCOMM 7
#define PG 4
//for blink without delay functions
#define LED_ON 400 //blink interval millis
#define LED_OFF 3000
unsigned long ms; //time from millis()
unsigned long msLast; //last time the LED changed state
boolean ledState; //current LED state
//for beep functions
unsigned long msBeep; //time from millis()
unsigned long msBeepLast;//last time of beep
unsigned int beepFreq = 440; //frequency of beep
unsigned long beepTime = 200; //duration of beep
unsigned long battBeepPause = 120000; //time between beeps
boolean audState; //current audible state
void setup()
{
pinMode(CANCEL, INPUT); //Cancel button input, mom LOW
pinMode(ALERTOFF, INPUT); //To Alerts Off switch. LOW = off
pinMode(TXSEL, INPUT); //To TXSEL switch. Low indicates COMM 2 selected
pinMode(redLED, OUTPUT); //Power low indication
pinMode(greenLED, OUTPUT); //Power good indication
pinMode(SWCOMM, OUTPUT);//Output to selector IC. HIGH = COMM 2
pinMode(PG, INPUT); //Normally high, a low indicates poor battery
pinMode(AUDTONE, OUTPUT); //PWM output pin
Serial.begin(9600); // for debugging
int pgValue = digitalRead (4); //for debugging
}
void loop()
{
msBeep = millis();
ms = millis();
noTone(6);
if (digitalRead(PG) == HIGH)//power good
{
blinkgreenLED();
powergood = true;
}
else
blinkredLED();
powergood = false;
lowbattBeep();
}
//Beep and Blink without delay functions. All other code above this.
void lowbattBeep(void)
{//is it the first indication of low battery?
if (digitalRead(PG) == LOW && battchange == false)
{
Serial.print(" first ind ");
battchange = true; //change the battery state
}//was it momentary?
if (digitalRead(PG) == HIGH && battchange == true)
{
battchange = false; // reset
noTone(6); //make sure the pin is off
Serial.print (" battchange reset ");
}
if (digitalRead(PG) == LOW)
{ //check time since last beep
if (msBeep - msBeepLast > (battBeepPause))
{
tone(6, beepFreq, beepTime); //play
delay(200);
noTone(6);
tone(6, 250, beepTime);//lower tone
delay(200);
noTone(6);
msBeepLast = msBeep;
}
}
}
void blinkgreenLED(void)
{
//determine the last time the LED was on
if (ms - msLast > (ledState ? LED_ON : LED_OFF))
{
//switch states if necessary
digitalWrite(greenLED, ledState = !ledState);
msLast = ms;
}
}
void blinkredLED(void)
{
if (ms - msLast > (ledState ? LED_ON : LED_OFF))
{
digitalWrite(redLED, ledState = !ledState);
msLast = ms;
}
}