Das sieht sehr vielversprechend aus.
Doch wie komme ich da hin?
Die ZIP-Datei, die du aufgelegt hast, ist unverändert die gleiche, wie auf deiner Homepage.
Ist das so gedacht?
Adafruit_MCP23X17 mcp[noOfMcp]; //
Compiler akzeptiert „MCP23X17“ nicht, nur MCP23017
Habe versucht deine Ideen umzusetzen, aber leider ohne Erfolg. Trotzdem vielen Dank noiasca. Vielleicht hat jemand Lust diese Herausforderung anzunehmen. Dazu habe ich den Sketch ein Stück weit vorbereitet und mit zusätzlichen Infos versehen. Da ich als Neueinsteiger keine Dateien hochladen darf, hier der Sketch in zwei Teilen:
/* *******************************************************************
A simple Arduino ethernet web server.
- https://werner.rothschopf.net/202001_arduino_webserver_post.htm
- MCP23017 Hardware ist eingebunden und funktioniert siehe dazu
- in void loop() "Test-LED" (Ausgang A1)
- Verwende Adafruit MCP23017 Arduino Library V 2.3.0
- A0, A1, A2 = GND → Adresse 0x20
- RESET = VCC
- Problem: Einbindung im sever in Zeile 132 "for (auto &pin : ???){}" wie???
* *************************************************************** */
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include <INTERVAL.h>
#include <Adafruit_MCP23017.h>
Adafruit_MCP23017 mcp; // Create MCP
byte mac[] {0x52, 0x64, 0x75, 0x69, 0x6E, 0x6F}; // you can change the MAC and IP addresses to suit your network
IPAddress ip(1, 1, 17, 12);
EthernetServer server(80); // Port 80 is HTTP port
const byte ledPin[] {2, 3, 5, 6, 7, 8, 9, A0, A1}; // define the LED pins - im sever Zeile 132 for (auto &pin : ledPin){} eingebunden
const uint8_t addr = 0; // Adresse 0x20 / 0 // Einbindung im sever in Zeile 132 for (auto &pin : ???){} wie???
void printHardwareInfo()
{
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println(F("Ethernet shield was not found"));
}
else if (Ethernet.hardwareStatus() == EthernetW5100) {
Serial.println(F("W5100 detected"));
}
else
{
if (Ethernet.hardwareStatus() == EthernetW5200) {
Serial.println(F("W5200 detected"));
}
else if (Ethernet.hardwareStatus() == EthernetW5500) {
Serial.println(F("W5500 detected"));
}
if (Ethernet.linkStatus() == Unknown) { // cable connection
Serial.println(F("Link status detection is only available with W5200 and W5500"));
}
else if (Ethernet.linkStatus() == LinkON) {
Serial.println(F("Link status: On"));
}
else if (Ethernet.linkStatus() == LinkOFF) {
Serial.println(F("Link status: Off"));
}
}
}
void setup()
{
Serial.begin(115200);
Serial.println(F("\nsimple webserver"));
for (auto &pin : ledPin) {
pinMode(pin, OUTPUT); // Set the digital pins ready to write to
}
mcp.begin(addr); // Start MCP
for (byte i=0; i<16; i++)
mcp.pinMode(i, OUTPUT);
for (byte i=0; i<16; i++)
mcp.digitalWrite(i, HIGH);
Ethernet.begin(mac, ip); // Start the Ethernet shield
printHardwareInfo();
server.begin(); // Start the webserver
Serial.print(F("server available at http://"));
Serial.println(Ethernet.localIP());
}
void loop()
{
// listen for incoming clients
checkForClient();
// Test-LED
INTERVAL(1000UL)
mcp.digitalWrite(1, LOW); // LED an A1 "AN"
INTERVAL(3000UL)
mcp.digitalWrite(1, HIGH); // LED an A1 "AUS"
////// alternativ /////
/*
mcp.digitalWrite(1, LOW); // LED an A1 "AN"
delay(3000);
mcp.digitalWrite(1, HIGH); // LED an A1 "AUS"
delay(1000);
*/
}
Teil 2 (server)
/* *******************************************************************
Webserver
***************************************************************** */
void checkForClient()
{
EthernetClient client = server.available();
if (client) {
Serial.println(F("\n[server] client connected"));
uint8_t i = 0; // index / current read position
const uint16_t buffersize = 100; // size of read buffer (reads a complete line) (if larger than 255, modify i also!
const uint16_t smallbuffersize = 30; // a smaller buffer for results
char lineBuffer[buffersize] {'\0'}; // buffer for incomming data
char method[8]; // largest one 7+1. HTTP request methods in RFC7231 + RFC5789: GET HEAD POST PUT DELETE CONNECT OPTONS TRACE PATCH
char uri[smallbuffersize]; // the requestet page, shorter than smallbuffersize - method
char requestParameter[smallbuffersize]; // parameter appended to the URI after a ?
char postParameter[smallbuffersize]; // parameter transmitted in the body / by POST
enum class Status {REQUEST, CONTENT_LENGTH, EMPTY_LINE, BODY};
Status status = Status::REQUEST;
while (client.connected()) {
while (client.available()) {
char c = client.read();
Serial.print(c); // Debug print received characters to Serial monitor
if ( c == '\n' )
{
if (status == Status::REQUEST) // read the first line
{
//Serial.print(F("lineBuffer="));Serial.println(lineBuffer);
// now split the input
char *ptr;
ptr = strtok(lineBuffer, " "); // strtok willdestroy the newRequest
strlcpy(method, ptr, smallbuffersize);
Serial.print(F("method=")); Serial.println(method);
ptr = strtok(NULL, " ");
strlcpy(uri, ptr, smallbuffersize); // enthält noch evtl. parameter
if (strchr(uri, '?') != NULL)
{
ptr = strtok(uri, "?"); // split URI from parameters
strcpy(uri, ptr);
ptr = strtok(NULL, " ");
strcpy(requestParameter, ptr);
Serial.print(F("requestParameter=")); Serial.println(requestParameter);
}
Serial.print(F("uri=")); Serial.println(uri);
status = Status::EMPTY_LINE; // jump to next status
}
else if (status == Status::CONTENT_LENGTH) // MISSING check for Content-Length
{
status = Status::EMPTY_LINE;
}
else if (status > Status::REQUEST && i < 2) // check if we have an empty line
{
status = Status::BODY;
}
else if (status == Status::BODY)
{
strlcpy(postParameter, lineBuffer, smallbuffersize);
break; // we have received one line payload and break out
}
i = 0;
strcpy(lineBuffer, "");
}
else
{
if (i < buffersize)
{
lineBuffer[i] = c;
i++;
lineBuffer[i] = '\0';
}
// MISSING wenn status 3 und content-length --> abbrechen.
}
}
if (status == Status::BODY) // status 3 could end without linefeed, therefore we takeover here also
{
strlcpy(postParameter, lineBuffer, smallbuffersize);
}
Serial.println(); // start new line at the end of the browser input
Serial.print(F("postParameter=")); Serial.println(postParameter);
// more advanced evaluation of postParameter from body
// post data looks like pinD2=On but number could have one, two or even three digits
if ( strncmp( postParameter, "pinD", 4) == 0 ) { // check the first 4 characters (= length of needle)
byte pin = atoi(postParameter + 4); // Convert ASCII to byte from position 4 onwards
//Serial.print(("pin=")); Serial.println(pin);
const char * ptr = strchr(postParameter, '='); // get a pointer to the first occurance of '='
if (ptr != NULL) // only continue when postParameter contains '='
{
size_t pos = ptr - postParameter +1; // calculate from the pointer adress to the absolute position within postParameter
if ( strncmp( postParameter + pos, "On", 2) == 0 ) {
digitalWrite(pin, 1);
}
else if ( strncmp( postParameter + pos, "Off", 3) == 0 ) {
digitalWrite(pin, 0);
}
}
}
// send back a response
if (!strcmp(uri, "/") || !strcmp(uri, "/index.htm") ) // the homepage
sendPage(client);
else if (!strcmp(uri, "/favicon.ico")) // a favicon
send204(client); // if you don't have a favicon, send 204
else // if the page is unknown, HTTP response code 404
send404(client);
delay(1);
client.stop();
}
}
}
void sendPage(EthernetClient & client)
{
// Serial.println("[server] 200 response send");
client.println( "HTTP/1.0 200 OK\r\n" // \r\n Header Fields are terminated by a carriage return (CR) and line feed (LF) character sequence
"Content-Type: text/html\r\n" // The media type of the body of the request (used with POST and PUT requests)
"\r\n" // a blank line to split HTTP header and HTTP body
"<!doctype html>\n" // the start of the HTTP Body - contains the HTML
"<html lang='en'>\n"
"<head>\n"
"<meta charset='utf-8'>\n"
"<meta name='viewport' content='width=device-width'>\n"
"<title>Webserver as pin controller</title>\n"
"</head>\n"
"<body style='font-family:Helvetica, sans-serif'>\n" // a minimum style to avoid serifs
"<h1>Webserver as pin controller</h1>\n"
"<p>Buttons turn pins on or off</p>\n"
"<form method='post' action='/' name='pins'>");
for (auto &pin : ledPin)
{
client.print(pin);
client.print(" <input name='pinD");
client.print(pin);
client.print("' type='submit' value='On'>");
client.print("<input name='pinD");
client.print(pin);
client.print("' type='submit' value='Off'>");
if (digitalRead(pin)) client.print(F(" active"));
client.print("<br>\n");
}
client.print("</form>\n");
// add any other data here before the end of the document
client.print("</body>\n</html>");
client.stop();
}
void send404(EthernetClient & client)
{
// Serial.println("[server] response 404 file not found");
client.println("HTTP/1.0 404 Not Found\r\n"
"Content-Type: text/plain\r\n" // simple plain text without html tags
"\r\n"
"File Fot Found");
}
void send204(EthernetClient & client)
{
// Serial.println("[server] response 204 no content");
client.println("HTTP/1.0 204 no content\r\n"); // no content
}