voltage reading help

hi all i am trying to write code for my second project. i found this code online and modified to suite me. it was written to change over to generator during a blackout and was written for ac voltage.

i am trying to get a 12v generator to start when a voltage set point is reached.

all seams fine apart from i am getting a voltage reading of 0v on the serial monitor.

and as it sees 0v, it wants to start the engine even though there is a good 12.6v.

could someone please tell me where i have gone wrong.

many thanks

#include "DS3231.h" //github.com/NorthernWidget/DS3231
#include <Wire.h> //used with ds3231.h for the i2c

const int VOLTS = A0;
//int SDA = A4; //This is not needed but makes it human readable to know the SDA i2c channel is A4
//int SCL = A5; //This is not needed but makes it human readable to know the SCL i2c channel is A5
int GEN = 3; //generator RPM pin
int IGN = 6; //Ignition Pin
int SW = 7; //Starter Pin
int PUSHBUTTON = 8; //Button Pin
int StopLed = 10; //Safe to stop generator LED
int IgnLed = 11; //Ignition on LED
int StartLed = 12; //Starter on LED
int GenLed = 13; //Generator run LED
uint32_t Start_Time = 10000; //10 seconds to allow starter to run per attempt
uint32_t Wait_Time = 30000; //30 seconds to wait between start attempts to allow starter to cool
const unsigned long sampleTime = 1000;
int long Gen_Shutdown_Time = 0;
int long Gen_Test_Time = 0;
int long Now_Test_Time = 0;
int long Now_Stop_Time = 0;
int long Stop_Time = 0;
int Current_Time = 0;
int Time_Left = 0;
int ButtonTimeLeft = 0;
int IGN_Attempt = 0;
int GasState = 0;
int SwState = 0;
int IgnState = 0;
int GenRpm = 0;
int GenState = 0;
int ButtonState = 0;
int StopState = 0;
int TestState = 0;
int Volts = 0;
int readIndex = 0;
int total = 0;
int average = 0;
int AutoState = LOW; //this is to indicate if generator manual started or automated.
const int numReadings = 5; //Number of times to read battery volts to create the average and add to array
int readings[numReadings]; //readings array to handle volt average
DateTime now;

void setup() {
  Serial.begin(115200); //enable serial connection for debug. Switch any oled.print to serial.print to send to serial
  digitalWrite(IGN,HIGH); //Starter off
  digitalWrite(SW,HIGH); //Ignition off
  digitalWrite(GenLed,LOW); //LED off
  digitalWrite(StopLed,LOW); //LED off
  digitalWrite(IgnLed,LOW); //LED off
  digitalWrite(StartLed,LOW); //LED off

void gen_status() { //generator loop to look at current generator state
  GenRpm = getRPM();
  if(GenRpm>=500) { //Check the RPMs of the generator and 500 or higher is running
    digitalWrite(GenLed,HIGH); //turn on LED if generator is running
    GenState = HIGH; //Set Gen state to high indicating generator is running
  else {
    digitalWrite(GenLed,LOW); //turn off LED if generator is not running
    GenState = LOW; //Set GenState to low indicating generator is not running

void volts() { //check on voltage to see battery is low
  float Vrms = (Vrms - 3);
  total = total - readings[readIndex]; //subtract the last reading
  readings[readIndex] = Vrms; //input the Vrms value
  total = total + readings[readIndex]; //add the resding to the total
  readIndex = readIndex + 1; //advance to the next position in the array
  if (readIndex >= numReadings) { //if we ae at the end of the array wrap around to the begining
    readIndex = 0;
  average = total / numReadings; //calculate the average
  if (average < 6.25) { Vrms = 0.0; } 
  Volts = average * 2; //Double Vrms to get actual voltage

void button() {
  DateTime now = RTC.now();
  if(GenState==1 && Volts<=11.5 && StopState==0) { //Press the button to indicate confirmation of manual switchover
    if(ButtonState==HIGH) { //Button pushed to indicate transfer began
    else {
      Serial.println("Hold button");
  if(GenState==1 && Volts>=14 && StopState==1) { //If generator stop LED is off we can initiate shutdown
    if(ButtonState==HIGH) { //Button pushed to start shutdown
      Now_Stop_Time = now.unixtime();
      Stop_Time = Now_Stop_Time + 300L; //Set stop time now.unixtime + 5 minutes
      Serial.println("Allow shutdown");
    else {
      Serial.println("Hold button");

void genstart() { //Generator start sequence
  if(IGN_Attempt<3 && GenState==LOW) { //Try this for 3 attempts with Generator at low and less than as starts with attempt 0
    IGN_Attempt++; //add one count to start attempts
    Serial.println(" of 3 attempts");
    Serial.println("Gen not running");
    delay(5000); //wait 5 seconds for gas to start flow
    delay(200); //wait 200ms to let choke get to set
    Serial.println("Ignition on");
    digitalWrite(IGN,LOW); //Ignition On
    digitalWrite(IgnLed,HIGH); //Ignition LED on
    delay(2000); //wait 2 second before starter attempt
    Serial.println("Starter on");
    for( uint32_t timer = millis(); (millis()-timer) < Start_Time; ) { //start a timer in milliseconds called timer and compare to time set against Start_Time
      digitalWrite(SW,LOW); //Starter On
      digitalWrite(StartLed,HIGH); //Starter LED on
      if(GenState==HIGH) { //generator running
        Serial.println("Starter off");
        digitalWrite(SW,HIGH); //Starter off
        digitalWrite(StartLed,LOW); //Starter LED off
        Serial.println("Generator running");
        AutoState = 1;
    Serial.println("Starter off");
    digitalWrite(SW,HIGH); //Starter Off
    digitalWrite(StartLed,LOW); //Starter LED off
    //if Start loop complete and genrator not running wait 30 sec before next attempt but if 3rd attempt no reason to delay since wont try start attempt again
    if(GenState==LOW && Volts<=11.5 && IGN_Attempt < 3) {
      Serial.println("Tried for 10 seconds");
      Serial.println("Failed to start");
      Serial.println("Wait 30 seconds");
      for( uint32_t timer2 = millis(); (millis()-timer2) < Wait_Time; ) {
  else {
    if(GenState==HIGH) { //change to RPM to indicate generator running
      Serial.println("Generator running");
    else { //Generator did not start so shutdown everything
      Serial.println("Failed to start!");
      Serial.println("Please check");

void genshutdown() { //Generator shutdown sequence
  digitalWrite(IgnLed,LOW); //Ignition LED off

void testrun() {
  DateTime now = RTC.now();
  if(now.day()==15 && now.hour()==12 && now.minute()==00 && TestState==LOW && GenState==LOW) { //Test the generator by starting at specified time and date
    Serial.println("Running test");
    TestState = HIGH; //set the Test State to High
    Now_Test_Time = now.unixtime(); //set the variable for now unix time in long format
    Gen_Test_Time = Now_Test_Time + 1800L; //Set test to run 30 minutes which is 1800 seconds

int getRPM() {
  int count = 0;
  boolean countFlag = LOW;
  unsigned long currentTime = 0;
  unsigned long startTime = millis();
  while (currentTime <= sampleTime)
    if (digitalRead(GEN) == HIGH) {
      countFlag = HIGH;
    if (digitalRead(GEN) == LOW && countFlag == HIGH) {
    currentTime = millis() - startTime; 
  int countRpm = int(60000/float(sampleTime))*count;
  return countRpm;

void loop() {
  DateTime now = RTC.now();
  volts(); //get ac pole voltage info
  gen_status(); //get generator run status
  button(); //check button
  GenRpm = getRPM(); //check RPM on generator
  SwState = digitalRead(SW); //current SW relay state
  IgnState = digitalRead(IGN); //current IGN relay state
  ButtonState = digitalRead(PUSHBUTTON); //current button state
  StopState = digitalRead(StopLed); //current state of the system safety LED
  testrun(); //check to see if we should run the monthly test run
  if(Volts<=11.5) { //This indicates the AC voltage sensor on pole side of power has been lost or brown out and 10 helps with initial start
  else { //if AC power from the pole is available
    if (VOLTS>=14)
    Serial.print("Good ");
    Serial.print(now.month(), DEC);
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(now.minute(), DEC);
    Serial.println(now.second(), DEC);
    if(GenState==HIGH && AutoState==HIGH) { //if generator is running in an auto fashion
      if(TestState == HIGH) { //check if running generator test
        if(Gen_Test_Time <= now.unixtime()) { //use generator test time to decide if we shutdown
          TestState = LOW;
          AutoState = LOW;
        else {
          Serial.print("Run test for ");
          Serial.print(Gen_Test_Time - now.unixtime());
          Serial.println(" s");
      if(TestState == LOW) { //not running generator test
        if(Stop_Time <= now.unixtime() && StopState==LOW) { //5 minute count down for cool down before begin shutdown and Red LED is off
          AutoState = LOW;
        else {
          Gen_Shutdown_Time = Stop_Time - now.unixtime();
          Serial.print("Shutdown in ");
          Serial.println(" s");
    if(GenState==HIGH && AutoState==LOW) {
      Serial.println("Generator manual run");
    IGN_Attempt=0; //reset ignition attempts

Where, in the code, is the voltage being read?

please forgive me for my ignorance i only have limited experiance with coding. im yet to write anything of my own from scratch.

voltage input is on A0

there is a "void" section for voltage

but i think this section has been written for ac and not dc with a voltage divider

so iv now got it reading/showing a voltage and its responding as it all should EXCEPT its only showing as whole numbers i would like it to read to at least 1 decimal place.

any ideas how i do that please


Post the new version of the code.

The volts variable is declared as an int data type. Doing calculations on ints (whole numbers) will not give decimal places. If you want decimals do the calculation with float data type and use print(float number, 1) to print with 1 decimal place.

ok this is the section that i added that gave me the voltage reading.

void loop() {
  //Conversion formula for voltage
   int analog_value = analogRead(A2);
   Volts= (analog_value / 1023.00) * 14.50;

yes the 14.5 is high, i made do with a divider made of what bits i had around the workshop. i will be ordering a ready made divider tomorrow.

i am getting 12v shown. but i know the battery is at 12.39v

Change the declaration of the volts variable from int to float to print decimals.