I’m trying to activate a relay from a reed switch have it activate for a few seconds and then deactivate it. I was able to build it with momentary button but then I realized a reed switch would still be closed and not deactivate the relay. Sorry, I’m very new to Arduino but I love learning.
you might benefit from studying state machines. Here is a small introduction to the topic: Yet another Finite State Machine introduction
You have 2 states : IDLE and ACTIVE
state IDLE
if the reed switch activates, note the time, activate the relay and change state to ACTIVE
state ACTIVE
if the reed switch deactivates, deactivate the relay and change state to IDLE
else
if the duration (current time minus the time you noted) exceeds some threshold, deactivate the relay and change state to IDLE
You can easily add a timer, but at the end the reed switch is still closed unless there is something you are not telling us.
Be more precise in your description and you will get a better answer.
Alternatively, you can get reed switches which are normally open like a push button switch (or change over SPDT reed switches which can be so wired). Example https://www.mouser.ch/datasheet/2/240/media-3320693.pdf
Ypu can detect the actions of the reed switch to trigger code that will "do_something" not dependent on what the reed switch is doing except for a particular change that your reed-switch-watcher code looks for.
You can have a function run in a non-blocked void loop() that uses real to do abstract, makes the leap you need even as it keeps track of the switch to work as often as needed.
Better to outline your project instead of offering suggestions to whatever it is you are trying to achieve.
However there are simple solutions to get a pulse from a toggle switch.
https://electronics.stackexchange.com/questions/236374/creating-a-momentary-low-pulse-with-a-toggle-switch
look this over
const byte PinSw = A1;
const byte PinLed = LED_BUILTIN; // 13
const unsigned long MsecPeriod = 2000; // a few seconds
unsigned long msecLst;
enum { Off = HIGH, On = LOW };
// -----------------------------------------------------------------------------
void
loop (void)
{
unsigned long msec = millis ();
if (msecLst && msec - msecLst >= MsecPeriod) {
digitalWrite (PinLed, Off);
msecLst = 0;
}
if (LOW == digitalRead (PinSw)) {
Serial.println (" but press");
if (0 == msecLst) {
msecLst = 0 != msec ? msec : 1; // never zero
digitalWrite (PinLed, On);
}
}
}
void
setup (void)
{
Serial.begin (9600);
pinMode (PinSw, INPUT_PULLUP);
pinMode (PinLed, OUTPUT);
digitalWrite (PinLed, Off);
}
this description is not precise enough to get a clear picture of what kind of functionality you want to have.
So one thing to learn is to give a precise description.
One method would be to hand-draw a timing-diagram where the important details and example-numbers are written into the timing-diagram and posting a pciture of this timing-diagram
Here is a WokSim which shows a so called Mono-Flop.
The code waits for a signal and if signal is detected switch an Output IO-pin
regardless of how long the input-signal is still on or off keep the output-IO-pin switched on until ON-time is over.
After that ignore a new signal for some time.
Then go back into "wait for an input-signal"
Here is another WokSim which does the same with a push-button
i thought the issue is that the timer should start when the switch it first activated, not constantly restarted while it remains active.
does the switch need to be ignored until it is cleanly (i.e. debounced) released?
https://www.talkingelectronics.com/te_interactive_index.html
Go here, open the 555 timer circuits book, and run down the list of 555 timer circuits to
" Active High Trigger". (a bit over 1/2 way down the page of circuits)
What are you trying to accomplish then? In other words perhaps?
There's a reed switch and a led, and some action where the switch detects a magnetic field and a led turns on for a while then turns off even if the switch is closed, and no one but you has a clue as to why or what else is going on yet you even got code...
does this show have more plot twists?
What you are asking for can be done, but once the part of the circuit that times out and turns the LED off runs, there is no further action. This does not sound useful. You need to tell us how you plan to deactivate the reed switch, and how long that might take even if it approaches infinity.
Think of it this way, if you take the circuit you built with the momentary button and replace it with a toggle switch, what happens after you toggle the switch or is this circuit designed to only work once in it's entire life. If so, an Arduino or any other MCU/MPU is not needed.
i believe he wants the circuit/relay to be active each time the switch triggers it. it can be re-triggered after the switch releases and after the relay times out
He never mentions removing the magnet from the reed switch. Therefore this is a one time circuit.
the condition for stopping the motor is when the sensor becomes active, not while it is active.
this is common when recognizing button presses and performing some activity, not to continue to perform that activity while the button is pressed.
const byte PinSw = A1;
const byte PinLed = LED_BUILTIN; // 13
const unsigned long MsecPeriod = 2000; // a few seconds
enum { Off = HIGH, On = LOW };
unsigned long msecLst;
byte swState;
// -----------------------------------------------------------------------------
void
relayOnOff (
int on )
{
digitalWrite (PinLed, on);
if (On == on)
Serial.println (" relay on");
else
Serial.println (" relay off");
}
// -----------------------------------------------------------------------------
void
loop (void)
{
unsigned long msec = millis ();
if (msecLst && msec - msecLst >= MsecPeriod) {
msecLst = 0; // reset
relayOnOff (On);
}
byte sw = digitalRead (PinSw);
if (swState != sw) { // state change
swState = sw;
delay (20); // debounce (for mech sw)
if (LOW == sw && 0 == msecLst) { // sw becomes active
msecLst = 0 != msec ? msec : 1; // never zero
relayOnOff (Off);
}
}
}
void
setup (void)
{
Serial.begin (9600);
pinMode (PinSw, INPUT_PULLUP);
swState = digitalRead (PinSw);
pinMode (PinLed, OUTPUT);
relayOnOff (On);
}
Ok, no problem, after the timer runs, then re-start the motor so that the magnet moves away. You will need a tiny delay to allow the switch to open.
why?
there's a difference between being on and changing state from off-to-on.
You have to allow the switch to open so you can then detect it closing.
That's kinda built into the hole "state change detection" pattern.
Here's @gcjr's loop() with the section that would be detecting the other edge (or in this case that signals having waited for the switch to open) made obvious:
void loop ()
{
unsigned long msec = millis ();
if (msecLst && msec - msecLst >= MsecPeriod) {
msecLst = 0; // reset
relayOnOff (On);
}
byte sw = digitalRead (PinSw);
if (swState != sw) { // state change
swState = sw;
delay (20); // debounce (for mech sw)
if (LOW == sw && 0 == msecLst) { // sw becomes active
Serial.println("Here's the switch getting pressed.");
msecLst = 0 != msec ? msec : 1; // never zero
relayOnOff (Off);
}
if (HIGH == sw) { // sw becomes unactive
Serial.println("Here's the switch getting released.");
}
}
}
HTH
a7
Perhaps you mean relay since the reed switch will open when the magnetic field is removed, it is a detector not a thrown switch.
I think that the assumption is that when the led times out and turns off that the relay Not Coded For Yet gets reversed too.
Stay tuned to find out in further posts!