Do I need to add a function?

Building a low voltage cutoff device.

Turns off once voltage is 10.9
Turns back on once voltage reaches 12.8

The kink I’m running into is if the arduino is powered on and the voltage is somewhere in the middle.

So if we power on the arduino and the voltage is 12.1, I want the mosfet pin set to HIGH.

Right now my voltage reading is all done in the void loop() section. Do I need to move that to it’s own function so I can call it one time when it boots from within void setup() ?

``````//Analog volt read pin
const int voltPin = 0;
// built in LED
const int ledPin =  LED_BUILTIN;// the number of the LED pin
const int mosfet = 6; //output from the LVD

// 500 millis delay in the loop. So let's adjust the timing of things
const int ChangeOverTime = 10; // figure out the multiple for the delay at bottom
int timetracker = 0; //keeping track of the number of half seconds

String lvdstatus = "OFF"; //keep track of the status of the system
int ledState = LOW; // ledState used to set the LED

// Set cut-in and cut-out
const float voltage_low = 10.9;
const float voltage_high = 12.8;

//Variables for voltage divider
float denominator;
int resistor1 = 47;
int resistor2 = 10;

void setup() {

// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
pinMode(mosfet, OUTPUT);
digitalWrite(mosfet, LOW);

Serial.begin(9600);
//Convert resistor values to division value
//  Equation is previously mentions voltage divider equation
//  R2 / (R1 + R2)
denominator = (float)resistor2 / (resistor1 + resistor2);

}

void loop() {

float voltage;
//Obtain RAW voltage data
//Convert to actual voltage (0 - 5 Vdc)
voltage = (voltage / 1024) * 5.0;
//Convert to voltage before divider
//  Divide by divider = multiply
//  Divide by 1/5 = multiply by 5
voltage = voltage / denominator;
//Output to serial
Serial.print("Volts: ");
Serial.println(voltage);
Serial.print("timetracker: ");
Serial.println(timetracker);
Serial.print("Status: ");
Serial.println(lvdstatus);
Serial.println();

// ---------- MANAGE THE OUTPUT ------------

if(lvdstatus == "ON" and voltage < voltage_low){
lvdstatus = "LOW";
timetracker = 0;
}

if(lvdstatus == "LOW"){
if(voltage < voltage_low){
timetracker++;
if(timetracker >= ChangeOverTime){
//we have had the necessary time, so we can change state to OFF
//turn off the output
lvdstatus = "OFF";
ledState = LOW;
digitalWrite(mosfet, LOW);
digitalWrite(ledPin, HIGH);
}
}else{
lvdstatus = "ON";
}
}

if(lvdstatus == "OFF" and voltage > voltage_high){
lvdstatus = "HIGH";
timetracker = 0;
}

if(lvdstatus == "HIGH"){
if(voltage > voltage_high){
timetracker++;
if(timetracker >= ChangeOverTime){
//we have had the necessary time, so we can change state to ON
//and turn on the output
lvdstatus = "ON";
ledState = HIGH;
digitalWrite(mosfet, HIGH);
digitalWrite(ledPin, HIGH);
}
}else{
lvdstatus = "OFF";
}
}

// ----------MAKE LED FLICKER FOR CHANGING STATE----------

//if we are heading toward change of state, then flicker the backlight
//either way - need to have a quarter second delay here for the benefit of screen readability
//and also as we need a long time before changeover.
if(lvdstatus == "LOW" or lvdstatus == "HIGH"){
digitalWrite(ledPin, LOW);
delay(125);
digitalWrite(ledPin, HIGH);
delay(125);
digitalWrite(ledPin, LOW);
delay(125);
digitalWrite(ledPin, HIGH);
delay(125);
}
else{
delay(500);
}

// Void loop close
}
``````
``````String lvdstatus = "OFF";
``````

80 bits of storage to store two bits of information?

Yes, you could use a function.

AWOL: ``` String lvdstatus = "OFF"; ```

80 bits of storage to store two bits of information?

Yes, you could use a function.

Roger that. I'll try.

Point me in a direction for your storage reference?

Any instance of the String class reserves six bytes of RAM, even before you've put string data in it, so a simple "OFF" consumes ten bytes of RAM. Because you have only "ON", " OFF", "HIGH" and "LOW", these can be represented by just two bits.

It’s better to forget that String (capital S) exists.

In this case you can e.g. use a byte variable (only 8 bits) and define some sensible names

``````#define LVD_OFF 0
#define LVD_ON 1
#define LVD_LOW 2
#define LVD_HIGH 3

char lvdstatus = LVD_OFF;

...
...

void setup()
{
...
...
}

void loop()
{
...
...

if (lvdstatus == LVD_ON and voltage < voltage_low)
{
lvdstatus = LVD_LOW;
timetracker = 0;
}

...
...
}
``````

You can not really get down to two bits although you can combine e.g. four 2-bit values in a byte; not useful in this scenario but possibly in future.

AWOL:
Any instance of the String class reserves six bytes of RAM, even before you’ve put string data in it, so a simple “OFF” consumes ten bytes of RAM.
Because you have only “ON”, " OFF", “HIGH” and “LOW”, these can be represented by just two bits.

So what do I use instead?

See reply #4 ? Note that I accidentally made it a char; does not matter for this.

Did I do this function correctly?

``````float ReadInTheVoltage(){
float voltage2;
//Obtain RAW voltage data
//Convert to actual voltage (0 - 5 Vdc)
voltage2 = (voltage2 / 1024) * 5.0;
//Convert to voltage before divider
//  Divide by divider = multiply
//  Divide by 1/5 = multiply by 5
voltage2 = voltage2 / denominator;

//Convert resistor values to division value
//  Equation is previously mentions voltage divider equation
//  R2 / (R1 + R2)
denominator = (float)resistor2 / (resistor1 + resistor2);

return voltage2;

}
``````

And that works, I can do a

``````Serial.print(ReadInTheVoltage());
``````

and it displays the desired output.

Is that the right way to do that?

`````` float voltage2;
//Obtain RAW voltage data
``````

analogRead does not return a float.

AWOL: ``` float voltage2;     //Obtain RAW voltage data   voltage2 = analogRead(voltPin); ```

analogRead does not return a float.

I stole the code from: http://playground.arduino.cc/Main/DirectMathVoltmeter

analogread should be "int" but we do some math to get the decimal, hence "float" - no?

Regardless of that, did I use and call the function correctly?

Then in void setup() I added

``````if battery is more than or the same as the low voltage - turn on
if (measuredVoltage >= voltage_low){
digitalWrite(mosfet, HIGH);
lvdstatus = "ON";
}
Serial.print("Setup loop voltage2: ");
Serial.println();
``````

But I get a compile error:

``````error: 'readInTheVoltage' was not declared in this scope
^
exit status 1
'readInTheVoltage' was not declared in this scope
``````

If I comment out everything but the serial.print stuff, it will compile and will display the voltage correctly. What am I missing here?

Full code

``````//Analog volt read pin
const int voltPin = 0;
// built in LED
const int ledPin =  LED_BUILTIN;// the number of the LED pin
const int mosfet = 6; //output from the LVD

// 500 millis delay in the loop. So let's adjust the timing of things
const int ChangeOverTime = 10; // figure out the multiple for the delay at bottom
int timetracker = 0; //keeping track of the number of half seconds

String lvdstatus = "OFF"; //keep track of the status of the system
int ledState = LOW; // ledState used to set the LED

// Set cut-in and cut-out
const float voltage_low = 10.9;
const float voltage_high = 12.1;

//Variables for voltage divider
float denominator;
int resistor1 = 47;
int resistor2 = 10;

//have a variable for storing the measured voltage
float measuredVoltage = 0.001;

void setup() {

// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
pinMode(mosfet, OUTPUT);
digitalWrite(mosfet, LOW);

Serial.begin(9600);

//Convert resistor values to division value
//  Equation is previously mentions voltage divider equation
//  R2 / (R1 + R2)
denominator = (float)resistor2 / (resistor1 + resistor2);

//if the voltage of the battery is more than or the same as the low voltage threshold then we need to turn on
//the mosfet output and set he lvdstatus to "ON".
//  if (measuredVoltage >= voltage_low){
//     digitalWrite(mosfet, HIGH);
//     lvdstatus = "ON";
//}
Serial.print("Setup loop voltage2: ");
Serial.println();

}

void loop() {

float voltage;
//Obtain RAW voltage data
//Convert to actual voltage (0 - 5 Vdc)
voltage = (voltage / 1024) * 5.0;
//Convert to voltage before divider
//  Divide by divider = multiply
//  Divide by 1/5 = multiply by 5
voltage = voltage / denominator;
//Output to serial
Serial.print("Volts: ");
Serial.println(voltage);
Serial.print("timetracker: ");
Serial.println(timetracker);
Serial.print("Status: ");
Serial.println(lvdstatus);
Serial.print("voltage2: ");
Serial.println();

// ---------- MANAGE THE OUTPUT ------------

if(lvdstatus == "ON" and voltage < voltage_low){
lvdstatus = "LOW";
timetracker = 0;
}

if(lvdstatus == "LOW"){
if(voltage < voltage_low){
timetracker++;
if(timetracker >= ChangeOverTime){
//we have had the necessary time, so we can change state to OFF
//turn off the output
lvdstatus = "OFF";
ledState = LOW;
digitalWrite(mosfet, LOW);
digitalWrite(ledPin, HIGH);
}
}else{
lvdstatus = "ON";
}
}

if(lvdstatus == "OFF" and voltage > voltage_high){
lvdstatus = "HIGH";
timetracker = 0;
}

if(lvdstatus == "HIGH"){
if(voltage > voltage_high){
timetracker++;
if(timetracker >= ChangeOverTime){
//we have had the necessary time, so we can change state to ON
//and turn on the output
lvdstatus = "ON";
ledState = HIGH;
digitalWrite(mosfet, HIGH);
digitalWrite(ledPin, HIGH);
}
}else{
lvdstatus = "OFF";
}
}

// ----------MAKE LED FLICKER FOR CHANGING STATE----------

//if we are heading toward change of state, then flicker the backlight
//either way - need to have a quarter second delay here for the benefit of screen readability
//and also as we need a long time before changeover.
if(lvdstatus == "LOW" or lvdstatus == "HIGH"){
digitalWrite(ledPin, LOW);
delay(125);
digitalWrite(ledPin, HIGH);
delay(125);
digitalWrite(ledPin, LOW);
delay(125);
digitalWrite(ledPin, HIGH);
delay(125);
}
else{
delay(500);
}

// Void loop close
}

float voltage2;
//Obtain RAW voltage data
//Convert to actual voltage (0 - 5 Vdc)
voltage2 = (voltage2 / 1024) * 5.0;
//Convert to voltage before divider
//  Divide by divider = multiply
//  Divide by 1/5 = multiply by 5
voltage2 = voltage2 / denominator;

//Convert resistor values to division value
//  Equation is previously mentions voltage divider equation
//  R2 / (R1 + R2)
denominator = (float)resistor2 / (resistor1 + resistor2);

return voltage2;
}
``````