I.m trying to setup a simple webserver with about 20x2 buttons to switch 20 track changers (don't know the exact word for it) in a model railway. I used some code I found on internet and changed it to how I want it to work but it doesn't work like I want it (-; . It is not switching 1 but 2 pins. Can someone have a look at what I have been doing wrong? Thanks in advance... Also I can use some help on adding the code.
//zoomkat 8-04-12
//simple button GET server code to control servo and arduino pins 5, 6, 7 and 8
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use ' instead of " in the html
//address will look like http://192.168.177.250:80 when submited
//for use with W5100 based ethernet shields
///note that the below bug fix may be required
// http://code.google.com/p/arduino/issues/detail?id=605
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 177, 250 }; // ip in lan
EthernetServer server(80); //server port
String readString;
//////////////////////
void setup(){
pinMode(5, OUTPUT); //pin selected to control
pinMode(6, OUTPUT); //pin selected to control
pinMode(7, OUTPUT); //pin selected to control
pinMode(8, OUTPUT); //pin selected to control
pinMode(22, OUTPUT); //pin selected to control
pinMode(23, OUTPUT); //pin selected to control
pinMode(24, OUTPUT); //pin selected to control
pinMode(25, OUTPUT); //pin selected to control
//start Ethernet
Ethernet.begin(mac, ip);
server.begin();
//enable serial data print
Serial.begin(9600);
Serial.println("server multi pin button test 1.0"); // so I can keep track of what is loaded
}
void loop(){
// Create a client connection
EthernetClient client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();
//read char by char HTTP request
if (readString.length() < 100) {
//store characters to string
readString += c;
//Serial.print(c);
}
//if HTTP request has ended
if (c == '\n') {
///////////////
Serial.println(readString); //print to serial monitor for debuging
client.println("HTTP/1.1 200 OK"); //send new page
client.println("Content-Type: text/html");
client.println();
client.println("<HTML>");
client.println("<HEAD>");
client.println("<TITLE>Wisselschakelaarpagina</TITLE>");
client.println("</HEAD>");
client.println("<BODY>");
//client.println("<H1>Zoomkat's simple Arduino button</H1>");
// For simple testing, pin 5, 6, 7, and 8 are used in buttons
// DIY buttons
client.println("<p></p>");
client.println("<a href=/?on2 >W 1 rechtuit</a>");
client.println("<a href=/?on4 >W 1 afslaan</a>");
//client.println("<p>Wissel 2</p>");
client.println("<a href=/?on6 >W 2 rechtuit</a>");
client.println("<a href=/?on8 >W 2 afslaan</a>");
//client.println("<p></p>");
client.println("<a href=/?on10 >W 3 rechtuit</a>");
client.println("<a href=/?on12 >W 3 afslaan</a>");
//client.println("<p></p>");
client.println("<a href=/?on14 >W 4 rechtuit</a>");
client.println("<a href=/?on16 >W 4 afslaan</a>");
client.println("</BODY>");
client.println("</HTML>");
delay(1);
//stopping client
client.stop();
///////////////////// control arduino pin
if(readString.indexOf('2') >0)//checks for 2
{
digitalWrite(5, HIGH); // set pin 5 high
Serial.println("Led 5 On");
delay(500);
digitalWrite(5,LOW);
}
if(readString.indexOf('4') >0)//checks for 4
{
digitalWrite(6, HIGH); // set pin 6 high
Serial.println("Led 6 On");
delay(500);
digitalWrite(6,LOW);
}
if(readString.indexOf('6') >0)//checks for 6
{
digitalWrite(7, HIGH); // set pin 7 high
Serial.println("Led 7 On");
delay(500);
digitalWrite(7,LOW);
}
if(readString.indexOf('8') >0)//checks for 8
{
digitalWrite(8, HIGH); // set pin 8 high
Serial.println("Led 8 On");
delay(500);
digitalWrite(8,LOW);
}
if(readString.indexOf('10') >0)//checks for 10
{
digitalWrite(22, HIGH); // set pin 5 high
Serial.println("Led 22 On");
delay(500);
digitalWrite(22,LOW);
}
if(readString.indexOf('12') >0)//checks for 12
{
digitalWrite(23, HIGH); // set pin 6 high
Serial.println("Led 23 On");
delay(500);
digitalWrite(23,LOW);
}
if(readString.indexOf('14') >0)//checks for 14
{
digitalWrite(24, HIGH); // set pin 7 high
Serial.println("Led 24 On");
delay(500);
digitalWrite(24,LOW);
}
if(readString.indexOf('16') >0)//checks for 16
{
digitalWrite(25, HIGH); // set pin 8 high
Serial.println("Led 25 On");
delay(500);
digitalWrite(25,LOW);
}
//clearing string for next read
readString="";
}
}
}
}
}
//zoomkat 8-04-12
//simple button GET server code to control servo and arduino pins 5, 6, 7 and 8
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use ' instead of " in the html
//address will look like http://192.168.177.250:80 when submited
//for use with W5100 based ethernet shields
///note that the below bug fix may be required
// http://code.google.com/p/arduino/issues/detail?id=605
#include <SPI.h>
#include <Ethernet.h>
const byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
const byte ip[] = { 192, 168, 177, 250 }; // ip in lan
EthernetServer server(80); //server port
String readString = "";
const byte Pages = 8;
const byte PageToPins[Pages][2] = {
2, 5,
4, 6,
6, 7,
8, 8,
10, 22,
12, 23,
14, 24,
16, 25
};
//////////////////////
void setup() {
pinMode(5, OUTPUT); //pin selected to control
pinMode(6, OUTPUT); //pin selected to control
pinMode(7, OUTPUT); //pin selected to control
pinMode(8, OUTPUT); //pin selected to control
pinMode(22, OUTPUT); //pin selected to control
pinMode(23, OUTPUT); //pin selected to control
pinMode(24, OUTPUT); //pin selected to control
pinMode(25, OUTPUT); //pin selected to control
//start Ethernet
Ethernet.begin(mac, ip);
server.begin();
//enable serial data print
Serial.begin(9600);
Serial.println("server multi pin button test 1.0"); // so I can keep track of what is loaded
}
void loop() {
// Create a client connection
EthernetClient client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();
//read char by char HTTP request
if (readString.length() < 100) {
//store characters to string
readString += c;
//Serial.print(c);
}
//if HTTP request has ended
if (c == '\n') {
///////////////
Serial.println(readString); //print to serial monitor for debuging
client.println("HTTP/1.1 200 OK"); //send new page
client.println("Content-Type: text/html");
client.println();
client.println("<HTML>");
client.println("<HEAD>");
client.println("<TITLE>Wisselschakelaarpagina</TITLE>");
client.println("</HEAD>");
client.println("<BODY>");
//client.println("<H1>Zoomkat's simple Arduino button</H1>");
// For simple testing, pin 5, 6, 7, and 8 are used in buttons
// DIY buttons
client.println("<p></p>");
client.println("<a href=/?on2 >W 1 rechtuit</a>");
client.println("<a href=/?on4 >W 1 afslaan</a>");
//client.println("<p>Wissel 2</p>");
client.println("<a href=/?on6 >W 2 rechtuit</a>");
client.println("<a href=/?on8 >W 2 afslaan</a>");
//client.println("<p></p>");
client.println("<a href=/?on10 >W 3 rechtuit</a>");
client.println("<a href=/?on12 >W 3 afslaan</a>");
//client.println("<p></p>");
client.println("<a href=/?on14 >W 4 rechtuit</a>");
client.println("<a href=/?on16 >W 4 afslaan</a>");
client.println("</BODY>");
client.println("</HTML>");
delay(1);
//stopping client
client.stop();
///////////////////// control arduino pin
for (byte i = 0; i < Pages; i++) {
if (readString.indexOf((String)PageToPins[i][0]) > 0) {
digitalWrite(PageToPins[i][1], HIGH);
Serial.print("LedOn ");
Serial.println(PageToPins[i][1]);
delay(500);
digitalWrite(PageToPins[i][1], LOW);
}
}
readString = ""; //clearing string for next read
}
}
}
}
}
Given that "readString" contains an entire HTTP request, extracting the switch id from it is not exactly trivial but something like this might do (put this directly after "client.stop()"):
int firstLineEnd = readString.indexOf("\n");
if (firstLineEnd <= 0) {
firstLineEnd = readString.length();
}
// readString will look like this: "GET /?on2"
string pointsId = readString.substr(8, firstLineEnd);
Then, change all the "if" conditions from that point on to look like this:
if (pointsId == "2") {
instead of this:
if (readString.indexOf('2') > 0) {
(Code is untested, may have off-by-one errors)
Also, please just ignore kolaha's code, I am pretty certain it'll show the exact same bug as your current code does.)
Thanks for your effort! I added the adjusted code according to your message. I get the following error:
Arduino:1.8.13 (Windows 10), Board:"Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
C:\Users\Ernie\Documents\Arduino\hopelijk-simpeler\hopelijk-simpeler.ino: In function 'void loop()':
hopelijk-simpeler:101:39: error: 'class String' has no member named 'substr'; did you mean 'c_str'?
String pointsId = readString.substr(8, firstLineEnd);
^~~~~~
c_str
exit status 1
'class String' has no member named 'substr'; did you mean 'c_str'?
The other code of Kaloha was giving the same errors as my original code however adjusting and tweaking it a bit gave me 10 pins I could use. (But I want 40 (-; )
Dit rapport zou meer informatie bevatten met
"Uitgebreide uitvoer weergeven tijden compilatie"
optie aan in Bestand -> Voorkeuren.
Checking the serial output when clicking on the first button of the webpage gives an: GET /?on2 HTTP/1.1 etc.etc . Unfortunately no Leds are working now but the problem with the substring is solved. Looks like the Arduino doesn't respond or receive the code correctly.
Right, I assumed that the first line of the request would just be "GET /?on2". Usually I have at least some kind of parser between me and raw HTTP requests so I don't know off the top of my head how to "manually" parse them.
Try this on for size:
// readString will look like this: "GET /?on2 HTTP/1.1"
int endOfUrl = readString.indexOf("HTTP") - 1;
string pointsId = readString.substr(8, endOfUrl);
(What this code is doing - or at least what it is supposed to do - is just extract the switch/points number from the HTTP request.)
I suppose you can, as long as your Arduino has at least 40 output pins. This code should work as long as all your URLs (in the <a href=...> tags) are formatted as /onXXX, with XXX being any number (letters probably also would work).
the 8 tells the substring function to ignore the first 8 characters of "readString". So, if your HTTP request looks like GET /?on17 HTTP/1.1, it just ignores everything before the 17. If you change those URLs, you also need to change the substring call's parameters to match it.
You may also want to use an array or map to define which switch corresponds to which I/O pin, so you don't duplicate the same code over and over again, but that's an advanced topic.