Hi, I am a beginner to Arduino of a few months. Apologies this is long, but I want to be specific as searches haven't helped.
Board:
Arduino Mega 2560
Shield:
Ethernet-Shield 2 (with SD Card)
Software:
Visual Studio - PlatformIO
Project:
I have made a circuit that is ten RGB 8x8 LED modules, all controlled via shift registers. And I have them working on a Mega 2560 via buttons (without the Eth-Shield 2 as a proof of concept project).
But now, I wish to control each module's colour and text to be displayed, via my browser. So, I got an Eth-Shield 2 and have been working on examples (WebServer) to get a feel for how the MCU and shield operate. As well as looking through the forum and doing google searches to get a web page (at least) looking and functioning how I like.
I use the SD Card on the Eth-Shield 2 to load the web page.
At this stage, I am not incorporating the RGB 8x8 ten-module circuit. I just want to prove to myself that a web page, hosted by the Mega, can send data to it, without the Mega reloading the entire web page (that is, keeping user entered data on the page intact). Later, when I get that working, I will incorporate the RGB 8x8 ten-module circuit.
Project overview, thus far:
First Part: I am using POST method to send a form with the colour-data to the Arduino Mega, when checkboxes are checked (having ten RGB 8x8 modules, I am sending a lot of data to the Mega, so I chose POST over GET). Each module has a red, green and blue checkbox, so, thirty checkboxes (Three checkboxes in ten forms). On the web page, when any selection of the three checkboxes per module are checked, or unchecked, javascript alters the hex-colour of a representation of the module (see/run the html code below).
Second Part: I have an input field with 'type='text', where the text part to be displayed on the RGB 8x8 ten-modules can be entered. At this stage, I have not tried sending this to the Arduino Mega. I am working upon the colour checkboxes first.
Issue with First Part:
When I check a checkbox, sending the form via POST to the Mega, the code I have reloads the entire page, erasing the check of the most recent checkbox, which I don't want to happen. I would just like to check a checkbox without the page reloading, losing the data entered.
Question:
In my code, how can I differentiate between loading the whole page, and 'pushing' new data selections (clicking a checkbox) to the Arduino Mega without the entire page reloading and loosing all the user data on the page?
Arduino Code:
#include <Arduino.h>
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xA8, 0x61, 0x0A, 0xAE, 0x6E, 0xA2 };
IPAddress ip( 192, 168, 1, 177 );
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
// File for loading web page from SD Card
File webFile;
// File to hold data transfered from PC browser (copied from Arduino Forum)
char new_state[1024];
// Configure all the things here
void setup()
{
// LEDs
pinMode(40, OUTPUT); // Blue Indication LED
pinMode(2, OUTPUT); // White Clear LED
pinMode(3, OUTPUT); // Red LED
pinMode(4, OUTPUT); // Yellow LED
pinMode(5, OUTPUT); // Orange LED
pinMode(6, OUTPUT); // Orange Clear LED
pinMode(7, OUTPUT); // Green LED
pinMode(8, OUTPUT); // Blue LED
pinMode(9, OUTPUT); // Blue Clear LED
// Test all LEDs
digitalWrite(40, HIGH);
delay(1000);
digitalWrite(40, LOW);
delay(1000);
digitalWrite(40, HIGH);
delay(1000);
digitalWrite(40, LOW);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
delay(1000);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
// Get Serial Monitor stuff up and running
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("Begin: RGB Shift Register Board WebServer POST method");
// (From Webserver example) You can use Ethernet.init(pin) to configure the CS pin
// (In some Forum and internet examples this is not here, and everything still works)
Ethernet.init(10); // Most Arduino shields
// Start the Ethernet server:
Ethernet.begin(mac, ip);
// Start the server
server.begin();
Serial.print("Serving at ");
Serial.println(Ethernet.localIP());
// Initialize the SD Card
Serial.println("Initializing SD card....");
if (!SD.begin(4)) {
Serial.println("ERROR!! - SD Card initialization failed!");
return;
}
Serial.println("SUCCESS!! - SD Card has been initialized.");
//check for index.htm file
if (!SD.exists("index1.htm")) {
Serial.println("ERROR!! - SD Card file: Can't find 'index1.htm' file!!");
return;
}
Serial.println("SUCCESS!! - Found 'index1.htm' file.");
}
// Where the web page HTML files are loaded from SD Card (Whole Page to send to browser)
void sendPage(EthernetClient client)
{
// Send a standard http response header
client.println("HTTP/1.0 200 OK\Content-Type: text/html\n\n");
// Send the rest of the page, read from SD Card
webFile = SD.open("index1.htm");
if (webFile) {
while (webFile.available()) {
client.write(webFile.read());
}
webFile.close();
}
client.stop();
}
// Main program loop
void loop()
{
// Listen for incoming clients
EthernetClient client = server.available();
if (client) {
while (client.connected()) {
int i = 0;
int head = 1;
int body = 0;
while(client.available()) {
char c = client.read();
if (c == '\n') {
if ( i <= 2 ) {
// An http request ends with a blank line
sendPage(client);
if ( head == 1 ) {
body = 1;
head = 0;
}
}
i = -1;
}
if ( body == 1 ) {
new_state[i] = c;
}
i++;
new_state[i] = '\0';
}
i = 0;
}
// While mucking around with code (before final code to use in project), see what comes back on the FORM (via POST method)
Serial.println(new_state);
// Parse whatever comes back here; Name and Value (looks like this; M10R=on).
// 'Name' (M10R) determines which local variable in this code to focus upon.
// 'Value' (on) is the value to update the local variable.
// If I had "var Module_10_Red = 0;", then here, 'M10R=on' would see variable 'Module_10_Red = 0xFF;'
}
}
HTML code (loaded into SD Card, as 'Index1.htm'):
<HTML>
<HEAD>
<LINK rel='icon' href='data:;base64,iVBORw0KGgo='>
<TITLE>
-~{Mega & EthShield2}~-
</TITLE>
<STYLE type='text/css'>
BODY {
background-color:#4F0445;
color:White;}
</STYLE>
</HEAD>
<BODY>
<H1 style='text-align:center'>Welcome to my Mega & Ethernet Shield 2 WebServer example muck-around with code! :D</H1>
<TABLE bgcolor=Black align=center border=1 width='1500' style='font-size:20px; font-familyterminal;'>
<TR style='height:40px'>
<TH colspan='10' style='font-size:30px'>RGB 8x8 (Shift Register) Colours</TH>
</TR>
<TR>
<TH id='dM10' style='Color:#808080'>Mod-10</TH>
<TH id='dM09' style='Color:#808080'>Mod-09</TH>
<TH id='dM08' style='Color:#808080'>Mod-08</TH>
<TH id='dM07' style='Color:#808080'>Mod-07</TH>
<TH id='dM06' style='Color:#808080'>Mod-06</TH>
<TH id='dM05' style='Color:#808080'>Mod-05</TH>
<TH id='dM04' style='Color:#808080'>Mod-04</TH>
<TH id='dM03' style='Color:#808080'>Mod-03</TH>
<TH id='dM02' style='Color:#808080'>Mod-02</TH>
<TH id='dM01' style='Color:#808080'>Mod-01</TH>
</TR>
<TR align=center style='height:100px'>
<TD>
<FORM method='POST' action='/' id='M10'>
<LABEL for='rM10' style='color:RED'>RED</LABEL>
<INPUT type='checkbox' id='rM10' name='M10R' onclick='change("M10")'></INPUT><br>
<LABEL for='gM10' style='color:GREEN'>GREEN</LABEL>
<INPUT type='checkbox' id='gM10' name='M10G' onclick='change("M10")'></INPUT><br>
<LABEL for='bM10' style='color:BLUE'>BLUE</LABEL>
<INPUT type='checkbox' id='bM10' name='M10B' onclick='change("M10")'></INPUT><br>
</FORM>
</TD>
<TD>
<FORM method='POST' action='/' id='M09'>
<LABEL for='rM09' style='color:RED'>RED</LABEL>
<INPUT type='checkbox' id='rM09' name='M09R' onclick='change("M09")'></INPUT><br>
<LABEL for='gM09' style='color:GREEN'>GREEN</LABEL>
<INPUT type='checkbox' id='gM09' name='M09G' onclick='change("M09")'></INPUT><br>
<LABEL for='bM09' style='color:BLUE'>BLUE</LABEL>
<INPUT type='checkbox' id='bM09' name='M09B' onclick='change("M09")'></INPUT><br>
</FORM>
</TD>
<TD>
<FORM method='POST' action='/' id='M08'>
<LABEL for='rM08' style='color:RED'>RED</LABEL>
<INPUT type='checkbox' id='rM08' name='M08R' onclick='change("M08")'></INPUT><br>
<LABEL for='gM08' style='color:GREEN'>GREEN</LABEL>
<INPUT type='checkbox' id='gM08' name='M08G' onclick='change("M08")'></INPUT><br>
<LABEL for='bM08' style='color:BLUE'>BLUE</LABEL>
<INPUT type='checkbox' id='bM08' name='M08B' onclick='change("M08")'></INPUT><br>
</FORM>
</TD>
<TD>
<FORM method='POST' action='/' id='M07'>
<LABEL for='rM07' style='color:RED'>RED</LABEL>
<INPUT type='checkbox' id='rM07' name='M07R' onclick='change("M07")'></INPUT><br>
<LABEL for='gM07' style='color:GREEN'>GREEN</LABEL>
<INPUT type='checkbox' id='gM07' name='M07G' onclick='change("M07")'></INPUT><br>
<LABEL for='bM07' style='color:BLUE'>BLUE</LABEL>
<INPUT type='checkbox' id='bM07' name='M07B' onclick='change("M07")'></INPUT><br>
</FORM>
</TD>
<TD>
<FORM method='POST' action='/' id='M06'>
<LABEL for='rM06' style='color:RED'>RED</LABEL>
<INPUT type='checkbox' id='rM06' name='M06R' onclick='change("M06")'></INPUT><br>
<LABEL for='gM06' style='color:GREEN'>GREEN</LABEL>
<INPUT type='checkbox' id='gM06' name='M06G' onclick='change("M06")'></INPUT><br>
<LABEL for='bM06' style='color:BLUE'>BLUE</LABEL>
<INPUT type='checkbox' id='bM06' name='M06B' onclick='change("M06")'></INPUT><br>
</FORM>
</TD>
<TD>
<FORM method='POST' action='/' id='M05'>
<LABEL for='rM05' style='color:RED'>RED</LABEL>
<INPUT type='checkbox' id='rM05' name='M05R' onclick='change("M05")'></INPUT><br>
<LABEL for='gM05' style='color:GREEN'>GREEN</LABEL>
<INPUT type='checkbox' id='gM05' name='M05G' onclick='change("M05")'></INPUT><br>
<LABEL for='bM05' style='color:BLUE'>BLUE</LABEL>
<INPUT type='checkbox' id='bM05' name='M05B' onclick='change("M05")'></INPUT><br>
</FORM>
</TD>
<TD>
<FORM method='POST' action='/' id='M04'>
<LABEL for='rM04' style='color:RED'>RED</LABEL>
<INPUT type='checkbox' id='rM04' name='M04R' onclick='change("M04")'></INPUT><br>
<LABEL for='gM04' style='color:GREEN'>GREEN</LABEL>
<INPUT type='checkbox' id='gM04' name='M04G' onclick='change("M04")'></INPUT><br>
<LABEL for='bM04' style='color:BLUE'>BLUE</LABEL>
<INPUT type='checkbox' id='bM04' name='M04B' onclick='change("M04")'></INPUT><br>
</FORM>
</TD>
<TD>
<FORM method='POST' action='/' id='M03'>
<LABEL for='rM03' style='color:RED'>RED</LABEL>
<INPUT type='checkbox' id='rM03' name='M03R' onclick='change("M03")'></INPUT><br>
<LABEL for='gM03' style='color:GREEN'>GREEN</LABEL>
<INPUT type='checkbox' id='gM03' name='M03G' onclick='change("M03")'></INPUT><br>
<LABEL for='bM03' style='color:BLUE'>BLUE</LABEL>
<INPUT type='checkbox' id='bM03' name='M03B' onclick='change("M03")'></INPUT><br>
</FORM>
</TD>
<TD>
<FORM method='POST' action='/' id='M02'>
<LABEL for='rM02' style='color:RED'>RED</LABEL>
<INPUT type='checkbox' id='rM02' name='M02R' onclick='change("M02")'></INPUT><br>
<LABEL for='gM02' style='color:GREEN'>GREEN</LABEL>
<INPUT type='checkbox' id='gM02' name='M02G' onclick='change("M02")'></INPUT><br>
<LABEL for='bM02' style='color:BLUE'>BLUE</LABEL>
<INPUT type='checkbox' id='bM02' name='M02B' onclick='change("M02")'></INPUT><br>
</FORM>
</TD>
<TD>
<FORM method='POST' action='/' id='M01'>
<LABEL for='rM01' style='color:RED'>RED</LABEL>
<INPUT type='checkbox' id='rM01' name='M01R' onclick='change("M01")'></INPUT><br>
<LABEL for='gM01' style='color:GREEN'>GREEN</LABEL>
<INPUT type='checkbox' id='gM01' name='M01G' onclick='change("M01")'></INPUT><br>
<LABEL for='bM01' style='color:BLUE'>BLUE</LABEL>
<INPUT type='checkbox' id='bM01' name='M01B' onclick='change("M01")'></INPUT><br>
</FORM>
</TD>
</TR>
<TR align=center style='height:70px'>
<TH colspan='10'><br>
Note: If the above module-display is 'grey' (and the colour checkboxes are all unchecked), and there is a 'space' or no text in the below text-field,<br>
then the actual RGB 8x8 Matrix associated module will have no LEDs lit.<br><br>
If text appears in the text-field below, and the associated module-display colour selection above is 'grey' (and the colour checkboxes are all unchecked),<br>
then the 'old colour value' or 'default colour value' for that character(s) on the RGB 8x8 Matrix will apply.<br><br>
(Make sure for the colour selection to work, there's text in the text-field below, before sending it.)<br><br>
</TH>
</TR>
</TABLE><BR><BR>
<TABLE bgcolor=Black align=center border=1 width='1500' style='font-size:20px; font-familyterminal;'>
<FORM method='POST' action='/' id='TXT'>
<TR style='height:40px'>
<TH colspan='4' align=center style='font-size:30px'>RGB 8x8 (Shift Register) Text</TH>
</TR>
<TR style='height:60px'>
<TD colspan='4' align=center>
<LABEL for='TextInput' style='font-size:25px'>Input Text:</LABEL>
<INPUT type='text' id='TextInput' name='RGBtxt' maxlength='10' size='10' style='background-color:Black; color:grey; height:30px; font-size:25px; text-align:center'><br>
</TD>
</TR>
</FORM>
</TABLE><BR><BR>
</FORM>
</BODY>
<SCRIPT>
var M10rgb = 0;
var M09rgb = 0;
var M08rgb = 0;
var M07rgb = 0;
var M06rgb = 0;
var M05rgb = 0;
var M04rgb = 0;
var M03rgb = 0;
var M02rgb = 0;
var M01rgb = 0;
var Mtext = 0;
function change(title) {
var aa = 0;
var bb = 0;
var cc = 0;
var dd = 0;
var valR = 0;
var valG = 0;
var valB = 0;
var r_hex = 0;
var g_hex = 0;
var b_hex = 0;
var hex = 0;
switch(title) {
case 'M10':
aa = 'rM10';
bb = 'gM10';
cc = 'bM10';
dd = 'dM10';
break;
case 'M09':
aa = 'rM09';
bb = 'gM09';
cc = 'bM09';
dd = 'dM09';
break;
case 'M08':
aa = 'rM08';
bb = 'gM08';
cc = 'bM08';
dd = 'dM08';
break;
case 'M07':
aa = 'rM07';
bb = 'gM07';
cc = 'bM07';
dd = 'dM07';
break;
case 'M06':
aa = 'rM06';
bb = 'gM06';
cc = 'bM06';
dd = 'dM06';
break;
case 'M05':
aa = 'rM05';
bb = 'gM05';
cc = 'bM05';
dd = 'dM05';
break;
case 'M04':
aa = 'rM04';
bb = 'gM04';
cc = 'bM04';
dd = 'dM04';
break;
case 'M03':
aa = 'rM03';
bb = 'gM03';
cc = 'bM03';
dd = 'dM03';
break;
case 'M02':
aa = 'rM02';
bb = 'gM02';
cc = 'bM02';
dd = 'dM02';
break;
case 'M01':
aa = 'rM01';
bb = 'gM01';
cc = 'bM01';
dd = 'dM01';
break;
};
if (document.getElementById(aa).checked) {
valR = 255;
} else {
valR = 0;
};
if (document.getElementById(bb).checked) {
valG = 255;
} else {
valG = 0;
};
if (document.getElementById(cc).checked) {
valB = 255;
} else {
valB = 0;
};
r_hex = parseInt(valR, 10).toString(16);
g_hex = parseInt(valG, 10).toString(16);
b_hex = parseInt(valB, 10).toString(16);
hex = '#' + pad(r_hex) + pad(g_hex) + pad(b_hex);
if (hex == '#000000') {
document.getElementById(dd).style.color = '#808080';
} else {
document.getElementById(dd).style.color = hex;
};
document.getElementById(title).submit();
};
function pad(n){
return (n.length<2) ? '0'+n : n;
};
</SCRIPT>
</HTML>
Thank you for any help