************************************************************************** WARNING - NEVER RELY SOLELY ON COMPUTERS! ALWAYS HAVE AT LEAST 1 BACKUP. PLAY SAFE. *************************************************************************
**********************************USE THIS GUIDE AND CODE AT YOUR OWN RISK. UNDERSTAND THAT YOU ARE RELYING ON STRANGERS ON THE INTERNET, THERE ARE RISKS ASSOSIATED WITH THAT ACTIVITY.********************************
*******************************************************************************PARTS OF THIS PROJECT DEAL WITH MAINS VOLTAGE AND CARE MUST BE TAKEN*************************************************************************************
*********************************************************************DO NOT CHANGE OR MODIFY THE CODE. DOING SO MAY CAUSE THE PROGRAM TO ACT IN UNEXPECTED WAYS****************************************************************
**The information on this website is for general informational purposes only. Boundanna.com and the makers of this guide make no representation or warranty, express or implied. Your use of this guide is solely at your own risk.**
Arduino and Relay
This project uses the following materials;
- Arduino Uno
Relay board
USB cable type A to type B
Extention cord
Plastic Electrical/Project box
Electromagnet of your choice
Cut your extention cord in the middle on the line side. Strip just enough to get good contact. Don't cut the load side ( you can cut it different lenghts as long as neither part is too short to complete the following steps )
Take your box and cut a hole for the cord to enter when folded. The result will look like one cable going in and one coming out of the same hole. Tie a knot in the cable to prevent pulling on the electronics.
Insert the cut and striped ends into the normally open (NO) and common (C) ports on the same relay switch.
connect the positive and negative from your Arduino to the relay board and connect the control pin to the ledPin (#13 for uno)
cut a second hole for your USB cable to pass through.
Once you plug the USB cable into the ARDUINO close up the box.
Plug your electromagnet into the extention cord.
_________________________________________________________________________________________________________________________________________________________________________________________________________
CODE
You should now have an extention cord that is switched on and off by the relay. Time for some code. A HUGE shout out to Riddle for his time and programing knowledge.
Code: Select all
/*
This sets up an Arduino to work with the XToys.app to control an electromagnet
As modified by Riddle
*/
#include <ArduinoJson.h>
DynamicJsonDocument doc(96); // https://arduinojson.org/v6/assistant/
//==THIS IS THE TIME LIMIT FOR THE EMERGENCY RELEASE===========
const int hours = 0;
const int minutes = 15;
const int secondS = 0;
//==The variables for counting down the time========
int hrs, mins, secs;
/*
The following line determines if the output logic is inverted or not
if inverse is defined, a low will energize the relay and a high will deenergize
Comment out or delete the line if a high logic signal energizes your relay
*/
#define inverse
/*
The following line determins if the max time will reset or not.
Comment out or delete the line if you do not want a second max time event
*/
// #define maxTimeReset
// Code by Riddle from blink without delay
const int ledPin = LED_BUILTIN; // Change to match your relay pin
unsigned long startMillis;
unsigned long currentMillis;
const unsigned long maxTime = 975; // Max time of 1 second
// These variables implement the magLock and vibrate global variables
bool magLock = false, magLockFlag = false, mode = false, timeUp = false;
int vibrate = 0, oldVibrate = 0, vibrateFlag = 0;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
timeReset(); // See code starting with "timeReset() {"
}
void loop() {
checkVibrate(); // See code starting with "void checkVibrate() {"
checkMillis(); // See code starting with "void checkMillis() {"
changeMagLock(); // See code starting with "changeMagLock() {"
}
// This code gets the serial data
void checkVibrate() { // Declares the function
/*
This while loop checks to see if serial data is available
and gets the data if available.
*/
while (Serial.available() > 0) {
/*
This declares a string named "s" and
sets it equal to the result of the
read serial data function
*/
String s = Serial.readStringUntil('\n');
/*
This calls the funtion to interpret
the string data received in the previous step
This takes string s received in the previous
step and stores the data in the json doc
*/
deserializeJson(doc, s);
/*
This sets the variable "vibrate" to the value
stored in the document
*/
vibrate = doc["vibrate"];
}
if (vibrate == !oldVibrate) { // if vibrate changed...
oldVibrate = vibrate; // store the current state of vibrate
vibrateFlag = 1; // Flag that vibrate has changed
}
}
// This code checks to see if a second has elapsed
void checkMillis() { // Declares the function
if (vibrateFlag && vibrate) {
startMillis = millis();
mode = true;
timeUp = false;
#ifdef maxTimeReset
timeReset();
#endif
}
currentMillis = millis();
if (currentMillis - startMillis >= maxTime) {
startMillis = millis();
if (mode = true) {
secs--;
if (hrs <= 0 && mins <= 0 && secs <= 0) {
secs = 0; mins = 0; hrs = 0;
timeUp = true;
mode = false;
}
else if (secs < 0) {
if (mins > 0) {
mins --;
secs = 59;
}
else if (hrs > 0 && mins <= 0) {
hrs --;
mins = 59;
secs = 59;
}
}
}
}
}
// This is where the code for changing the MagLock exists
void changeMagLock() { // Declares the function
if (timeUp) {
magLock = false;
magLockFlag = true;
}
else if (vibrateFlag && vibrate) {
magLock = true;
magLockFlag = true;
vibrateFlag = false;
mode = true;
}
else if (vibrateFlag && !vibrate) {
magLock = false;
magLockFlag = true;
vibrateFlag = false;
}
else {
delay (10);
}
if (magLockFlag == true) {
magLockFlag = false;
#ifdef inverse
magLock = !magLock;
#endif
digitalWrite(ledPin, magLock);
}
}
// This resets the time remaining
void timeReset() { // Declares the function
hrs = hours;
mins = minutes;
secs = secondS;
}
This section of code is where you enter the MAX time you want the magnet energised. This serves as an additional backup should the person you met on the internet not be reliable. This does not, however, count as your emergency backup.
The timer starts when you connect the arduino to XToys and works independently of the switch.
//==THIS IS THE TIME LIMIT FOR THE EMERGENCY SHUT OFF===========
const int hours = 0;
const int minutes = 15;
const int secondS = 0;
The code is currently set for 15 minutes. Upload the code to the arduino.
______________________________________________________________________________________________________________________________________________________________________________________________________________
XToys.app Setup
Go to XToys.app
Make an account.
Click on the 3 lines in the top left corner of the window to show the menu.
select "Custom Toys"
click on the + in the bottom right corner of the screen and select "Crteate a New Serial Toy"
Give your toy a name.
under type select 1 channel vibrator
under number of steps enter 1
click SAVE
On the main screen of XToys click on the + in the top right corner of the window.
Add your custom toy. connect and test your toy before use.
_______________________________________________________________________________________________________________________________________________________________________________________________________
Inversed Code
There are many different suppliers of relay boards available and they do not all work exactly the same way.
If after testing your arduino with the code above you find that your magnet does the opposite of what you want ( on when you want it off and off when you want it on ) Please test the following code to see if you get your desired results.
Note that the method of setting a max time does not change.
Code: Select all
/*
This sets up an Arduino to work with the XToys.app to control an electromagnet
As modified by Riddle
*/
#include <ArduinoJson.h>
DynamicJsonDocument doc(96); // https://arduinojson.org/v6/assistant/
//==THIS IS THE TIME LIMIT FOR THE EMERGENCY RELEASE===========
const int hours = 0;
const int minutes = 15;
const int secondS = 0;
//==The variables for counting down the time========
int hrs, mins, secs;
/*
The following line determines if the output logic is inverted or not
if inverse is defined, a low will energize the relay and a high will deenergize
Comment out or delete the line if a high logic signal energizes your relay
*/
// #define inverse
/*
The following line determins if the max time will reset or not.
Comment out or delete the line if you do not want a second max time event
*/
// #define maxTimeReset
// Code by Riddle from blink without delay
const int ledPin = LED_BUILTIN; // Change to match your relay pin
unsigned long startMillis;
unsigned long currentMillis;
const unsigned long maxTime = 975; // Max time of 1 second
// These variables implement the magLock and vibrate global variables
bool magLock = false, magLockFlag = false, mode = false, timeUp = false;
int vibrate = 0, oldVibrate = 0, vibrateFlag = 0;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
timeReset(); // See code starting with "timeReset() {"
}
void loop() {
checkVibrate(); // See code starting with "void checkVibrate() {"
checkMillis(); // See code starting with "void checkMillis() {"
changeMagLock(); // See code starting with "changeMagLock() {"
}
// This code gets the serial data
void checkVibrate() { // Declares the function
/*
This while loop checks to see if serial data is available
and gets the data if available.
*/
while (Serial.available() > 0) {
/*
This declares a string named "s" and
sets it equal to the result of the
read serial data function
*/
String s = Serial.readStringUntil('\n');
/*
This calls the funtion to interpret
the string data received in the previous step
This takes string s received in the previous
step and stores the data in the json doc
*/
deserializeJson(doc, s);
/*
This sets the variable "vibrate" to the value
stored in the document
*/
vibrate = doc["vibrate"];
}
if (vibrate == !oldVibrate) { // if vibrate changed...
oldVibrate = vibrate; // store the current state of vibrate
vibrateFlag = 1; // Flag that vibrate has changed
}
}
// This code checks to see if a second has elapsed
void checkMillis() { // Declares the function
if (vibrateFlag && vibrate) {
startMillis = millis();
mode = true;
timeUp = false;
#ifdef maxTimeReset
timeReset();
#endif
}
currentMillis = millis();
if (currentMillis - startMillis >= maxTime) {
startMillis = millis();
if (mode = true) {
secs--;
if (hrs <= 0 && mins <= 0 && secs <= 0) {
secs = 0; mins = 0; hrs = 0;
timeUp = true;
mode = false;
}
else if (secs < 0) {
if (mins > 0) {
mins --;
secs = 59;
}
else if (hrs > 0 && mins <= 0) {
hrs --;
mins = 59;
secs = 59;
}
}
}
}
}
// This is where the code for changing the MagLock exists
void changeMagLock() { // Declares the function
if (timeUp) {
magLock = false;
magLockFlag = true;
}
else if (vibrateFlag && vibrate) {
magLock = true;
magLockFlag = true;
vibrateFlag = false;
mode = true;
}
else if (vibrateFlag && !vibrate) {
magLock = false;
magLockFlag = true;
vibrateFlag = false;
}
else {
delay (10);
}
if (magLockFlag == true) {
magLockFlag = false;
#ifdef inverse
magLock = !magLock;
#endif
digitalWrite(ledPin, magLock);
}
}
// This resets the time remaining
void timeReset() { // Declares the function
hrs = hours;
mins = minutes;
secs = secondS;
}