Hi,
This ought to be a challenge…
Im trying to have the Redboard (arduino) work with ESP8266 wifi shield and the M6E Nano rfid reader.
The thought is the following:
-
M6E Nano reads a rfid sticker
-
The program sends a ping to a server with the EPC through the wifi shield.
I have taken the examples (provided by sparkfun) for both shields and combined them into the code below.
It works for a little while - i can see it being sent up to the server. The reading of the rfid works continuously, but it stops pinging the server unless there is a constant flow of readings. Ie. i read the tag - it works - then wait a minute and read again → the rfid will read it but it wont ping the server.
What am I doing wrong in my code?
#include <SoftwareSerial.h> //Used for transmitting to the device
SoftwareSerial softSerial(2, 3); //RX, TX
#include "SparkFun_UHF_RFID_Reader.h" //Library for controlling the M6E Nano module
RFID nano; //Create instance
#define BUZZER1 10
//#define BUZZER1 0 //For testing silently
#define BUZZER2 9
boolean tagDetected; //Keeps track of when we've beeped
#include <SparkFunESP8266WiFi.h>
const char mySSID[] = "mywifi";
const char myPSK[] = "mywifipass";
//ESP8266Server server = ESP8266Server(80);
const char destServer[] = "mydomain.se";
//const String httpRequest = "GET / HTTP/1.1\n"
// "Host: mydomain.se\n"
// "Connection: close\n\n";
// To use the ESP8266 as a TCP client, use the
// ESP8266Client class. First, create an object:
ESP8266Client client;
void setup()
{
Serial.begin(115200);
initializeESP8266();
connectESP8266();
displayConnectInfo();
// ESP8266Client connect([server], [port]) is used to
// connect to a server (const char * or IPAddress) on
// a specified port.
// Returns: 1 on success, 2 on already connected,
// negative on fail (-1=TIMEOUT, -3=FAIL).
//int retVal = client.connect(destServer, 80);
//if (retVal <= 0)
//{
// Serial.println(F("Failed to connect to server."));
// return;
//}
int retVal;
do {
delay(50);
retVal = client.connect(destServer, 80);
} while (retVal <=0);
while (!Serial); //Wait for the serial port to come online
if (setupNano(38400) == false) //Configure nano to run at 38400bps
{
Serial.println(F("Module failed to respond. Please check wiring."));
while (1); //Freeze!
}
nano.setRegion(REGION_OPEN); //Set to North America
nano.setReadPower(500); //5.00 dBm. Higher values may caues USB port to brown out
//Max Read TX Power is 27.00 dBm and may cause temperature-limit throttling
Serial.println(F("Press a key to begin scanning for tags."));
while (!Serial.available()); //Wait for user to send a character
Serial.read(); //Throw away the user's character
nano.startReading(); //Begin scanning for tags
}
void loop()
{
if (nano.check() == true) //Check to see if any new data has come in from module
{
byte responseType = nano.parseResponse(); //Break response into tag ID, RSSI, frequency, and timestamp
if (responseType == RESPONSE_IS_KEEPALIVE)
{
Serial.println(F("Scanning"));
tagDetected = false;
//lowBeep();
}
else if (responseType == RESPONSE_IS_TAGFOUND)
{
//If we have a full record we can pull out the fun bits
int rssi = nano.getTagRSSI(); //Get the RSSI for this tag read
long freq = nano.getTagFreq(); //Get the frequency this tag was detected at
long timeStamp = nano.getTagTimestamp(); //Get the time this was read, (ms) since last keep-alive message
byte tagEPCBytes = nano.getTagEPCBytes(); //Get the number of bytes of EPC from response
Serial.print(F(" rssi["));
Serial.print(rssi);
Serial.print(F("]"));
Serial.print(F(" freq["));
Serial.print(freq);
Serial.print(F("]"));
Serial.print(F(" time["));
Serial.print(timeStamp);
Serial.print(F("]"));
//Print EPC bytes, this is a subsection of bytes from the response/msg array
Serial.print(F(" epc["));
String test;
for (byte x = 0 ; x < tagEPCBytes ; x++)
{
if (nano.msg[31 + x] < 0x10) Serial.print(F("0")); //Pretty print
Serial.print(nano.msg[31 + x], HEX);
Serial.print(F(" "));
test = test + (nano.msg[31+x]);
}
Serial.print(F("]"));
Serial.println();
Serial.print(test);
Serial.println();
clientDemo(String(test));
if (tagDetected == false) //Beep if we've detected a new tag
{
tagDetected = true;
highBeep();
}
}
else if (responseType == ERROR_CORRUPT_RESPONSE)
{
Serial.println("Bad CRC");
tagDetected = false;
//lowBeep();
}
else
{
//Unknown response
Serial.print("Unknown error");
tagDetected = false;
//lowBeep();
}
}
}
//Gracefully handles a reader that is already configured and already reading continuously
//Because Stream does not have a .begin() we have to do this outside the library
boolean setupNano(long baudRate)
{
nano.begin(softSerial); //Tell the library to communicate over software serial port
//Test to see if we are already connected to a module
//This would be the case if the Arduino has been reprogrammed and the module has stayed powered
softSerial.begin(baudRate); //For this test, assume module is already at our desired baud rate
while(!softSerial); //Wait for port to open
//About 200ms from power on the module will send its firmware version at 115200. We need to ignore this.
while(softSerial.available()) softSerial.read();
nano.getVersion();
if (nano.msg[0] == ERROR_WRONG_OPCODE_RESPONSE)
{
//This happens if the baud rate is correct but the module is doing a ccontinuous read
nano.stopReading();
Serial.println(F("Module continuously reading. Asking it to stop..."));
delay(1500);
}
else
{
//The module did not respond so assume it's just been powered on and communicating at 115200bps
softSerial.begin(115200); //Start software serial at 115200
nano.setBaud(baudRate); //Tell the module to go to the chosen baud rate. Ignore the response msg
softSerial.begin(baudRate); //Start the software serial port, this time at user's chosen baud rate
}
//Test the connection
nano.getVersion();
if (nano.msg[0] != ALL_GOOD) return (false); //Something is not right
//The M6E has these settings no matter what
nano.setTagProtocol(); //Set protocol to GEN2
nano.setAntennaPort(); //Set TX/RX antenna ports to 1
return (true); //We are ready to rock
}
void initializeESP8266()
{
// esp8266.begin() verifies that the ESP8266 is operational
// and sets it up for the rest of the sketch.
// It returns either true or false -- indicating whether
// communication was successul or not.
// true
int test = esp8266.begin();
if (test != true)
{
Serial.println(F("Error talking to ESP8266."));
errorLoop(test);
}
Serial.println(F("ESP8266 Shield Present"));
}
void connectESP8266()
{
// The ESP8266 can be set to one of three modes:
// 1 - ESP8266_MODE_STA - Station only
// 2 - ESP8266_MODE_AP - Access point only
// 3 - ESP8266_MODE_STAAP - Station/AP combo
// Use esp8266.getMode() to check which mode it's in:
int retVal = esp8266.getMode();
if (retVal != ESP8266_MODE_STA)
{ // If it's not in station mode.
// Use esp8266.setMode([mode]) to set it to a specified
// mode.
retVal = esp8266.setMode(ESP8266_MODE_STA);
if (retVal < 0)
{
Serial.println(F("Error setting mode."));
errorLoop(retVal);
}
}
Serial.println(F("Mode set to station"));
// esp8266.status() indicates the ESP8266's WiFi connect
// status.
// A return value of 1 indicates the device is already
// connected. 0 indicates disconnected. (Negative values
// equate to communication errors.)
retVal = esp8266.status();
if (retVal <= 0)
{
Serial.print(F("Connecting to "));
Serial.println(mySSID);
// esp8266.connect([ssid], [psk]) connects the ESP8266
// to a network.
// On success the connect function returns a value >0
// On fail, the function will either return:
// -1: TIMEOUT - The library has a set 30s timeout
// -3: FAIL - Couldn't connect to network.
retVal = esp8266.connect(mySSID, myPSK);
if (retVal < 0)
{
Serial.println(F("Error connecting"));
errorLoop(retVal);
}
}
}
void displayConnectInfo()
{
char connectedSSID[24];
memset(connectedSSID, 0, 24);
// esp8266.getAP() can be used to check which AP the
// ESP8266 is connected to. It returns an error code.
// The connected AP is returned by reference as a parameter.
int retVal = esp8266.getAP(connectedSSID);
if (retVal > 0)
{
Serial.print(F("Connected to: "));
Serial.println(connectedSSID);
}
// esp8266.localIP returns an IPAddress variable with the
// ESP8266's current local IP address.
IPAddress myIP = esp8266.localIP();
Serial.print(F("My IP: ")); Serial.println(myIP);
}
// errorLoop prints an error code, then loops forever.
void errorLoop(int error)
{
Serial.print(F("Error: ")); Serial.println(error);
Serial.println(F("Looping forever."));
for (;;)
;
}
void clientDemo(String id)
{
/* if (client.connected() == 0){
client.connect(destServer, 80);
Serial.write("Reconnected");
}*/
// print and write can be used to send data to a connected
// client connection.
String httpRequest = "GET /rfid.php/?id="+id+" HTTP/1.1\n"
"Host: mydomain.se\n"
"Connection: closed\n\n";
client.print(httpRequest);
// available() will return the number of characters
// currently in the receive buffer.
while (client.available()){
Serial.write(client.read()); // read() gets the FIFO char
}
// connected() is a boolean return value - 1 if the
// connection is active, 0 if it's closed.
if (client.connected())
client.stop(); // stop() closes a TCP connection.
}
// serialTrigger prints a message, then waits for something
// to come in from the serial port.
void serialTrigger(String message)
{
Serial.println();
Serial.println(message);
Serial.println();
while (!Serial.available())
;
while (Serial.available())
Serial.read();
}
void lowBeep()
{
tone(BUZZER1, 130, 150); //Low C
//delay(150);
}
void highBeep()
{
tone(BUZZER1, 2093, 150); //High C
//delay(150);
}