I am new to the Arduino world and I am busy with a project. The details of the project are,
I have RF tags attached to boxes and a RF reader (RC522) attached to a mobile crane. When the crane drops the box I want to record the that last GPS position and date time and send it to my server. On the crane I have a Waveshare SIM 808 shield and an Arduino mega for recording the GPS data. I have got the arduino to start the GPS position and constantly record while there is contact between the tag and reader.
The issues I am experiencing are
I cannot get the tag id
I cannot store the last position and time to a variable to send once the contact is broken between the RF reader and tag
My code is below , hardware used is
Arduino Mega 2560
RC522 RF reader
Waveshare SIM808 module
#include <SPI.h>
#include <RFID.h>
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>
#define SDA_DIO 53 /* define for RC522 */
#define RESET_DIO 5 /* define for RC522 */
#define PIN_RX 11 /* define for Sim8080 */
#define PIN_TX 10 /* define for Sim808 */
RFID RC522(SDA_DIO, RESET_DIO);
SoftwareSerial mySerial(PIN_TX, PIN_RX);
DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,
static char latitude;
static char longitude;
static char positiontime;
static char tagid;
static int count;
void setup()
{
mySerial.begin(9600);
Serial.begin(9600);
SPI.begin();
RC522.init();
//************* Turn on the GPS power************
if ( sim808.attachGPS())
Serial.println("Open the GPS power success");
else
Serial.println("Open the GPS power failure");
}
void loop() {
if (sim808.getGPS() && RC522.isCard()) {
count = count + 1;
Serial.print(RC522.serNum[count], DEC);
Serial.print(sim808.GPSdata.year);
Serial.print("/");
Serial.print(sim808.GPSdata.month);
Serial.print("/");
Serial.print(sim808.GPSdata.day);
Serial.print(" ");
Serial.print(sim808.GPSdata.hour);
Serial.print(":");
Serial.print(sim808.GPSdata.minute);
Serial.print(":");
Serial.print(sim808.GPSdata.second);
Serial.print(":");
Serial.println(sim808.GPSdata.centisecond);
Serial.print("latitude :");
Serial.println(sim808.GPSdata.lat, 6);
sim808.latitudeConverToDMS();
Serial.print("latitude :");
Serial.print(sim808.latDMS.degrees);
Serial.print("\^");
Serial.print(sim808.latDMS.minutes);
Serial.print("\'");
Serial.print(sim808.latDMS.seconeds, 6);
Serial.println("\"");
Serial.print("longitude :");
Serial.println(sim808.GPSdata.lon, 6);
sim808.LongitudeConverToDMS();
Serial.print("longitude :");
Serial.print(sim808.longDMS.degrees);
Serial.print("\^");
Serial.print(sim808.longDMS.minutes);
Serial.print("\'");
Serial.print(sim808.longDMS.seconeds, 6);
Serial.println("\"");
Serial.print("speed_kph :");
Serial.println(sim808.GPSdata.speed_kph);
Serial.print("heading :");
Serial.println(sim808.GPSdata.heading);
Serial.print(count);
latitude = (sim808.GPSdata.lat, 6);
longitude = (sim808.GPSdata.lon, 6);
positiontime = (sim808.latDMS.seconeds, 6);
}
//************* Turn off the GPS power ************
if (count != 0) {
Serial.print(" last latitude is :");
Serial.print(latitude);
Serial.print(" last longitue is :");
Serial.print(longitude);
}
}
I am very new to Arduino. I have tried using serial on the Mega but the Sim808 does not connect.
I have split the if statement to read the RF then send me the location. The result is still the same, I get constant GPS positions when the card is present.
Details of the project are. Its an industrial crane that lifts boxes from a point and then drives and drops them of at another point. I am trying to get the latitude and longitude of the drops against the tag id. In short Crane A dropped Box 123 at latitude 29,934343, longitude 12.232323.
I am very new to Arduino. I have tried using serial on the Mega but the Sim808 does not connect.
This sounds like one of the first things to correct. Use one of the additional hardware serial ports on the Mega rather than software serial.
The Arduino Mega has three additional serial ports: Serial1 on pins 19 (RX) and 18 (TX), Serial2 on pins 17 (RX) and 16 (TX), Serial3 on pins 15 (RX) and 14 (TX).
Based on your code and guesses on how the libraries work (I don't use those),
-> Assumes you have enough power for your SIM808
-> Assumes SIM808 Rx and Tx are 5V compatible
-> Connect sim808 Rx to pin 18 (TX1) and sim808 Tx to pin 19 (RX1) to use Serial1
I would structure the code somewhat like this:
setup():
opens Serial communication at 115200 bauds with your Mac/PC
opens Serial1 communication at 9600 bauds with your SIM808
initializes the sim808 on Serial1
activates the GPS
loop():
constantly listens for a GPS fix and maintains a copy in lastGPSData
checks for card presence and maintains a copy of the Serial Number in lastSerial
upon loosing card contact, if there was a card known, prints the lat/long of last fix.
the code could be something like this - fully untested, typed here....
#include <RFID.h> // assuming https://github.com/song940/RFID-RC522
#include <DFRobot_sim808.h>
#define SS_PIN 53 /* RC522 SS pin */
#define RST_PIN 5 /* RC522 Reset pin */
RFID rfid(SS_PIN, RST_PIN);
DFRobot_SIM808 sim808(&Serial1);
// Connect sim808 to Serial1 on your MEGA
// sim808 Rx to pin 18 (TX1)
// sim808 Tx to pin 19 (RX1)
// and POWER
const byte serialNumberSize = sizeof rfid.serNum;
uint8_t emptySerial[serialNumberSize];
uint8_t lastSerial[serialNumberSize];
DFRobot_SIM808::gspdata lastGPSData;
bool fixAcquired = false;
void setup() {
Serial.begin(115200);
Serial1.begin(9600);
SPI.begin();
rfid.init();
Serial.println(F("\nReady"));
memcpy(lastSerial, emptySerial, sizeof emptySerial); // set last Serial to null
byte nbTrials = 0;
Serial.print(F("sim808 init "));
while (!sim808.init()) {
nbTrials++;
if (nbTrials >= 5) {
Serial.print("Sim808 init error\r\n");
while (true) yield(); // die here
} else Serial.write('.');
delay(1000);
}
Serial.println(F("sim808 init OK"));
if ( sim808.attachGPS()) {
Serial.println("ERROR: GPS failure");
while (true) yield(); // die here
}
Serial.println(F("GPS OK"));
}
void loop() {
if (sim808.getGPS()) {
lastGPSData = sim808.GPSdata; // capture fix as often as possible
fixAcquired = true; // remember we have at least one
}
if (rfid.isCard()) { // there is a card
if (rfid.readCardSerial()) memcpy(lastSerial, rfid.serNum, sizeof emptySerial); // if we can read its tag, let's capture it
} else { // we don't see a card present
if (! memcmp(lastSerial, emptySerial, serialNumberSize)) { // check if we had one before
// yes, so we lost connexion with a known Serial
Serial.println(F("I just lost contact with card #"));
for (uint8_t i = 0; i < serialNumberSize; i++) {
if (lastSerial[i] < 0x10) Serial.write('0');
Serial.print(lastSerial[i], HEX);
}
Serial.println();
// print our last known fix
// coud do that only if fixAcquired is true, would also need to check how old it is...
Serial.print(F("GPS POSITION: "));
Serial.print(lastGPSData.lat, 6);
Serial.write(',');
Serial.println(lastGPSData.lon, 6);
memcpy(lastSerial, emptySerial, serialNumberSize); // reset last Serial to null
} // else there was no known card to deal with
}
}
One issue is that time is not handled, so the last fix might be very old if the GPS is not working well.
I have no clue if the RFID library works as advertised. I only used Miguel Balboa's one.
it uses RC522.readCardSerial() to read serial number
I have tried the code you sent me and the output is
00:20:27.105 -> I just lost contact with card #
00:20:27.137 -> 0000000000
00:20:27.137 -> GPS POSITION: 0.000000
00:20:27.172 -> ,0.000000
00:20:27.172 -> I just lost contact with card #
00:20:27.206 -> 0000000000
00:20:27.240 -> GPS POSITION: 0.000000
00:20:27.240 -> ,0.000000
00:20:27.275 -> I just lost contact with card #
00:20:27.308 -> 0000000000
00:20:27.308 -> GPS POSITION: 0.000000
00:20:27.349 -> ,0.000000
00:20:27.349 -> I just lost contact with card #
00:20:27.382 -> 0000000000
00:20:27.382 -> GPS POSITION: 0.000000
00:20:27.417 -> ,0.000000
00:20:27.417 -> I just lost contact with card #
00:20:27.452 -> 0000000000
00:20:27.485 -> GPS POSITION: 0.000000
00:20:27.519 -> ,0.000000
The output stops when a tag is presented. It should work work opposite to the output. When a tag is presented the id and GPS data should be read and when the connection is lost this should be stored and sent. How will I send only the last value to via HTTP.
Seems the GPS does not work as you don’t get any position. Are you powering the module with enough current?
The way it was coded (at least attempted to) was to report gps’ position upon loosing the card (The idea was that if you loose connection it’s probably when you dropped the box. )
As you can see the printing is in the else part of a check on rfid.isCard() so If you think you get something printed upon presenting a card, may be it’s because the rfid.isCard() method returns the card only once?
=> write a simple code to print rfid.isCard() and ensure it does what you expect
The GPS is working I tested it with my script. How will I store the last tag id, last latitude, last longitude in a variable and send it to the server.
How will I store the last tag id, last latitude, last longitude in a variable
in my code
This part is feeding the GPS
if (sim808.getGPS()) {
lastGPSData = sim808.GPSdata; // capture fix as often as possible
fixAcquired = true; // remember we have at least one
}
and maintaining in lastGPSData variable the last known good GPS fix.
That part is supposed to copy the Serial Number into the lastSerial variable as long as you see a card
if (rfid.isCard()) { // there is a card
if (rfid.readCardSerial()) memcpy(lastSerial, rfid.serNum, sizeof emptySerial); // if we can read its tag, let's capture it
}
In the else part of that if, you know you've lost contact with the card so if lastSerial has ever been initialized and you've got a fix, then you have all you need.