I use an electromagnet controlled by an Arduino to "tie the last hand". However, it's a bit clumsy to just add a delay between the time the Arduino is powered on and the time everything is done and I can drop the plate on the magnet before starting, ahem, other things. So I figured out a simple way to detect the latching of the plate on the magnet, at which point the countdown timer really starts.
Turns out there is a sharp drop in the current consumed by the electromagnet when the plate latches. See image below. So I used a resistor as a shunt on the low side (since the high side is 12v and Arduinos can only read up to 5V) to measure the associated voltage drop. All I had were 1/4 watts and my smallest one was 2.2ohms. The magnet uses about 350mA, so that would have meant just above 1/4 watts. Not wanting to risk anything catching on fire, I went with two 2.2ohms in parallel, effectively making the equivalent resistance 1.1ohms. This halved the dissipated power with the added benefit that the dissipation would occur in 2 resistors instead of one. One can expect a normal voltage of ~0.4v accross the shunt. That kind of voltage drop is not a problem for the magnet, but a little low for a good resolution on the Arduino side. Since I had no other analog input in use, I just modified the analog voltage reference in software (INTERNAL makes it 2.56v on an Uno). Good enough.
Schematics: Code
The code is pretty simple. It just starts the magnet as soon as the Arduino powers on, and starts a countdown timer when the latch is detected. To be on the safe side, there is also a timer that powers down the magnet if no latch has been detected in a certain time, in case the detection didn't work (otherwise the countdown would never start and thus never release you!)
Here is the code:
Code: Select all
#define magnetPin 4
#define sensorPin A0
#define duration 60000 // 1 minute
#define latchWait 60000 // 1 minute.
unsigned long start;
void setup() {
Serial.begin(9600);
digitalWrite(magnetPin, HIGH);
printTime();
Serial.println("Magnet powered. Stabilizing reading.");
analogReference(INTERNAL);
delay(5000); // arbitrary
printTime();
Serial.println("Sensing...");
waitForLock();
printTime();
Serial.println("Magnet plate latched. Beginning session.");
start = millis();
}
void loop() {
// do something devious here
if (millis() - start > duration) {
// we're done here
digitalWrite(magnetPin, LOW);
printTime();
Serial.println("We're done here. Magnet powered off.");
while (true) {}; // grinds everything to a halt
}
}
void waitForLock() {
int initCurrent = analogRead(A0);
int current;
unsigned int start = millis();
do {
current = analogRead(A0);
if (millis() - start > latchWait) {
printTime();
Serial.println("That took too long. Powering off magnet...");
digitalWrite(magnetPin, LOW);
while (true) {};
}
} while (current > 0.75 * initCurrent);
}
void printTime() {
Serial.print(millis() / 1000);
Serial.print("s: ");
}
Successful latch detection: Unsuccessful latch detection: Safety
- Resistors fail open, so fried resistors = free
- Code detects if no latch occured, setting you free
- I use 4xLiFePO4 18650 batteries to power everything. Safer than normal lithium, 4 of them also closely match a normal 12V source. This is backup #1 (they should last a bit more than an hour at 1500mAh each)
- Key in ice. This is backup #2
I have learned a lot by lurking on this site before posting. I hope this helps someone!
Cheers