Author Topic: RFID moteino controled access system [FINISHED]  (Read 62778 times)

luisr320

  • Sr. Member
  • ****
  • Posts: 255
  • Country: pt
RFID moteino controled access system [FINISHED]
« on: May 29, 2014, 08:54:29 PM »
Hello fellow moteiners.

I'm loosing a lot of hair trying to figure this one out and I ask for help.

I'm assembling a RFID entrance control device that will send a RFID tag id via radio to a radio gateway to be forward to my home automation system via com port. The system must check if the tag is allowed in the house and returns a radio signal back to the RFID radio node to open the gate.

The RFID is a seedstudio 125Khz in UART mode connected to a moteino via TX/RX ports.

This hardware communication setup is functioning well and if I approach the tag to the RFID antena, the moteino sends a text packet to the gateway with "12345678" in it, that is the tag id, and my home automation system can deal with it for whatever purpose I want.

The problem is that I can't figure out how to make the RFID moteino send the content of the tag.id variable to the receiver. And unless I figure out how to do this, I have to setup all the cleared tags directly on the RFID arduino sketch. And since I use the TX/RX pins to communicate with the seedstudio RFID brick, I have to disconnect the RX pin every time I want to update the cleared tags numbers.

This is the code that sends the tag id:
Code: [Select]
void loop() 
{
if(RFID.isIdAvailable())
{
tag = RFID.readId();

Serial.print("ID:");
Serial.println(tag.id);
if (tag.id == 12358867)
{
Serial.print("ID (HEX):");
Serial.println(tag.raw);
Serial.print("TAG DETECTED! - Waiting for ACK...");//Send this message to the serial monitor
if (radio.sendWithRetry(DESTINATION_NODE, "12345678", 8, 2, ACK_TIME))
{
Serial.println("ACK Received!");//If the sent packet was delivered and an ACK received, send this message to the serial monitor
delay(3);// Allow the the radio to switch to receive mode
Blink(LED,100);//Blink the transmitter led to show the data was successfully sent
}
}
}
}

When I send Serial.println(tag.id); to the serial monitor I get the correct id 12345678.
But if I use tag.id on the transmitting command if (radio.sendWithRetry(DESTINATION_NODE, tag.id, 8, 2, ACK_TIME)) I get the following error on the compiler:

Moteino_Homeseer_RFID_Node_V0_1.ino: In function 'void loop()':
Moteino_Homeseer_RFID_Node_V0_1:77: error: invalid conversion from 'long int' to 'const void*'
Moteino_Homeseer_RFID_Node_V0_1:77: error: initializing argument 2 of 'bool RFM69::sendWithRetry(byte, const void*, byte, byte, byte)'


So it looks like the data to be passed to the receiver should be of the const void* type and I'm trying to pass a long int into it.

So my question is, is it possible to make the tag.id content be converted into something that will occupy the 2nd argument of sendWithRetry()?

Thank you.
« Last Edit: June 14, 2014, 07:59:41 AM by luisr320 »

ssmall

  • Full Member
  • ***
  • Posts: 158
  • Country: us
Re: RFID moteino controled access system
« Reply #1 on: May 29, 2014, 10:11:50 PM »
You want to use a struct instead of a string.

Check out this post: https://lowpowerlab.com/forum/index.php/topic,94.msg211.html#msg211

Hope that helps

luisr320

  • Sr. Member
  • ****
  • Posts: 255
  • Country: pt
Re: RFID moteino controled access system
« Reply #2 on: May 30, 2014, 04:35:20 AM »
You want to use a struct instead of a string.

Check out this post: https://lowpowerlab.com/forum/index.php/topic,94.msg211.html#msg211

Hope that helps

Thank you for the pointer (pass the pun :))

I'll post back the developments and a full project description as soon as I figure this out.

luisr320

  • Sr. Member
  • ****
  • Posts: 255
  • Country: pt
Re: RFID moteino controled access system
« Reply #3 on: May 30, 2014, 01:20:59 PM »


That did it!!! Thank you.
Now I know what those struct examples are for ;)!

So now I can send the RFID tag id directly to the other moteino, which in turn sends it out the com port to my Homeseer home automation software.
But I can't figure out how to send text along with the TAG number.
I tried
Code: [Select]
typedef struct
{
char *dataType
long int tagID;
} Payload;
Payload theData;

But it doesn't work  :(
« Last Edit: May 30, 2014, 01:30:53 PM by luisr320 »

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: RFID moteino controled access system
« Reply #4 on: May 30, 2014, 01:48:59 PM »
You can store a char array but it needs to be fixed length (otherwise C++ won't know how long the struct is).
What you defined is a single char pointer, which takes 1 byte. That's perfectly fine but it won't have any meaning on the receiving end.
Sp you can make it something like char[20] then store up to 20 chars in there. Remember there is a maximum limit of 61 bytes for the RFM69 lib payload.

luisr320

  • Sr. Member
  • ****
  • Posts: 255
  • Country: pt
Re: RFID moteino controled access system
« Reply #5 on: May 30, 2014, 04:48:49 PM »
Thank you Felix, for your response.

I just can't do it.

If I try to use
 
Code: [Select]
typedef struct
{
char dataType[6];
} Payload;
Payload theData;

And in the loop()
Code: [Select]
theData.dataType = "TAGID";
Serial.println(theData.dataType);
Serial.println(sizeof(theData));
if (radio.sendWithRetry(DESTINATION_NODE, (const void*)(&theData), sizeof(theData), 2, ACK_TIME))

it doesn't compile.
It gives the following error:
Moteino_Homeseer_RFID_Node_V0_2.ino: In function 'void loop()':
Moteino_Homeseer_RFID_Node_V0_2:93: error: invalid array assignment


ssmall

  • Full Member
  • ***
  • Posts: 158
  • Country: us
Re: RFID moteino controled access system
« Reply #6 on: May 30, 2014, 05:46:29 PM »
Try the following:

strcpy(theData.dataType, "TAGID");

You have to be careful that the theData.dataType array is large enough for what you are copying from including the terminating null '\0'.

luisr320

  • Sr. Member
  • ****
  • Posts: 255
  • Country: pt
Re: RFID moteino controled access system
« Reply #7 on: May 30, 2014, 07:58:37 PM »


Finally!!!
I spent the whole day figuring this out and just a simple remark from Felix and ssmall and it got fixed.
So this is the winning code:

On the variables definition area of the sketch I inserted this:
Code: [Select]
typedef struct
{
char dataType[6];
long int data;
} Payload;
Payload theData;

And in the loop() I have this:
Code: [Select]
void loop() 
{

if(RFID.isIdAvailable())
{

Serial.println("TAG DETECTED!");//Send this message to the serial monitor

tag = RFID.readId();

Serial.print("TAG ID:");
Serial.println(tag.id);
Serial.print("TAG ID (HEX):");
Serial.println(tag.raw);

//fill in the struct with new values
strcpy(theData.dataType, "TAGID");
theData.data = tag.id;
Serial.print("Data packet size:");Serial.println(sizeof(theData));
Serial.println("Sending data to the gateway and waiting for ACK...");
if (radio.sendWithRetry(DESTINATION_NODE, (const void*)(&theData), sizeof(theData), 2, ACK_TIME))
{
Serial.println("ACK Received!");//If the sent packet was delivered and an ACK received, send this message to the serial monitor
Serial.println();
delay(3);// Allow the the radio to switch to receive mode
Blink(LED,100);//Blink the transmitter led to show the data was successfully sent
}
}
}
void Blink(byte PIN, int DELAY_MS)//Local led blinking function
{
pinMode(PIN, OUTPUT);
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}

And so now I get this on the serial monitor of the RFID node:
Code: [Select]
Transmiting at 433 Mhz...
TAG DETECTED! - Waiting for ACK...
ID:12358867
ID (HEX):010CBC94D3F6
10
ACK Received!

And on the receiving end, the gateway, I have this code on the variable declaration area of the sketch:
Code: [Select]
typedef struct {	
  char dataType[6]; //Type of data received
  long int data; //Data received
} Payload;
Payload theData;

And the loop() is like this:
Code: [Select]
void loop()
{
  if (radio.receiveDone())//If some packet was received by the radio, wait for all its contents to come trough
        {
if (radio.TARGETID == 1)//Check if the packet destination is this radio (NODE 1)
{
//Display a message on the serial monitor showing the packet origin radio NODE number
Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");
                       
//If the radio Promiscuous mode is ON, show the packet destination radio NODE number on the serial monitor
if (promiscuousMode)
{
Serial.print("to [");Serial.print(radio.TARGETID, DEC);Serial.print("] ");
}

//Add the transmission signal level to the message to be displayed on the serial monitor
                        Serial.print("[RX_RSSI:");Serial.print(radio.RSSI);Serial.println("] ");
                        Serial.print("Data packet size: ");Serial.println(sizeof(Payload));
                        theData = *(Payload*)radio.DATA; //assume radio.DATA actually contains our struct and not something else
                        Serial.print("Data Type: ");
                        Serial.println(theData.dataType);
                        Serial.print("Data: ");
                        Serial.println(theData.data);

                        //If an ACK (acknowledge) was requested by the data packet transmitter radio, send the ACK back to it and display "ACK sent" on the serial monitor
if (radio.ACK_REQUESTED)
{
radio.sendACK();
Serial.println("ACK sent!");
                                Serial.println();
                                Blink(LED,100);
}
}
}
}
void Blink(byte PIN, int DELAY_MS)//The led blinking function
{
  pinMode(PIN, OUTPUT);
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}

Which displays the following on the serial monitor:
Code: [Select]
[2] to [1] [RX_RSSI:-44] 
Data packet size: 10
Data Type: TAGID
Data: 12358867
ACK sent!

My home automation software show this on the log:
Code: [Select]
31-05-2014 00:56:01  - COM DATA 1 - ACK sent!
31-05-2014 00:56:01  - COM DATA 1 - Data: 12358867
31-05-2014 00:56:01  - COM DATA 1 - Data Type: TAGID
31-05-2014 00:56:01  - COM DATA 1 - Data packet size: 10
31-05-2014 00:56:01  - COM DATA 1 - [2] to [1] [RX_RSSI:-45]

HURRAY!!!

This way the RFID node can send the RFID tag ID to the gateway and both can care less of what the contents of the tag ID is.

Furthermore, as there is a type of data sent to the gateway along with the data itself (the "TAGID"), the gateway sends the data to my home automation software via USB COM port  for processing with VB Script language and it will know what type of node sent it and act accordingly, and will do the same to whatever other type of data I send from other nodes, like a remote control (next project), or a temperature sensor (future project).

So next I'm going to try to send back a blinking led command to the RFID node, simulating an "OPEN DOOR" command sent to the lock at the gate next to the RFID node.

I will also show some pictures of the present breadboard setup.

Thanks for the help

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: RFID moteino controled access system
« Reply #8 on: May 31, 2014, 09:11:18 AM »
Excellent!

luisr320

  • Sr. Member
  • ****
  • Posts: 255
  • Country: pt
Re: RFID moteino controled access system
« Reply #9 on: May 31, 2014, 12:51:02 PM »
So here is the breadboard setup of the seedstudio RFID board and the moteino:


I managed to get my home automation system to acknowledge and recognize the RFID tag and to send back to the RFID node a BLINK command to blink the local LED, thus closing the circuit.
For now the data sent back is just a simple "LED ON" text that the RFID node moteino detects coming in the radio.DATA and acts accordingly.
I still have to work on the data packet sent by the gateway containing the type of data, node destination, and the data itself and not just plain text.
« Last Edit: June 06, 2014, 07:56:36 PM by luisr320 »

luisr320

  • Sr. Member
  • ****
  • Posts: 255
  • Country: pt
Re: RFID moteino controled access system
« Reply #10 on: June 06, 2014, 07:47:02 PM »
Some more developments regarding this project:

I managed to get the the response from my home automation system (Homeseer) to go trough the Gateway Moteino back to the RFID node and the sketch on the RFID node reads the data correctly and blinks the local led for 5 seconds as a response. So now, as I approach the RFID tag to the RFID antenna after a very brief moment of about 1/2 a second the local LED starts blinking, showing that the whole circuit was processed.

I spent the whole week looking for ways to correctly read the data from the home automation computer serial port. The problem was quite simple to solve but only after I tried all the wrong ways of doing it.

Why was it hard? Well, for once I know nothing about C++. So I had to read all the stuff I could get my eyes on to try to figure this out. Of course I could just ask around and I'm sure I wouldn't waste so much time if I did, but by not doing it the easy way I now have a much better know-how to tackle my other Moteino projects.

So what was my solution, you ask?

Well, the whole projects goes like this:

[RFID ANTENA] --> [RFID MOTEINO NODE] ))))(airwaves)(((([GATEWAY MOTEINO]-->[USB PORT]-->[HOME AUTOM SOFT]-->[VB SCRIPT - CHECK TAG NUMBER LIST...

...IF TAG EXIST ON LIST SEND PROTOCOL #2/1/]-->[HOME AUTOM SOFT]-->[USB PORT]-->[GATEWAY MOTEINO]))))(airwaves)(((([RFID MOTEINO NODE]-->[DOOR LOCK]

The biggest problem to solve was how to handle variable types conversion form String to char to int to whatever. I guess for someone with experience in C++ that wouldn't be a problem but for me it drove me on a path of discovery reading everything I could get my eyes on.
The simple solution was to make my home automation software lookup the tag number it received trough the serial port (USB) on a txt file and if it is on that list sends a preset protocol phrase to the serial port to be picked up by the Serial.read() of the gateway Moteino and passed on to the RFID node.

The protocol e very simple: #2/3/
The '#' marks the beginning of the message. The '2' is the node number to which this message will be sent to and the '/' marks the end of the node number. This is important because the node number may have more than one digit and the gateway must know where to stop reading the node number. Next is a data package, an unsigned long int (a bit overkill since it may hold a number as big as 4.294.967.295), which will be interpreted by the RFID Moteino node and act upon according to the loaded sketch. In this case that '1/' means blink the local led and flip flop some digital output to drive the electric lock. So this means I can send 4.294.967.295 different instructions to any node as a response to a RFID Tag. Maybe I'll turn them into an int later on :).

This is where the parsing and interpretation of the protocol message is done on the gateway:
Code: [Select]
if (Serial.available()>0)
{
inbyte = Serial.read();
if (inbyte == '#')//É o início de um packet?
{
serialdata = 0;
while (inbyte != '/')
{
inbyte = Serial.read();
if (inbyte > 0 && inbyte != '/')
{
serialdata = serialdata * 10 + inbyte - '0';
}
}
inbyte = 0;
destinationNode = serialdata;//Atribui o numero do node a destinationNode
Serial.print("destinationNode:");Serial.println(destinationNode);

serialdata = 0;
while (inbyte != '/')
{
inbyte = Serial.read();
if (inbyte > 0 && inbyte != '/')
{
serialdata = serialdata * 10 + inbyte - '0';
}
}
inbyte = 0;
data = serialdata;//Atribui o numero do node a destinationNode
Serial.print("Data:");Serial.println(data);
}
Serial.flush();
if (radio.sendWithRetry(destinationNode, (const void*)&data, 5, 5, ACK_TIME))
{
Serial.println("ACK Received!");//If the sent packet was delivered and an ACK received, send this message to the serial monitor
delay(3);// Allow the the radio to switch to receive mode
}
destinationNode = 0;
data = 0;
Serial.flush();
}
I still have to do some tuning on the code to prevent the gateway to get mad and lost if the protocol message is broken midway for some reason.

I'll be updating the code I posted previously and add some more as soon as I have more time.

The last thing I did was to connect an optocoupler that will drive the electric door lock. I'll make a video of the whole thing soon.

Happy Motoining :)
« Last Edit: June 06, 2014, 07:55:25 PM by luisr320 »

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: RFID moteino controled access system
« Reply #11 on: June 07, 2014, 01:02:08 PM »
Thanks for continuing to share your progress, nice to see you are persevering and not giving up. Electronics is fun when things start to work ;)

luisr320

  • Sr. Member
  • ****
  • Posts: 255
  • Country: pt
Re: RFID moteino controled access system
« Reply #12 on: June 14, 2014, 07:59:07 AM »
With the arrival of the new Moteinos I could finally finish my RFID project. The Moteino was essential since I didn't wanted to run wires trough the house.

Since the intercom box runs on 24V, I had to reduce it to 5V for the RFID reader and trust the internal voltage regulator of the Moteino to bring it further down to 3.3V.
I had a couple of DC/DC converters I bought on ebay and it seemed a good candidate for the project. A small trim pot allowed the output voltage to be precisely regulated to 4.99V, good enough for me:


Then came the problem of joining all together in a single circuit board. I didn't want to waste time fabricating a PCB so I used a perfboard:



The intercom box is made of aluminum, so I had to position the antena behind the plastic name tag:

Hot glued in placed:

A new tag for the front:


Then all was enclosed in a neat box I had:


Closing up:


Voltage regulator on top:


Next I'll make a small video to show how the system works and post the final code used on both Moteinos. I still have to clean up and comment the code.

Now I can give a tag to the gardener and program my home automation system to only allow that tag to open on a preset time window and only on the days hes coming.
And I can now check at what time my kids come in at night, with the possibility to send SMS messages or mails when they do. And I can open the door from the other side of the world, if necessary.

Now lets move on to my next project.  :D

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: RFID moteino controled access system [FINISHED]
« Reply #13 on: June 14, 2014, 08:24:59 PM »
Pretty awesome, looking forward to your video :D

WhiteHare

  • Hero Member
  • *****
  • Posts: 1300
  • Country: us
Re: RFID moteino controled access system [FINISHED]
« Reply #14 on: January 06, 2016, 02:18:15 PM »
@luisr320:  I'm impressed!

I understand you're sending your data to the serial port on whatever platform you have running Homeseer, but how are you importing that data into Homeseer and getting it to work within that framework?  I have Homeseer3, but this has been a stumbling block on unifying the two worlds.  I assume you wrote a Homeseer script of some kind?

In general, I prefer Felix's Pi automation over mysensors, but mysensors does have a homeseer plug-in, so it's tempting, but only for that reason.
« Last Edit: January 06, 2016, 04:50:20 PM by WhiteHare »