"delay off" function

I am trying to create what is the "delay off" function in the timing relay world...or at least I think I am. Here is the idea:

a reed switch goes "LOW"
turns on electromagnet (far away from reed switch) to "lock" an object in position
after "X" time, electromagnet turns off and "unlocks" object allowing it to change the state of the reed switch back to "HIGH"
wait for reed switch to go "LOW"

Hardware is not an issue. That is my thing. I am using internal pull-up resistors, and a sainsmart relay board, which triggers relays with "LOW" signal.

I am looking at millis(), state change, and even interrupts...not sure. I am using an arduino nano.

I initially used the "delay()" function, as I did not care if the button state was ignored during the time that the electromagnet was on.

What I am struggling with is that after reed switch goes "LOW" and the electromagnet turns on, and then after "x" time turns off, the reed switch is still in a "low" state, thus keeping it in a neverending cycle.

How do I ignore the reed switch state, or force it to change to "HIGH" after the "X" time.

code attempt 1:

const int top = 8;
const int bottom = 7;

const int topmag =  12;
const int bottommag =  11;
const int topled =  10;
const int bottomled =  9;

const int timing = 2000;
const int wait = 500;

int topstate = 0;
int bottomstate = 0;

int pretopstate = 0;

void setup() {

  pinMode(topmag, OUTPUT);
  pinMode(bottommag, OUTPUT);
  pinMode(topled, OUTPUT);
  pinMode(bottomled, OUTPUT);

  pinMode(top, INPUT);
  pinMode(bottom, INPUT);

  digitalWrite(topmag, HIGH);
  digitalWrite(bottommag, HIGH);
  digitalWrite(topled, HIGH);
  digitalWrite(bottomled, HIGH);

  digitalWrite(top, HIGH);
  digitalWrite(bottom, HIGH);
}

void loop()
{
  topstate = digitalRead(top);
  bottomstate = digitalRead(bottom);


  if (topstate == LOW)
  {

    digitalWrite(topmag, LOW);
    delay(timing);
    topstate = pretopstate;
  }


  else
  {
    digitalWrite(topmag, HIGH);
  }
}

second try(not working...)

const int top = 8; //reed switch input


const int topmag =  12;// elctromagnet to "lock" cylendar in place
const int topled =  10;


//const int timing = 2000;//potential timing "on" variable for 2 electromagnets
//const int wait = 500;//if only 1 electromagnet is activated, wait this amount to wait for other reed switch to go "LOW"
int topstate = 0;//variable for the reed switch state
int pretopstate = 0;//variable for after reed switch is triggered

unsigned long toptime = 0;//variable for before reed switch is triggered for millis()

void setup() {

  pinMode(topmag, OUTPUT);

  pinMode(topled, OUTPUT);


  pinMode(top, INPUT);
  digitalWrite(topmag, HIGH);
  digitalWrite(topled, HIGH);


  digitalWrite(top, HIGH);

}

void loop()
{
  topstate = digitalRead(top);



  if (topstate == LOW)
    toptime == millis();
  {
    if (millis() - toptime < 2000)
    {
      digitalWrite(topmag, LOW);

      topstate = HIGH;

    }




    else
    {
      digitalWrite(topmag, HIGH);
    }
  }
}

if (topstate == LOW)
toptime == millis();
{
. . .
}

:wink:

== is not the same as =
Also check the placement of your { and }

Look these up in the reference section.

The state of the pin that the reed switch is connected to is controlled by the reed switch, not your code. You can't change the state of the reed switch.

   topstate = pretopstate;

What is this for? Typically, one sets the previous state to the current state, not the other way around. Not that it matters, since you never use the value in pretopstate.

 digitalWrite(top, HIGH);

Since top is an INPUT, you just turned the internal pullup resistor on. Is that what you wanted to do?

Have a look at this. Press the button and the LED stays on for a period.

const byte inputPin = A1;
const byte ledPin = 13;
unsigned long startTime;
unsigned long currentTime;
unsigned long period = 5000;  //adjust to change period
byte currentButtonState = HIGH;
byte previousButtonState = HIGH;
boolean timing = false;

void setup()
{
  Serial.begin(115200);
  pinMode(inputPin, INPUT_PULLUP);  //input will he HIGH when not pressed
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH); //turn off the LED
}

void loop()
{
  currentTime = millis();
  if (!timing)  //only react to input if not already timing
  {
    previousButtonState = currentButtonState;
    currentButtonState = digitalRead(inputPin);
    if (currentButtonState != previousButtonState & currentButtonState == LOW)  //button has become pressed
    {
      digitalWrite(ledPin, LOW);  //turn on the LED
      startTime = millis();
      timing = true;
    }
  }
  else if (currentTime - startTime >= period)
  {
    digitalWrite(ledPin, HIGH); //turn off the LED
    timing = false;
  }
}

The button is wired to take the input to GND when pressed. The LED is turned on by a LOW because of how it is wired

Adjust the logic to suit your system or change your system to match the code.