I'm VERY new to Ardiuno, having only ever worked with Raspberry Pis and even then never with the actual pins. This is my very first hardware project.
Project: automated cat feeder for use while I'm on vacation
Issue: I'm having memory crash/reboots at random and I'm unable to determine the cause. I cannot tell if I have a faulty board or if my limited C knowledge has caused memory issues.
Connected hardware: RFID reader, servo, LED
Board: https://www.amazon.com/gp/product/B07333L9VR/ (this is exactly the board I purchased based upon a tutorial I found)
RFID Reader: 125Khz RFID module - UART | Seeed Studio Wiki
Code: attached
Known issues: these occurred after I began noticing the crash/reboot process. I find it highly unlikely that they are the issue.
- I'm not great at soldering. I know it's not the best job but I've ensured there aren't any bridges causing shorts.
- I somehow managed to mess up the LED. I don't know if I soldered one of the resisters on backwards, if I fried something in it while attaching the leads and resisters or if I managed to somehow attach the leads to the GPIO pins in the wrong order. I only added the LED for troubleshooting while detached from my computer. The crashes occurred before the addition of the light and I used it to tell when reboot/wifi reconnect occurred.
Configuration:
- all 5v power is tied together to a 5v transformer (both positive and ground) so as to remove the load from the USB port
- Servo data line is attached to pin D1
- LED R is pin D5
- LED G is pin D6
- LED B is pin D7
- RFID TX is pin D2
- Error log readout is attached
Other notes:
- As I mentioned, this is my first project. I'll be going on vacation at the end of the month and I need to get this running in a stable manner before then.
- The entire reason for the different RFID tags is because 1 cat is on a diet, 1 cat never gets to eat her food because the one on the diet steals it, and one cat is a kitten that needs free access to food right now. This type of access control is easily handled manually but I need to ensure their diet is followed while I'm gone.
- I can provide the API I have set up if needed. It's built in Node.JS and SQLite and running on a Raspberry Pi Zero.
- My understanding of C syntax is limited. I work in software development but I'm teaching myself this language for hobby use in my free time. If I've made an error I would very much appreciate the opportunity to learn through examples rather than being told what I've done wrong. I can't spontaneously know what I don't already know.
- The log files are just a sample. I can provide more if requested.
UPDATE
I removed the original attachment and have included the updated code below. I re-wrapped the RFID.available() as the trigger in the main loop rather than calling a function blindly and THEN testing. I've also included a second log. I'm repeatedly getting the following error with some variation of stack trace (see attached for trace).
Exception 0: Illegal instruction
PC: 0x4022fe48
EXCVADDR: 0x00000000
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <SoftwareSerial.h>
#include <Servo.h>
SoftwareSerial RFID(D2, D3); // RX and TX
Servo servo;
HTTPClient http;
const char* ssid = "YourSSID";
const char* password = "YOURPASSWORD";
// use first sketch in http://wp.me/p3LK05-3Gk to get your tag numbers
int tag1[14] = {2, 54, 56, 48, 48, 65, 57, 54, 67, 54, 48, 67, 68, 3}; //Medli
int tag2[14] = {2, 54, 56, 48, 48, 65, 57, 66, 55, 69, 53, 57, 51, 3}; //testing
//int tag2[14] = {2, 54, 56, 48, 48, 65, 57, 56, 52, 53, 52, 49, 49, 3}; //Pixel
int tag3[14] = {2, 54, 56, 48, 48, 65, 57, 56, 52, 53, 49, 49, 52, 3}; //Majora
void setup()
{
pinMode(D5, OUTPUT);
pinMode(D6, OUTPUT);
pinMode(D7, OUTPUT);
Serial.begin(9600); // start serial to PC
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
analogWrite(D5, 0); //R
analogWrite(D6, 0); //G
analogWrite(D7, 0); //B
delay(500);
analogWrite(D5, 255);
analogWrite(D6, 0);
analogWrite(D7, 0);
delay(500);
}
analogWrite(D5, 0);
analogWrite(D6, 255);
analogWrite(D7, 0);
RFID.begin(9600); // start serial to RFID reader
}
void loop()
{
if (RFID.available() > 0) {
Serial.println(F("RFID Available"));
readTags();
}
}
boolean comparetag(int a[14], int b[14])
{
int d = 0;
for (int c = 0 ; c < 14 ; c++)
{
if (a[c] == b[c])
{
d++;
}
}
if (d == 14)
{
return true;
}
return false;
}
int checkmytags(int newtag[14]) // compares each tag against the tag just read
{
int cat = -1;
if (comparetag(newtag, tag1) == true)
{
cat = 0;
}
if (comparetag(newtag, tag2) == true)
{
cat = 2;
}
if (comparetag(newtag, tag3) == true)
{
cat = 1;
}
if (calculateUsage(cat) == 0) {
return 0;
}
else {
return 1;
}
}
void readTags()
{
int newtag[14] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // used for read comparisons
int tagCheck = -1;
//if (RFID.available() > 0)
//{
// read tag numbers
delay(100); // needed to allow time for the data to come in from the serial buffer.
for (int z = 0 ; z < 14 ; z++) // read the rest of the tag
{
int data1 = RFID.read();
newtag[z] = data1;
}
RFID.flush(); // stops multiple reads
analogWrite(D5, 0);
analogWrite(D6, 0);
analogWrite(D7, 255);
//do the tags match?
tagCheck = checkmytags(newtag);
//}
// now do something based on tag type
if (tagCheck == 0) // if we had a match
{
analogWrite(D5, 128);
analogWrite(D6, 0);
analogWrite(D7, 128);
feed();
delay(600000);
}
else if (tagCheck != 0) // if we didn't have a match
{
analogWrite(D5, 255);
analogWrite(D6, 255);
analogWrite(D7, 0);
delay(1000);
}
}
void feed() {
servo.attach(5);
servo.write(180);
delay(250);
servo.write(90);
servo.detach();
}
int checkCap(int cat) {
String address = "http://192.168.2.19:3000/cats/";
String uriValue = "/cap";
String string = address + cat + uriValue;
if (WiFi.status() == 3) {
http.begin(string);
int httpCode = http.GET();
String payload = http.getString();
http.end();
if (httpCode != 200) {
return -1;
}
int validate = payload.toInt();
return validate;
}
else {
return -1;
}
}
int checkUsage(int cat) {
String address = "http://192.168.2.19:3000/cats/";
String uriValue = "/usage";
String string = address + cat + uriValue;
if (WiFi.status() == 3) {
http.begin(string);
int httpCode = http.GET();
String payload = http.getString();
http.end();
if (httpCode != 200) {
return -1;
}
int validate = payload.toInt();
return validate;
}
else {
return -1;
}
}
int calculateUsage(int cat) {
int usage = checkUsage(cat);
int counter = 0;
while (usage < 0 && counter <= 5) {
delay(1000);
int usage = checkUsage(cat);
counter++;
}
if (counter == 5 && usage < 0) {
return -1;
}
delay(1000);
counter = 0;
int cap = checkCap(cat);
while (cap < 0 && counter <= 5) {
delay(500);
int cap = checkCap(cat);
counter++;
}
if (counter == 5 && cap < 0) {
return -1;
}
counter = 0;
if (cap == 0) {
return 0;
}
if (usage < cap) {
int updateUsageResult = updateUsage(cat, usage);
while (updateUsageResult != 0 && counter <= 5) {
delay(1000);
int updateUsageResult = updateUsage(cat, usage);
counter++;
}
if (counter == 5 && updateUsageResult != 0) {
return -1;
}
return 0;
}
else {
return 1;
}
}
int updateUsage(int cat, int usage) {
int updateValue = usage + 1;
String address = "http://192.168.2.19:3000/cats/update";
String put1 = "cat=";
String put2 = "&";
String put3 = "usage=";
String putValue = put1 + cat + put2 + put3 + updateValue;
if (WiFi.status() == 3) {
http.begin(address);
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
int httpCode = http.PUT(putValue);
String payload = http.getString();
http.end();
if (payload == "Ok") {
return 0;
} else {
return -1;
}
}
else {
return -1;
}
}
log.txt (187 KB)
log2.txt (63.3 KB)