Coding Millis for first time

I am working on a project where I have a device which when it is tripped, you have 30 seconds to press a button, and if you don’t push it within that allotted time, it will continue the code and call my phone. A delay isn’t going to work because it holds up the loop for 30 seconds, so im thinking that I need to use Millis. I have never used Millis before and need some help getting it into my code.

Here is my code…

#include "Adafruit_FONA.h"

#define FONA_RX 2
#define FONA_TX 3
#define FONA_RST 4

#include <SoftwareSerial.h>
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

Adafruit_FONA fona = Adafruit_FONA(FONA_RST);


// constants won't change:
const int buttonPin = 7 ;     // button for auto emergency distress
const int ledPin =  12;      // LED for distress will be called
const int recordPin = 11;

unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 1000;  //the value is a number of milliseconds

// variables will change:
int buttonState = 0;         // start button HIGH
char gps_string[ 140 ];

void setup() {
  fonaSerial->begin(4800);
  fona.begin(*fonaSerial);
  fona.enableGPS(true);      //enable GPS function
  fona.getGPS( 0, gps_string, 140 );
  pinMode(ledPin, OUTPUT);  // initialize the LED pin as an output
  pinMode(buttonPin, INPUT); // initialize the pushbutton pin as an input
  pinMode(recordPin, OUTPUT);
  startMillis = millis();  //initial start time
}

void loop() {
  buttonState = digitalRead(buttonPin);
  fona.getGPS( 0, gps_string, 140 );
  
if (buttonState == LOW) {
    digitalWrite(ledPin, LOW);
    digitalWrite(recordPin, LOW);
    fona.hangUp();}
else { 
    digitalWrite(ledPin, HIGH);     //tripped
      delay( 5000);                 //person-response delay
    fona.sendSMS("7247147099", gps_string );
     delay(5000);
    fona.callPhone("7247147099");
      delay(10000);
    digitalWrite(recordPin, HIGH);
      delay(100);
    digitalWrite(recordPin, LOW);
      delay(15000);
  }
}

If you have any questions about that anything is in the code just feel free to ask. I code things by naming them what works best for me…so my apologies. Thanks in advance!

Learn how to work with millis(), starting with a much simpler task. Study this excellent tutorial on the Blink without Delay program.

What is going on in here:

    digitalWrite(ledPin, HIGH);     //tripped
      delay( 5000);                 //person-response delay
    fona.sendSMS("7247147099", gps_string );
     delay(5000);
    fona.callPhone("7247147099");
      delay(10000);
    digitalWrite(recordPin, HIGH);
      delay(100);
    digitalWrite(recordPin, LOW);
      delay(15000);

Clearly you're not just waiting 30-seconds and then calling the number (not your real number I hope, BTW...)

  • Is the timing and sequence of events here critical? After the trip, you wait 5-seconds: for what? "person-response delay"?
  • You then send the GPS SMS to the number and then wait another 5-seconds. Is that delay necessary before calling the number?
  • after calling the number, you have another 10-second delay: purpose?
  • what does record pin do? what is the purpose of pulsing it for 100mS?

Using something close to your logic, there’s this attempt (compiles, not tested):

#include "Adafruit_FONA.h"

#define FONA_RX 2
#define FONA_TX 3
#define FONA_RST 4

#define NOT_TRIPPED                 0
#define TRIPPED_WAIT_RESPOND        1
#define TRIPPED_CALL_PHONE          2
#define TRIPPED_PULSE_RECORD_HIGH   3
#define TRIPPED_PULSE_RECORD_LOW    4
#define TRIPPED_FORCE_DELAY         5
#define TRIPPED_WAIT_UNTRIPPED      6
#define TRIPPED_WAIT_RESPOND        7

#include <SoftwareSerial.h>
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

// constants won't change:
const int buttonPin = 7 ;     // button for auto emergency distress
const int ledPin =  12;      // LED for distress will be called
const int recordPin = 11;

// variables will change:
int buttonState = 0;         // start button HIGH
char gps_string[ 140 ];

byte
    lastButtonState;

void setup() 
{
    fonaSerial->begin(4800);
    fona.begin(*fonaSerial);
    fona.enableGPS(true);      //enable GPS function
    fona.getGPS( 0, gps_string, 140 );
  
    pinMode(ledPin, OUTPUT);  // initialize the LED pin as an output
    
    pinMode(buttonPin, INPUT); // initialize the pushbutton pin as an input
    lastButtonState = digitalRead( buttonPin );
    
    pinMode(recordPin, OUTPUT);
    
}//setup

bool ReadButton( bool *ButtonState )
{
    static unsigned long
        timeButton = 0;
    unsigned long
        timeNow;
    byte
        currButtonState;

    //only attempt to read the button every 50mS
    timeNow = millis();
    if( timeNow - timeButton < 50 )
        return false;
    timeButton = timeNow;
    
    currButtonState = digitalRead( buttonPin );
    if( currButtonState != lastButtonState )
    {
        lastButtonState = currButtonState;
        *ButtonState = (currButtonState == LOW )?false:true;

        return true;
        
    }
    else
        return false;
        
}//ReadButton

void loop() 
{
    static unsigned long
        timeTripped = 0;
    static byte
        stateTripped = NOT_TRIPPED;
    bool
        button;

    switch( stateTripped )
    {
        case    NOT_TRIPPED:
            //
            if( ReadButton( &button ) == true )
            {
                //button changed state; is it high indicating a trip?
                if( button == true )
                {
                    digitalWrite(ledPin, HIGH);     //indicate pending SMS/call
                    timeTripped = millis();                
                    stateTripped = TRIPPED_WAIT_RESPOND;
                    
                }//if
                
            }//if
            
        break;

        case    TRIPPED_WAIT_RESPOND:
            //wait for the button to show response or 30-seconds to pass
            if( millis() - timeTripped >= 30000ul )
            {
                //yes; start the SMS/call process
                fona.getGPS( 0, gps_string, 140 );
                fona.sendSMS( "7247147099", gps_string );
                timeTripped = millis();
                stateTripped = TRIPPED_CALL_PHONE;
                
            }//if
            else
            {            
                //check the button for response
                if( ReadButton( &button ) == true )
                {
                    //button changed state; is it low now indicating a clear/response?
                    if( button == false )
                    {
                        //yes; go back to NOT_TRIPPED state
                        digitalWrite(ledPin, LOW);
                        stateTripped = NOT_TRIPPED;                
                                
                    }//if
                    
                }//if
                
            }//else
            
        break;

        case    TRIPPED_CALL_PHONE:
            //5-seconds after SMS, call number
            if( millis() - timeTripped >= 5000ul )
            {
                fona.callPhone("7247147099");
                timeTripped = millis();
                stateTripped = TRIPPED_PULSE_RECORD_HIGH;
                                        
            }//if
            
        break;
        
        case    TRIPPED_PULSE_RECORD_HIGH:
            //10-seconds after call started, proceed to pulse the record pin for 100mS
            if( millis() - timeTripped >= 10000ul )
            {
                digitalWrite(recordPin, HIGH);
                timeTripped = millis();
                stateTripped = TRIPPED_PULSE_RECORD_LOW;
                                        
            }//if
            
        break;

        case    TRIPPED_PULSE_RECORD_LOW:
            //after 100mS set recordPin low
            if( millis() - timeTripped >= 100ul )
            {
                digitalWrite(recordPin, LOW);
                timeTripped = millis();
                stateTripped = TRIPPED_FORCE_DELAY;
                                        
            }//if
            
        break;

        case    TRIPPED_FORCE_DELAY:
            //force a 15-second delay (analogous to delay(15000) in original code)
            if( millis() - timeTripped >= 15000ul )
                stateTripped = TRIPPED_WAIT_UNTRIPPED;
            
        break;
        
        case    TRIPPED_WAIT_UNTRIPPED:
            //once the SMS/call/delay sequence has completed, wait for the button to show low before hanging up and
            //returning to the NOT_TRIPPED state
            if( ReadButton( &button ) == true )
            {
                if( button == false )
                {
                    digitalWrite(ledPin, LOW);
                    digitalWrite(recordPin, LOW);
                    fona.hangUp();
                    stateTripped = NOT_TRIPPED;                
                    
                }//if
    
            }//if
                    
        break;
    
    }//switch

}//loop

[Off topic] @OP, you're obviously a Smokey and the Bandit fan.... Dumbest. Movie. Ever :wink:

(Sally Fields was cute though.)
[/Off topic]

Josephm3502:
I am working on a project where I have a device which when it is tripped, you have 30 seconds to press a button, and if you don't push it within that allotted time, it will continue the code and call my phone.

I do that sort of thing with code like this pseudo code

if device is tripped and tripHappened == false
    timeDeviceTripped = millis()
    tripHappened = true

read button

if (buttonState == HIGH) {  // assumes LOW when pressed
   if (millis() - timeDeviceTripped >= 30 seconds) {
        // timeout has happened 
        // make the call
else {
    // button is pressed so do whatever

...R