Need help for a "Low Battery" alarm [SOLVED]

Ok, so here it is!!
I'm using this code

/************************************************************
   Led dimmer using a logic lever MOSFET transitor
   Supply voltage is 12V / LED build for 12V, so no resistor is needed
   PIR-sensor power is fed from Arduino 5V / GND-pins. 
   PIR output to digital pin (D2) - polled
   PIR can be retriggable or non retriggable
   LED switches on when PIR detects movement
   LED output will stay 'ON' until 5 minutes of 'PIR silence'
   LED (Mosfet gate) MUST be connected to PWM pin. (D11)
   this code can be drastically redused on volume - made for readability
****************************************************************/   
// declare global constants 
const byte led = 11;         // connect to gate
const byte pir =  3;         // PIR signal out 
const byte turnOnTime = 1;   // turn on/off time in seconds !(will be forced:  50 > time > 0)
const byte secondsToOff = 5; // seconds of 'silence' before "lights out" !! ALTER THIS VALUE
const boolean debug=false;
// declare global variables
boolean lightIsOn = false;   // remember LED-status 'now'
unsigned long timeToTurnOff; // time when led  will turn off
unsigned long timeNow;       // current time

//*************************************************************
  //DisplayMoreThan5V sketch
  //prints the voltage on analog pin to the serial port
  //Do not connect more than 5 volts directly to an Arduino pin.

const float referenceVolts = 5;        // the default reference on a 5-volt board
//const float referenceVolts = 3.3;  // use this for a 3.3-volt board

const float R1 = 2100; // value for a maximum voltage of 15 volts
const float R2 = 1000; // determine by voltage divider resistors, see text
const float resistorFactor = 1023.0 / (R2/(R1 + R2));  
const int batteryPin = 7;         // +V from battery is connected to analog pin 7

void setup() 
{
  // set status og used I/O-pins
  pinMode(led,OUTPUT);
  pinMode(pir,INPUT);  
  Serial.begin(9600);

}
//********************************
// small functions and procedures - to make reading of main prog easier
boolean heWantsLightsOn()
{
  return (digitalRead(pir)==HIGH);  
}
//********************************
void turnLightsOn(byte period)
{
  // now the LED shall increase light intensity over "turnOnTime" seconds
  long delayTime = period * 5 ;
  for (byte i=0; i<255; i++) 
  {
    analogWrite(led,i);
    delay(delayTime);
  }
  digitalWrite(led,HIGH); // no PWM needed - turn on 100%
  lightIsOn=true;         // remember status
}
//**********************************
void turnLightsOff(byte period)
{
  // now the LED shall decrease light intensity - slowly to zero 
  long delayTime = period*5 ;
  for (byte i=254; i>0; i--) 
  {
    analogWrite(led,i);
    delay(delayTime);
  }
  digitalWrite(led,LOW); // no PWM needed - turn off
  lightIsOn=false;         // remember status
}
//**********************************
void loop() 
{
  timeNow=millis();  // note time now
  if (heWantsLightsOn()) // if movement -> be light! 
  {  
    if (!lightIsOn) turnLightsOn(turnOnTime);   // if still dark - be light! (else light were on already)
    // set 'new' time for off -since you just told 'stay on for some mor minutes..)
    timeToTurnOff=timeNow + secondsToOff * 1000;  // set 'off-time' some minutes into the future (milliseconds used)
    if (debug) Serial.println("renew for one minute");
  }
  // now test for "Elvis  has left the building"
  if (timeNow > timeToTurnOff) // is it time to turn off ??
  {
    if (lightIsOn) turnLightsOff(turnOnTime);  // if light still are on: turn them off
  }
{
   int val = analogRead(batteryPin);  // read the value from the sensor
   float volts = (val / resistorFactor) * referenceVolts ; // calculate the ratio
   Serial.println(volts);  // print the value in volts
}
}
//***************END***********************

I also have a Velleman MK174 Kit to play a message when the Battery is low. I think it shoud be around 11.5 volts (out of 14.4)
Is there someone who could help there??

So what is the problem exactly?
what do you get,
what did you expect
what did you try sofar?

const float R1 = 2100; // value for a maximum voltage of 15 volts
const float R2 = 1000; // determine by voltage divider resistors, see text
const float resistorFactor = 1023.0 / (R2/(R1 + R2));
const int batteryPin = 7; // +V from battery is connected to analog pin 7

// use a comment to tell constant used : 5/1023*3.1 = 0,015151515151
const float resistorFactor =0,015151515151

int val = analogRead(batteryPin); // read the value from the sensor
float volts = (val / resistorFactor) * referenceVolts ; // calculate the ratio
Serial.println(volts); // print the value in volts

int val = analogRead(batteryPin);  // read the value from the sensor
   float volts = val  * resistorFactor ; // calculate the ratio
   Serial.println(volts,1);  // print the value in volts

Updated the code a little to something that I myself could understand a little better.

/************************************************************
   Led dimmer using a logic lever MOSFET transitor
   Supply voltage is from 14.4v and down/ LED build for 12V, 
   But voltagedrop over Transistor and wires makes it ok.
   PIR-sensor power is fed from Arduino 5V / GND-pins. 
   PIR output to digital pin (D3) - polled
   PIR can be retriggable or non retriggable
   LED switches on when PIR detects movement
   LED output will stay 'ON' until 5 sec of 'PIR silence'
   LED (Mosfet gate) MUST be connected to PWM pin. (D11)
   this code can be drastically redused on volume - made for readability
****************************************************************/   
// declare global constants 
const byte led = 11;         // connect to gate
const byte pir =  3;         // PIR signal out 
const byte turnOnTime = 1;   // turn on/off time in seconds !(will be forced:  50 > time > 0)
const byte secondsToOff = 5; // seconds of 'silence' before "lights out" !! ALTER THIS VALUE
const boolean debug=false;

// declare global variables
boolean lightIsOn = false;   // remember LED-status 'now'
unsigned long timeToTurnOff; // time when led  will turn off
unsigned long timeNow;       // current time

//Setup for measuring voltage
// number of analog samples to take per reading
#define NUM_SAMPLES 10

int sum = 0;                    // sum of samples taken
unsigned char sample_count = 0; // current sample number
float voltage = 0.0;            // calculated voltage


// one time setup
void setup() 
{
  // set status og used I/O-pins
  pinMode(led,OUTPUT);
  pinMode(pir,INPUT);  
  Serial.begin(9600);
}
//********************************
// small functions and procedures - to make reading of main prog easier
boolean heWantsLightsOn()
{
  return (digitalRead(pir)==HIGH);  
}
//********************************
void turnLightsOn(byte period)
{
  // now the LED shall increase light intensity over "turnOnTime" seconds
  long delayTime = period * 5 ;
  for (byte i=0; i<255; i++) 
  {
    analogWrite(led,i);
    delay(delayTime);
  }
  digitalWrite(led,HIGH); // no PWM needed - turn on 100%
  lightIsOn=true;         // remember status
}
//**********************************
void turnLightsOff(byte period)
{
  // now the LED shall decrease light intensity - slowly to zero 
  long delayTime = period*5 ;
  for (byte i=254; i>0; i--) 
  {
    analogWrite(led,i);
    delay(delayTime);
  }
  digitalWrite(led,LOW); // no PWM needed - turn off
  lightIsOn=false;         // remember status
}
//**********************************

void loop() 
{
  timeNow=millis();  // note time now
  if (heWantsLightsOn()) // if movement -> be light! 
  {  
    if (!lightIsOn) turnLightsOn(turnOnTime);   // if still dark - be light! (else light were on already)
    // set 'new' time for off -since you just told 'stay on for some mor minutes..)
    timeToTurnOff=timeNow + secondsToOff * 1000;  // set 'off-time' some minutes into the future (milliseconds used)
    if (debug) Serial.println("renew for one minute");
  }
  // now test for "Elvis  has left the building"
  if (timeNow > timeToTurnOff) // is it time to turn off ??
  {
    if (lightIsOn) turnLightsOff(turnOnTime);  // if light still are on: turn them off
  }
  {
    // take a number of analog samples and add them up
    while (sample_count < NUM_SAMPLES) {
        sum += analogRead(A2);
        sample_count++;
        delay(10);
    }
    // calculate the voltage
    // use 5.0 for a 5.0V ADC reference voltage
    voltage = ((float)sum / (float)NUM_SAMPLES * 4.73) / 1024.0;
    // send voltage for display on Serial Monitor
    // voltage multiplied by 3 when using voltage divider that
    // divides by 3. 3 is the calibrated voltage divide
    // value
    Serial.print(voltage * 3);
    Serial.println (" V");
    sample_count = 0;
    sum = 0;
}
}
//***************END***********************

The more specific question is now:
How can I save the "Voltage" (which is acurate) and use it for an "HIGH" statement for 10ms at some pin?

and sorry for the inconvinience knut_ny

How can I save the "Voltage" (which is acurate)

on top, declare: float voltagetoremember;
..in running program: voltagetoremember = voltage; //voltage from ADC

and use it for an "HIGH" statement for 10ms at some pin?

if (voltagetoremember > value_of_your_choice)
{
digitalWrite(any_output_pin_number,HIGH);
delay(10);
digitalWrite(any_output_pin_number,LOW);
}

I'm loving you Knut_NY :slight_smile:

knut_ny:

How can I save the "Voltage" (which is acurate)

on top, declare: float voltagetoremember;
..in running program: voltagetoremember = voltage; //voltage from ADC

and use it for an "HIGH" statement for 10ms at some pin?

if (voltagetoremember > value_of_your_choice)
{
digitalWrite(any_output_pin_number,HIGH);
delay(10);
digitalWrite(any_output_pin_number,LOW);
}

Why involve a second variable ?
Having derived the voltage then

if (voltage > value_of_your_choice)
{
  digitalWrite(any_output_pin_number,HIGH);
  delay(10);
  digitalWrite(any_output_pin_number,LOW);
}

Could I just do that??
Just right that in the loop??

Pady:
Could I just do that??
Just right that in the loop??

Yes. Use of the delay() function is frowned upon because it blocks operation of the program at that point until the delay() is over but if you can put up with a 10ms program pause then it will work. From the point of view of readability I would make the output to the pin a function and call it from loop().

if (voltage > value_of_your_choice)
{
  blip();
}

Then outside of the loop() function

void blip()
{
  digitalWrite(any_output_pin_number,HIGH);
  delay(10);
  digitalWrite(any_output_pin_number,LOW);
}

Implementing it as a function means that you can give it a meaningful name and isolates the code making debugging and alterations to the code easier in the long run.

When I think about it, this means that I would be spammed with alarm, I don't want that.

But if I do this:

if (voltage > 11.5)
void blip()
{
  digitalWrite(alarm,HIGH);
  delay(10);
  digitalWrite(alarm,LOW);
}

and then in the loop:

if (voltage > 11.5) // is it low battery?
{
if (lightIsOn=true); //is the light fully on?
  blip();    //Go for a ride and send a signal to the soundkit
}

It'll only run if the light is 100% on right?
I have no way of testing this right now, thats why i'm milking this...
But i'm thinking now, it should only run once every time the light is 100% and then stay quiet till the next time I turn on the lights.
Like a "Blink once" kind of thing...

?? blip every 10 sec ??
long bliptime;

if (voltage < value_of_your_choice && millis()>bliptime) // blip if [b]Low [/b]voltage
{
  blip();
  bliptime=millis()+10000;
}

But i'm thinking now, it should only run once every time the light is 100% and then stay quiet till the next time I turn on the lights.
Like a "Blink once" kind of thing...

So, when the light is 100% and you trigger the blip (feel free to change the name of the function by the way) set a boolean variable to true to indicate that the blip has been triggered boolean alreadyBlipped = trueand test the variable before calling blip() each time, including the first time. If it is currently true do not call blip(). When the light level falls below 100% change the state of the variable to false.

So, when the light is 100% and you trigger the blip (feel free to change the name of the function by the way) set a boolean variable to true to indicate that the blip has been triggered

I kin'a'like the name :slight_smile:

and test the variable before calling blip() each time, including the first time. If it is currently true do not call blip(). When the light level falls below 100% change the state of the variable to false.

How do I acctualy test for that?
Most of the code, I borrowed but I'm learning a ton of stuff from this :slight_smile:

if (voltage > 11.5)
{
  if (lightIsOn=true);
  blip();    //Go for a ride and send a signal to the soundkit
}
}
if (voltage > 11.5)
{
  if (lightIsOn == true && alreadyBlipped == false);
  blip();    //Go for a ride and send a signal to the soundkit
  alreadyBlipped = true;
}

Note the subtle but important change to your test for the value of lightIsOn which was wrong in your code.

Shouldn't this :

if (voltage > 11.5)

be changed to :

if (voltage < 11.5)

?? :wink:

Note the subtle but important change to your test for the value of lightIsOn which was wrong in your code.

I noted that, and have been looking into it in reference but don't really understand it the way they descripe it.
ONE = is setting something and TWO == is testing??
and the && is for??
I really want to understand this, so that one day I myself can explain it to others...

Shouldn't this :

Code:
if (voltage > 11.5)

be changed to :

Code:
if (voltage < 11.5)

?? smiley-wink

Don't know, should it?
I want the alarm UNDER 11.5 volts :slight_smile:

Also my void blip() looks like this:

void blip()
{
  digitalWrite(alarm,HIGH); //open the trigger pin
  delay(10);                //let it stay on a bit
  digitalWrite(alarm,LOW);  //close it again
  alreadyBlipped=true;      //remember that the alarm have been triggered
}

Should I skip the alreadyBlipped=true; state here?

your_variable = 5

Means : assign value of 5 to your_variable . After this, when you "read" a value of your_variable, you'll get 5 :

your_variable == 5

This means that your_variable equals 5 .

&& is logical AND . For egzample :

if ( your_variable == 5 && my_variable == 6 )
{
do_something
}

Do something ONLY when your_variable equals five AND my_variable equals 6 .

If you want alarm to of when voltage is lower than 11.5 , then you have to use :

if (voltage < 11.5)

That means : voltage lower than 11.5 . voltage > 11.5 means : voltage greater than 11.5 .

Ahh ok, think I understand a little better now :slight_smile:
I did some changes, also the if (voltage < 11.5)
Tomorrow I'll have anothe look at it but I think that we are close now :wink:
I have learned and still learning a lot off the tread/project, you guys are the best.

Here is the complete code:

/************************************************************
   Led dimmer using a logic lever MOSFET transitor
   Supply voltage is from 14.4v and down/ LED build for 12V, 
   But voltagedrop over Transistor and wires makes it ok.
   PIR-sensor power is fed from Arduino 5V / GND-pins. 
   PIR output to digital pin (D3) - polled
   PIR can be retriggable or non retriggable
   LED switches on when PIR detects movement
   LED output will stay 'ON' until 5 sec of 'PIR silence'
   LED (Mosfet gate) MUST be connected to PWM pin. (D11)
   this code can be drastically redused on volume - made for readability
****************************************************************/   
// declare global constants 
const byte led = 11;         // connect to gate
const byte pir =  3;         // PIR signal out 
const byte alarm = 7;        // The positive to the alarm trigger
const byte turnOnTime = 1;   // turn on/off time in seconds !(will be forced:  50 > time > 0)
const byte secondsToOff = 5; // seconds of 'silence' before "lights out" !! ALTER THIS VALUE
const boolean debug=false;

// declare global variables
boolean alreadyBlipped = true; //Have there been a "Low Voltage Alarm"?
boolean lightIsOn = false;   // remember LED-status 'now'
unsigned long timeToTurnOff; // time when led  will turn off
unsigned long timeNow;       // current time

//Setup for measuring voltage
// number of analog samples to take per reading
#define NUM_SAMPLES 10

int sum = 0;                    // sum of samples taken
unsigned char sample_count = 0; // current sample number
float voltage = 0.0;            // calculated voltage


// one time setup
void setup() 
{
  // set status og used I/O-pins
pinMode(led,OUTPUT);
pinMode(pir,INPUT);
pinMode(alarm,OUTPUT);
Serial.begin(9600);
}
//********************************
// small functions and procedures - to make reading of main prog easier
boolean heWantsLightsOn()
{
  return (digitalRead(pir)==HIGH);  
}
//********************************
void turnLightsOn(byte period)
{
  // now the LED shall increase light intensity over "turnOnTime" seconds
  long delayTime = period * 5 ;
  for (byte i=0; i<255; i++) 
  {
    analogWrite(led,i);
    delay(delayTime);
  }
  digitalWrite(led,HIGH); // no PWM needed - turn on 100%
  lightIsOn=true;         // remember status
  Serial.println("Light Is On"); //Tell me that the light is on
}
//**********************************
void turnLightsOff(byte period)
{
  // now the LED shall decrease light intensity - slowly to zero 
  long delayTime = period*5 ;
  for (byte i=254; i>0; i--) 
  {
    analogWrite(led,i);
    delay(delayTime);
  }
  digitalWrite(led,LOW); // no PWM needed - turn off
  lightIsOn=false;         // remember status
  Serial.println("Light Is Off"); //Tell me that the light is off
}
//**********************************
//This will take care of the trigger to the alarm.
void blip()
{
  digitalWrite(alarm,HIGH); //open the trigger pin
  delay(10);                //let it stay on a bit
  digitalWrite(alarm,LOW);  //close it again
  Serial.println("Low Voltage, Please Recharge"); //Tell me to recharge, but on-screen
  alreadyBlipped=true;      //remember that the alarm have been triggered
}
//******************************************
void loop() 
{
  timeNow=millis();  // note time now
  if (heWantsLightsOn()) // if movement -> be light! 
  {  
    if (!lightIsOn) turnLightsOn(turnOnTime);   // if still dark - be light! (else light were on already)
    // set 'new' time for off -since you just told 'stay on for some mor minutes..)
    timeToTurnOff=timeNow + secondsToOff * 1000;  // set 'off-time' some minutes into the future (milliseconds used)
    if (debug) Serial.println("renew for one minute");
  }
  // now test for "Elvis  has left the building"
  if (timeNow > timeToTurnOff) // is it time to turn off ??
  {
    if (lightIsOn) turnLightsOff(turnOnTime);  // if light still are on: turn them off
  }
  {
    // take a number of analog samples and add them up
    while (sample_count < NUM_SAMPLES) {
        sum += analogRead(A2);
        sample_count++;
        delay(20);  //Wait 20ms before reading voltage again
    }
    // calculate the voltage
    // use 5.0 for a 5.0V ADC reference voltage
    voltage = ((float)sum / (float)NUM_SAMPLES * 4.73) / 1024.0;
    // send voltage for display on Serial Monitor
    // voltage multiplied by 3 when using voltage divider that
    // divides by 3. 3 is the calibrated voltage divide
    // value
    Serial.print(voltage * 3);
    Serial.println (" V");
    sample_count = 0;
    sum = 0;
}
if (voltage < 11.5)
{
  if (lightIsOn == true && alreadyBlipped == false); //test if it's time to give the alarm
  blip();    //Go for a ride and send a signal to the soundkit
  alreadyBlipped = true; //Yes now the alarm has gone off!
}
}
//***************END***********************

I think that this is looking pretty good, or?

ok, It's friday and I ahve had a look at the code again, did none major change to it, but took away the first time i wrote "AlreadyBlipped"

I thank you so much for all the help and we can now call the topic [SOLVED]