Help making arduino sent serial command when power is down

Hi I am trying to make a small battery charger that also can test battery voltage value.
When you send test command the arduino cut the power from the external power source and test the battery activating a load and measuring the voltage from the battery at the begin and end of the test.
The volt command send the current charger voltage.

that part is working fine, but I want the arduino to send a serial command when the external power supply is down, but I can't make it

This is my code I try to comment it as good as possible

Please help me

int memory = 0; //Set memory to 0
const int  Power_Pin = 3;  // Pin used to detect power failure or not
int PowerState = 0; //Current power suply status
int lastPowerState = 0;  //Last Power Supply state

void setup() {
  pinMode(A1, INPUT);   //Analog read of battery voltage
  pinMode(2,OUTPUT);  // Activate a relay with the test command
  pinMode(3,INPUT);  // Receive 5V from power source to detect Power Supply status
  Serial.begin(9600);
}

void loop() {
  
  
  if (PowerState != lastPowerState) {   //Detect changes in power supply
  PowerState = digitalRead(Power_Pin); //reads power pin
  if (PowerState == HIGH) {            // It will be HIGH if there is power supply
  Serial.println("Supply is back");   // Let you know when power is back
     } 
    else {
      Serial.println("No supply");  // Let you know that the power supply is off
   }
    delay(50);
      }
    lastPowerState = PowerState;  //Record current power supply status
    
  if (Serial.available() == 0) {}     //wait for data available
  String teststr = Serial.readString();  //read until timeout
  teststr.trim();                        // remove any \r \n whitespace at the end of the String
  if (teststr == "volt") {
    Serial.print("Corrent voltage is ") + Serial.print((analogRead(A1) * 0.0293255),1)+ Serial.println(" V");
  } 
  if (teststr == "test") {
       Serial.println("Starting 5s test"); 
     digitalWrite(2, HIGH);
     delay(1000);
     memory = analogRead(A1) * 0.0293255;
     delay(4000);
     Serial.print("Initial voltage is ") + Serial.print(memory,1)+ Serial.println(" V");
     Serial.print("Current voltage is ") + Serial.print((analogRead(A1) * 0.0293255),1)+ Serial.println(" V");
    delay(1000); 
    digitalWrite(2, LOW);
     }
  
    
}

may be you want to send the message when the external power supply goes down not when it is down

➜ see the state change detection example in the IDE

You will have to move PowerState = digitalRead(Power_Pin); before the first if. As it's now, if (PowerState != lastPowerState) will always evaluate to false as both variables are set to 0 so you will never get inside the the 'if` body.

Please note that an Arduino that does not have power can not send anything :wink: Curious how you keep it alive long enough to send the message.

the code doesn't read the input pin unless there's a change in state

i don't see where the Relay is turned on except after a "test". shouldn't it be turned on in setup()?

i wonder if you may want to measure/report the voltage when external power is restored

may damage input pin if external power is > 5V. could drive an external transistor (and base resistor) that pulls down the digital pin used to monitor for it. what about simply measuring the voltage to determine when external power is available?

some other minor simplifications that hopefully make the code easier to understand

// battery charger monitor

const byte  PinPower  = 3;  // Pin used to detect power failure or not
const byte  PinRelay  = 2;  // relay
const byte  PinAnalog = A1; // analog inpput

byte  pwrLst;

enum { RelayOn = LOW, RelayOff = HIGH };

// -----------------------------------------------------------------------------
float
readVoltage (void)
{
    return analogRead (A1) * 0.0293255;
}

// -----------------------------------------------------------------------------
void loop ()
{
    // monitor external power
    byte pwr = digitalRead (PinPower);
    if (pwrLst != pwr) {   //Detect changes in power supply
        pwrLst = pwr;

        if (pwr == HIGH)
            Serial.println ("Supply is back");
        else
            Serial.println ("No supply");
        delay (50);
    }

    if (Serial.available() == 0)
        return;         // no input to process


    String teststr = Serial.readString ();  //read until timeout
    teststr.trim ();    // remove \r, \n, whitespace from end of the String

    if (teststr == "volt") {
        Serial.print   ("Corrent voltage is ");
        Serial.print   (readVoltage());
        Serial.println (" V");
    }

    if (teststr == "test") {
        Serial.println ("Starting 5s test");
        digitalWrite (PinRelay, RelayOff);

        delay (1000);
        Serial.print   ("Initial voltage is ");
        Serial.print   (readVoltage());
        Serial.println (" V");

        delay (4000);
        Serial.print   ("Current voltage is ");
        Serial.print   (readVoltage());
        Serial.println (" V");

        digitalWrite (PinRelay, RelayOn);
    }
}

// -----------------------------------------------------------------------------
void setup () {
    pinMode (A1, INPUT);   // Analog read of battery voltage

    pinMode (PinPower, INPUT);   // sense external power

    pinMode (PinRelay, OUTPUT);
    digitalWrite (PinRelay, RelayOn);

    Serial.begin (9600);
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.