Hey everyone! Thank you for advance if you are reading this and can maybe give some insight what is happening (or is not) with this project.
I am new to electronics and coding in general. Have been building this project almost a year now and learning step by step. Trying to keep genie smoke inside components.
This is also my first topic in here. Trying to use code tags correctly and be as informative as possible. I made bread board view drawing about wiring with Fritzing and later read that it is not recommended.
Hardware used:
Arduino uno wifi rev.2 (with latest WifiNINA 1.4.8 update) + screwshield for secure connections
Two Velleman VMA405 rfid-sensors: Two sensors share same 3.3V,RST-pin(RST_PIN 8), GND, MISO, MOSI and CLK. NSS are separate from both sensors. They go to D2 and D3 on arduino. (Board is based on MFRC522 chip) MISO, MOSI and CLK are soldered to arduinos ICSP pins. Other wires are connected with wire ferrules and screwterminals to arduino. All wires are soldered to rfid-sensors.
Two sensors are side by side because space limitations (Foreshadowing for trouble)
PC atx power supply: gives 12V to project. there are 5A fuses on the board. 12V is distributed separately to two DC-DC converters (LM2596S). First converter converts 12V to 9V and that powers Arduino and connected Rfid-sensors and Hall-sensor. Second converter converts 12V to 5V and that powers 2 channel relay module (HW-279) (there are optoisolation on input side and protection diodes)
12V magnetic lock: with protection diode (1N5408). Lock is driven trough relays normaly open. When lock is open arduinos A1 is driven HIGH.
Allegro A1324 Linear Hall-sensor: Sensor is driven with 5V and gives 2,5V (numerical 512) output when idle. There are 100nF ceramic capasitor smoothing the signal.
What should be happening:
When first and second puzzle pieces with embedded rfid-tags are bringed to sensors we check if they are right ones. It dont matter which sensor pick witch piece. We also want that puzzle state and opening the lock happens only when pieces are at the sensor.
This will open the magnetic lock
This will activate the hall-sensor and player can now put piece with embedded magnet to right place. We check if threshold is been low enough and enough time has passed so we can be sure that magnet is on the spot. This will end the puzzle and we send sendsolve() trough wifi to admin.
Code below:
</>[code]
// Puzzle logic:
// Both pieces with embeded RFID-tag have to be on the sensor, so the maglock can be opened
// After that Hall-sensor starts to give readings. Players have object with embeded magnet
// and place where they can put the object and when treshold and time is passed the puzzle will end
// solving the puzzle will send message via wifi to admin server
// admin server can solve and reset puzzle with commands via wifi
// Include the puzzleWifiConnect library and settings
#include "puzzleWifiConnect.h"
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN_1 2 // 1 rfid sensor slave select
#define SS_PIN_2 3 // 2 rfid sensor slave select
#define RST_PIN 8 // RST-pin for both mfrc522 sensors
MFRC522 mfrc522_1(SS_PIN_1, RST_PIN); // Create MFRC522_1 instance.
MFRC522 mfrc522_2(SS_PIN_2, RST_PIN); // Create MFRC522_2 instance.
// This pin will be driven LOW to release a lock.
const byte lockPin = A1;
//Puzzle steps states
int object_1 = 0;
int object_2 = 0;
//Hall sensor variables
const int numReadings = 10; // size of the readings array
int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
int Hall_1 = A0; // pin for Hall-sensor
bool object_3 = false; // state for final puzzle
//threshold time for hall-sensor read
unsigned long magnet = 0;
const long magnet_read = 100;
//pause between sensor readings object1
unsigned long previousMillis1 = 0;
const long wait1 = 2000;
//pause between sensor readings object2
unsigned long previousMillis2 = 0;
const long wait2 = 2000;
void setup() {
Serial.begin(9600); // Initiate a serial communication
Serial.println("Card reader setup");
SPI.begin(); // Initiate SPI bus
mfrc522_1.PCD_Init(); // Initiate MFRC522_1
mfrc522_2.PCD_Init(); // Initiate MFRC522_2
Serial.println("Card reader setup ready");
Serial.println();
// initialize all the hall-sensor readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
// setup wifi
Serial.println("Setup wifi");
puzzleWifiSetup();
Serial.println("Wifi setup ready");
Serial.println();
delay (10);
}
void loop() {
object1();
object2();
// if both objects are on reader, lets check the puzzle states
if (object_1 == 1 && object_2 == 1) {
Serial.println("objects at place. Release the magnet");
Serial.println();
// if so release the magnet
digitalWrite(lockPin, HIGH);
object3();
}
puzzleWifiLoop();
delay (10);
}
void object1() {
unsigned long currentMillis1 = millis();
if (currentMillis1 - previousMillis1 <= wait1) {
previousMillis1 = currentMillis1;
}
// Look for new cards
if ( ! mfrc522_1.PICC_IsNewCardPresent())
{
return;
}
// Select one of the cards
if ( ! mfrc522_1.PICC_ReadCardSerial())
{
Serial.println();
Serial.print("object_1 detected");
return;
}
//Show UID on serial monitor
Serial.print("UID tag :");
String content = "";
byte letter;
for (byte i = 0; i < mfrc522_1.uid.size; i++)
{
Serial.print(mfrc522_1.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522_1.uid.uidByte[i], HEX);
content.concat(String(mfrc522_1.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522_1.uid.uidByte[i], HEX));
}
Serial.println();
Serial.print("Message : ");
content.toUpperCase();
//change here the UID of the card/cards that you want to give access
if ((content.substring(1) == "E9 C7 75 99", "3A 9F 74 1A") && ( ! mfrc522_1.PICC_IsNewCardPresent()))
{
Serial.println("Authorized access");
Serial.println();
object_1 = 1;
if (object_1 = 1)
{
Serial.println("object1 solved");
Serial.println();
}
}
// Halt PICC
mfrc522_1.PICC_HaltA();
// Stop encryption on PCD
mfrc522_1.PCD_StopCrypto1();
delay(100);
}
void object2() {
unsigned long currentMillis2 = millis();
if (currentMillis2 - previousMillis2 <= wait2) {
previousMillis2 = currentMillis2;
}
// Look for new cards
if ( ! mfrc522_2.PICC_IsNewCardPresent())
{
return;
}
// Select one of the cards
if ( ! mfrc522_2.PICC_ReadCardSerial())
{
Serial.println();
Serial.print("object_2 detected");
return;
}
//Show UID on serial monitor
Serial.print("UID tag :");
String content = "";
byte letter;
for (byte i = 0; i < mfrc522_2.uid.size; i++)
{
Serial.print(mfrc522_2.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522_2.uid.uidByte[i], HEX);
content.concat(String(mfrc522_2.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522_2.uid.uidByte[i], HEX));
}
Serial.println();
Serial.print("Message : ");
content.toUpperCase();
//change here the UID of the card/cards that you want to give access
if ((content.substring(1) == "E9 C7 75 99", "3A 9F 74 1A") && ( ! mfrc522_2.PICC_IsNewCardPresent()))
{
Serial.print("Authorized access");
Serial.println();
object_2 = 1;
if (object_2 = 1)
{
Serial.print("object2 solved");
Serial.println();
}
}
// Halt PICC
mfrc522_2.PICC_HaltA();
// Stop encryption on PCD
mfrc522_2.PCD_StopCrypto1();
delay(100);
}
void object3() {
// subtract the last reading:
total = total - readings[readIndex];
// read from the sensor:
readings[readIndex] = analogRead(Hall_1);
// add the reading to the total:
total = total + readings[readIndex];
// advance to the next position in the array:
readIndex = readIndex + 1;
// if we're at the end of the array...
if (readIndex >= numReadings) {
// ...wrap around to the beginning:
readIndex = 0;
}
// calculate the average:
average = total / numReadings;
// send it to the computer as ASCII digits
Serial.println(average);
unsigned long magnet = millis();
while (millis() < magnet + magnet_read) {
if ((average <= 485) && object_3 == false) {
if (object_3 == false) {
object_3 = true;
solve();
// Moment when magnet is not present
if ((average > 485) && object_3 == true) {
object_3 = false;
}
}
}
}
// delay before next reading
delay(10);
}
/*************************************
Wifi communication functions below
*************************************/
/**
SOLVE
This is solve function. When you click puzzle solved in admin dashboard this function gets called.
*/
void solve() {
if (puzzleActive) {
// do here what you have to do to solve the puzzle
// Send status to admin
sendSolve();
} else {
Serial.println("Puzzle not active, cant solve it");
}
}
/**
RESET
This is reset function. When you click puzzle reset in admin dashboard this function gets called.
*/
void reset() {
if (puzzleActive) {
// do here what you have to do to reset the puzzle
// Set the lock pin as output and secure the lock
pinMode(lockPin, OUTPUT);
digitalWrite(lockPin, LOW);
// Reset puzzle states back to zero
object_1 = 0;
object_2 = 0;
object_3 = 0;
// Send status to admin
sendReset();
} else {
Serial.println("Puzzle not active, cant reset it");
}
}
/**
ACTIVATE
This is activate function. When you click puzzle activate in admin dashboard this function gets called.
*/
void activate() {
// do here what you have to do to activate the puzzle
// Send status to admin
sendActive();
}
/**
DEACTIVATE
This is deactivate function. When you click puzzle deactivate in admin dashboard this function gets called.
*/
void deactivate() {
// do here what you have to do to deactivate the puzzle
// Send status to admin
sendDeactive();
}
/**
This will check if wifi has received any control messages eg. solve, reset etc.
Call this in the loop.
*/
void checkIncomingCommands() {
if (hasReset) {
hasReset = false;
reset();
}
if (hasSolve) {
hasSolve = false;
solve();
}
if (hasActivate) {
hasActivate = false;
activate();
}
if (hasDeactivate) {
hasDeactivate = false;
deactivate();
}
}
[/code]</>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
What is happening:
Rfid readers freeze. They wont read tags and puzzle wont go forward.
I checked connections and continuity with multimeter. Those checks ok.
When i take other sensor away from vcc and gnd, other sensors starts to work and vice versa.
When first i started making the enclosure for sensors i didnt know possible interference what sensors can cause for eachother. Now it is obvious to me because i understand that sensors are antennas and receivers at same time.
Maybe the easiest way would be making the new enclosure with spacing at least 50cm or more between sensors, but that would be painstaking work to start all over again.
So i ask. Is it possible to use only one reader at the time and loop readers on at the time and save the states, so we can check are the conditions right to open the magnet. How this is done in code?
Would it be option to power up sensors separately for example with relay and do sensor looping that way?
Thank you for reading this far. I hope this information is enough and there are stuff what you can point me.
Best regards:
rei_kalev
![Puzzle|574x500](upload://m1nwTvnUv75bIiT87XHJkguhPri.jpeg)