I'm experiencing a challenge with my Arduino OPTA board. I've been trying to build a simple web server to control LEDs and outputs, using some code examples from this forum.
However, I'm encountering a problem: each time I run the code, the RED LED above the RESET button on my OPTA starts blinking. This blinking LED seems to signal some kind of error, but I'm unable to pinpoint the exact issue. Here's what I've done so far:
Adapted web server example code from the forum for my project.
Made necessary modifications for controlling LEDs and outputs.
On execution, the RED LED begins to blink, and the setup doesn't work as expected.
Has anyone else experienced this blinking RED LED issue on the Arduino OPTA while running a web server or similar projects? How did you manage to resolve it?
I'm looking for any advice, troubleshooting tips, or relevant experiences that could help me understand and fix this problem.
with the help of SimpleWebServer example for Portenta H7 in Arduino Pro Tutorials and the help of ChatGPT, i managed to create a working code if case someone is interessted.
#include <Ethernet.h>
EthernetServer server(80);
const int ledPins[] = {LED_RELAY1, LED_RELAY2, LED_RELAY3, LED_RELAY4}; // Pins for LEDs LED_RELAY1 to LED_RELAY4
const int relayPins[] = {RELAY1, RELAY2, RELAY3, RELAY4}; // Pins for Relays RELAY1 to RELAY4
boolean ledStates[] = {LOW, LOW, LOW, LOW}; // Initial LED states
boolean relayStates[] = {LOW, LOW, LOW, LOW}; // Initial Relay states
void setup() {
Serial.begin(115200); // Initialize serial communication for debugging
for (int i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT);
pinMode(relayPins[i], OUTPUT);
digitalWrite(ledPins[i], ledStates[i]);
digitalWrite(relayPins[i], relayStates[i]);
}
Ethernet.begin();
server.begin();
Serial.print("IP: ");
Serial.println(Ethernet.localIP());
}
void loop() {
EthernetClient client = server.available();
if (client) {
serveWebpage(client);
}
}
void serveWebpage(EthernetClient client) {
String httpRequest = "";
// Read the entire HTTP request into a string
while (client.connected()) {
if (client.available()) {
char c = client.read();
httpRequest += c;
// Check for the end of the HTTP request
if (httpRequest.endsWith("\r\n\r\n")) {
break;
}
}
}
// Check for Relay and LED control requests
for (int i = 0; i < 4; i++) {
String ledOn = "GET /H" + String(i);
String ledOff = "GET /L" + String(i);
if (httpRequest.indexOf(ledOn) != -1) {
digitalWrite(relayPins[i], HIGH); // Turn on the Relay
digitalWrite(ledPins[i], HIGH); // Turn on the LED
ledStates[i] = HIGH;
relayStates[i] = HIGH;
} else if (httpRequest.indexOf(ledOff) != -1) {
digitalWrite(relayPins[i], LOW); // Turn off the Relay
digitalWrite(ledPins[i], LOW); // Turn off the LED
ledStates[i] = LOW;
relayStates[i] = LOW;
}
}
// Generate the HTML response
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("<html><body>");
client.println("<h1>Webserver LED Example</h1>");
client.println("<p>Use Edge or Safari Browser. Code seeme to hang when using Google Chrome Browser</p>");
// Define labels
String txtLabels[] = {"Relay1", "Relay2", "Relay3", "Relay4"};
// Generate buttons
for (int i = 0; i < 4; i++) {
client.println("<div style=\"display: flex; flex-direction: row; align-items: center;\">");
client.print("<h2 style=\"font-size: 24px;\">");
client.print(txtLabels[i]); // Display the label
client.println("</h2>");
// Add a green or red circle based on LED state
if (ledStates[i] == HIGH) {
client.println("<div style=\"width: 20px; height: 20px; background-color: green; border-radius: 50%; margin-left: 10px;\"></div>");
} else {
client.println("<div style=\"width: 20px; height: 20px; background-color: red; border-radius: 50%; margin-left: 10px;\"></div>");
}
client.println("</div>");
client.println("<div style=\"display: flex; flex-direction: row; align-items: center;\">");
client.println("<a href=\"/H");
client.print(i);
client.print("\" style=\"font-size: 20px;\">ON</a> <span style=\"margin-right: 10px;\"></span> <a href=\"/L");
client.print(i);
client.print("\" style=\"font-size: 20px;\">OFF</a>");
client.println("</div>");
}
client.println("</body></html>");
}
The only thing i noticed, it's working fine when using Safari browser on my ipad. When using Google Chrome on ipad, webpage refresh is pretty slow and often i get "Page could not be loaded". Any ideas?
Hi Muerzi,
I am working with Arduino Opta connected with an Ethernet cable. I have also installed a web server very similar as yours. And I have the same problem or at least I think so. When I access Opta with Firefox, it works fine. But when I try with Google Chrome, the flow control gets stuck when I close the connection ( inside "client.stop()") until the watchdog resets the Opta. I have no idea how to fix it.
After searching the web i found out, that the favicon (Image left of URL in adressbar) is causing that problem. Chrome is waitng for a favicon but arduino is not providing that.
if your html code provided by your OPTA looks like this, it will fix the issue:
I have also tried with this other line instead: client.println("<link rel='icon' href='http://google.com/favicon.ico' type='image/x-icon'>");
But the problem continues: when I try the server with Firefox, it works fine. But when I try with Google Chrome, the control gets stuck and the Opta ends up falling.
I keep looking at it. I need to fix it.
Try the following: Open Chrome, Press F12 on choose Network Tab, try to access webpage of your arduino and post the result from Debugconsole (include Waterfall diagram)
Hi Muerzi, and thanks again.
I have done it.
I have access the arduino webpage with this command: this.document.location = "http://192.168.1.177"
from the DebugConsole in Chrome.
Seems there is no errors under Chrome, but when I access like this, the Opta stops working.
I am trying to post the result as a image (don`t know if I am doing this well)
#include <Ethernet.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 177); // Comprobar que la IP esta vacante en tu red local
EthernetServer server(80);
EthernetClient clients[8];
bool ledLights = false;
void setup() {
delay (5000); // Just in case
Ethernet.begin(mac, ip);
Serial.begin(9600);
while (!Serial) ;
pinMode (LED_D0, OUTPUT);
digitalWrite (LED_D0, HIGH);
ledLights = true;
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1);
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
server.begin(); // start listening for clients
Serial.println ("**************************************");
Serial.println (Ethernet.localIP());
}
void loop() {
EthernetClient client = server.available();
if (client) {
Serial.println (""); Serial.println ("new client");
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
if (c == 'n' && currentLineIsBlank) {
// Answer the client
client.println ("HTTP/1.1 200 OK");
client.println ("Content-Type: text/html");
client.println("Connection: close");
client.println ();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<head><title>Hello world </title>");
client.print ("<link rel='icon' href='data:;base64,iVBORw0KGgo='>");
client.println("</head>");
client.println("<body>");
client.println("<h2>Hello world</h2>");
client.println("</body>");
client.println("</html>");
break;
}
if (c == 'n') {
currentLineIsBlank = true;
} else if (c != 'r') {
currentLineIsBlank = false;
}
}
}
delay(1);
client.stop(); // close conection
}
if (ledLights) {
digitalWrite (LED_D0, LOW);
ledLights = false;
} else {
digitalWrite (LED_D0, HIGH);
ledLights = true;
}
delay (100);
}
The OPTA is connected via Ethernet cable.
In summary, when I access the arduino website from Firefox it works fine, but when accessing with Chrome the OPTA blocks (the led stops blinking).
Again thank you for your help.
Hi,
I have been studding this issue. The behavior of Google Chrome is curious regarding how the html frame is constructed. Chrome usually makes 2 calls, the second asking for the favicon. Regarding to the head tag I have observed this:
If you write "Arduino web server " (with a blank after "server"), connection is blocked.
Chrome makes 2 calls, the second asking for the favicon. The second connection is blocked.
If you try this instead: client.println ("<link rel='google icon' href='http://google.com/favicon.ico' type='image/x-icon'>");
or this: client.println ("<link rel='world icon' href='data:,'>");
... the result is the same: 2 calls and the second one is blocked.
The simplest thing is to skip the favicon.ico . Chrome makes 2 calls but at least it doesn't it does not get stuck.
With firefox browser, none of these problems appear.
Since I need the main thread to run smoothly, I have prepared a new sketch putting the task that attends the web client inside a thread running in background:
#include <SPI.h>
#include <PortentaEthernet.h>
#include <Ethernet.h>
IPAddress ip(192, 168, 1, 180);
EthernetServer server(80);
static rtos::Thread *backgroundThread = NULL; // real time operating system
rtos::Thread::State threadState;
EthernetClient client;
unsigned long timeClient = 0;
bool led0 = false;
void setup() {
delay (5000);
Serial.begin(9600);
while (!Serial) {;}
Serial.println("Ethernet WebServer in a thread");
pinMode (LED_D0, OUTPUT);
digitalWrite (LED_D0, LOW);
led0 = false;
Ethernet.begin(ip);
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
// start the server
server.begin ();
Serial.print ("server is at ");
Serial.println (Ethernet.localIP());
}
void loop() {
EthernetLoop (); // listen for incoming clients
if (led0) {
digitalWrite (LED_D0, LOW);
led0 = false;
} else {
digitalWrite (LED_D0, HIGH);
led0 = true;
}
delay (100);
}
void EthernetLoop () {
if (backgroundThread != NULL) { // serving a client
if (millis() - timeClient > 5000) { // audit time
threadState = backgroundThread->get_state();
if (threadState != rtos::Thread::State::Deleted) { // kill the thread
backgroundThread->terminate();
delete backgroundThread; backgroundThread = NULL;
Serial.println ("Webserver blocked, kill the thread");
}
} else { // Still serving a client?
threadState = backgroundThread->get_state();
if (threadState == rtos::Thread::State::Deleted) {
delete backgroundThread; backgroundThread = NULL;
Serial.println ("The thread is over");
} else { // The thead is running and on time
Serial.print (".");
return;
}
}
}
// Available for new clients
client = server.available();
if (client) {
Serial.println ("Serving a client");
timeClient = millis();
backgroundThread = new rtos::Thread;
backgroundThread->start (Background);
}
}
void Background () {
Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
// google Chrome call the server twice (favicon)
client.println ("<head>");
client.println ("<title>Arduino web server</title>");
// client.println ("<link rel='icon' href='data:;base64,iVBORw0KGgo='>"); // Chrome makes 2 calls, the second blocked
// client.println ("<link rel='google icon' href='http://google.com/favicon.ico' type='image/x-icon'>"); // Chrome makes 2 calls, the second blocked
// client.println ("<link rel='world icon' href='data:,'>"); // Chrome makes 2 calls, the second blocked
client.println ("</head>");
client.println ("<body>");
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
int sensorReading = analogRead(analogChannel);
client.print("<h3>");
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(sensorReading);
client.println("</h3>");
}
client.println ("</body>");
client.println ("</html>");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
} else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
delay(1); // give the web browser time to receive the data
client.stop(); // close the connection:
Serial.println("client disconnected");
Serial.println ("Serving a client is over");
}
In this sketch the main loop only blinks the LED_0, but always with rhythm, regardless of the requests that the OPTA is attending to. If the web client gets stuck, the background thread will be deleted after 5 seconds. This sketch works fine for OPTA connected via Ethernet cable. I hope this solution helps others, I have wasted a lot of time analyzing this issue.