Hi guys, I am quite new to the ethernet world. So please bear with me if I do ask stupid questions.
I designed a PCB using Atmega328P+ENC28J60 chip (schematic attached in the images below - sch1, sch2, sch3). The function of this board is basically sending GET requests to the server and retrieve a set of json data, so based on my understanding my board acts as a client only right? I am currently using UIPEthernet v2.0.9 and ArduinoJson v6.17.0, code is as below:
#include <EEPROM.h>
#include <ArduinoJson.h>
#include <UIPEthernet.h>
#define OUT0 2
#define OUT1 A3
#define OUT2 A2
#define OUT3 A1
#define OUT4 A0
#define OUT5 9
#define OUT6 8
#define OUT7 7
#define OUT8 6
#define OUT9 5
#define CS 10
// mac: 46 57 5a 6b 48 51
// mac (char): FWZkHQ
#define HOSTNAME "autolighting.afa-sports.com"
#define ID_SIZE 6
byte mac[ID_SIZE];
char macBuffer[ID_SIZE*2];
const byte output[] PROGMEM = {OUT0, OUT1, OUT2, OUT3, OUT4, OUT5, OUT6, OUT7, OUT8, OUT9};
EthernetClient client;
void clientRead() {
StaticJsonDocument<40> filter;
StaticJsonDocument<120> doc;
filter.clear();
doc.clear();
filter["data"]["relay_actions"] = true;
Serial.println(doc.memoryUsage());
client.find("\r\n\r\n");
deserializeJson(doc, client, DeserializationOption::Filter(filter));
client.flush();
delay(50);
if (!doc["data"]["relay_actions"].isNull()) {
for (byte i = 0; i < 10; i++) {
// Serial.print(doc["data"]["relay_actions"][i].as<bool>());
digitalWrite(pgm_read_byte_near(&output[i]), doc["data"]["relay_actions"][i].as<bool>());
}
// Serial.println();
}
filter.clear();
doc.clear();
Serial.println(freeRam());
}
void sendReq() {
client.println(F("GET /api/iot/master-controller/get-command HTTP/1.1"));
client.println(F("Host: autolighting.afa-sports.com"));
client.println(F("DEVICE-ID: 46575a6b4851"));
// client.print(F("DEVICE-ID: "));
// client.println(macBuffer);
client.println(F("Connection: close"));
client.println();
}
void setup() {
Serial.begin(115200);
for (byte i = 0; i < 10; i++) {
pinMode(pgm_read_byte_near(&output[i]), OUTPUT);
digitalWrite(pgm_read_byte_near(&output[i]), LOW);
}
for (uint8_t i = 0; i < ID_SIZE; i++) {
byte charByte = EEPROM.read(i);
if (charByte != 0) {
char temp[2];
mac[i] = charByte;
itoa(mac[i], temp, 16);
strcat(macBuffer, temp);
free(temp);
}
}
Serial.println(macBuffer);
Ethernet.init(CS);
while (!Ethernet.begin(mac)) {
Serial.println(F("Failed to configure Ethernet"));
}
delay(1000);
}
void loop() {
Ethernet.maintain();
if (client.connect(HOSTNAME, 80)) {
sendReq();
clientRead();
}
client.stop();
delay(2000);
}
Due to the high SRAM consumption (1.3kb) and I might have other things (not sure what yet) to add in to the board in the future, I tried to minimize the dynamic memory by changing this (in the uipethernet-conf.h file):
#define UIP_SOCKET_NUMPACKETS 5
#define UIP_CONF_MAX_CONNECTIONS 4
#define UIP_CONF_UDP_CONNS 4
to this (888bytes SRAM):
#define UIP_SOCKET_NUMPACKETS 2
#define UIP_CONF_MAX_CONNECTIONS 1
#define UIP_CONF_UDP_CONNS 1
I'm wondering will this affect the system performance? Btw, I've also set the timeout to 10s
After 13 hours of smooth operation, the board freezes and only became normal when i hard-reset the board. Currently, I'm connecting my board to a wireless extender, because I am not sitting right next to the wifi router.
So basically my question would be what would be the problem causing the board to freeze? This piece of code below is my previous version, but the board freezes even quicker (around 3hours):
#include <EEPROM.h>
#include <ArduinoJson.h>
#include <UIPEthernet.h>
#define OUT0 2
#define OUT1 A3
#define OUT2 A2
#define OUT3 A1
#define OUT4 A0
#define OUT5 9
#define OUT6 8
#define OUT7 7
#define OUT8 6
#define OUT9 5
#define CS 10
// host name: "autolighting.afa-sports.com
// resource: "/api/iot/master-controller/get-command"
// mac: 46 57 5a 6b 48 51
// mac (char): FWZkHQ
#define HOSTNAME "autolighting.afa-sports.com"
#define ID_SIZE 6
byte mac[ID_SIZE];
const byte output[] PROGMEM = {OUT0, OUT1, OUT2, OUT3, OUT4, OUT5, OUT6, OUT7, OUT8, OUT9};
EthernetClient client;
StaticJsonDocument<40> filter;
StaticJsonDocument<120> doc;
void clientRead() {
filter.clear();
doc.clear();
filter["data"]["relay_actions"] = true;
deserializeJson(doc, client, DeserializationOption::Filter(filter));
client.flush();
if (!doc["data"]["relay_actions"].isNull()) {
for (byte i = 0; i < 10; i++) {
// Serial.print(doc["data"]["relay_actions"][i].as<bool>());
digitalWrite(pgm_read_byte_near(&output[i]), doc["data"]["relay_actions"][i].as<bool>());
}
}
}
void serialRead() {
Serial.println(F("ACK"));
unsigned long prevTime = millis() + 3000;
while (millis() < prevTime) {
while (Serial.available()) {
while (true) {
StaticJsonDocument<100> doc;
deserializeJson(doc, Serial);
if (doc["Read"] == true) {
// for (byte i = 0; i < 6; i++) doc["ID"].add(mac[i]);
// serializeJson(doc, Serial);
Serial.print(F("{\"ID\":["));
for (byte i = 0; i < ID_SIZE; i++) {
Serial.print(mac[i]);
if (i != ID_SIZE-1) Serial.print(F(","));
}
Serial.println(F("]}"));
}
else if (doc["SetID"] == true) {
// use atoi to convert char array to int
// then write to eeprom
memset(mac, 0, ID_SIZE);
for (byte i = 0; i < ID_SIZE; i++) mac[i] = doc["ID"][i].as<byte>();
for (byte i = 0; i < ID_SIZE; i++) EEPROM.write(i, 0);
for (byte i = 0; i < ID_SIZE; i++) EEPROM.write(i, mac[i]);
}
}
}
}
}
void connectToServer() {
if (!client.connect(HOSTNAME, 80)) {
Serial.println(F("Connection failed"));
return;
}
delay(100);
client.println(F("GET /api/iot/master-controller/get-command HTTP/1.1"));
client.println(F("Host: autolighting.afa-sports.com"));
client.println(F("DEVICE-ID: 46575a6b4851"));
client.println(F("Connection: close"));
client.println();
delay(500);
client.find("\r\n\r\n");
if (client.available()) clientRead();
if (!client.connected()) client.stop();
}
void setup() {
Serial.begin(115200);
for (byte i = 0; i < 10; i++) {
pinMode(pgm_read_byte_near(&output[i]), OUTPUT);
digitalWrite(pgm_read_byte_near(&output[i]), LOW);
}
for (uint8_t i = 0; i < ID_SIZE; i++) {
byte charByte = EEPROM.read(i);
if (charByte != 0) {
mac[i] = charByte;
}
}
serialRead();
Ethernet.init(CS);
while (!Ethernet.begin(mac)) {
Serial.println(F("Failed to configure Ethernet"));
}
client.setTimeout(10000);
delay(1000);
}
void loop() {
Ethernet.maintain();
connectToServer();
delay(2000);
}
I'm sorry if I missed out any important information. Your help is greatly appreciated. Thank you very much.