Obsługa HTTP POST przez Arduino

Prosty sposób na przetwarzanie formularza wysłanego metodą post z poziomu arduino.

Dlaczego?

Miałem trochę problemów z obsługą metody POST, praktycznie każdy projekt opiera się na metodzie GET. Dla mojego projektu krytyczne było użycie POST z dwóch powodów:

  • Walidacja ponownego przesłania danych (komunikat z potwierdzeniem)
  • Możliwość wysłania różnych kodów za pomocą pola INPUT

Opis projektu

Projekt ma robić bardzo prostą rzecz, a możliwe że będzie rozbudowany. Mianowicie jego zadaniem jest wciśniecie przycisku reset w serwerze w przypadku braku fizycznego dostępu.
Aby zabezpieczyć przed przypadkowym resetem (lub resetem w trakcie indeksowania przez roboty) dodałem pole input i walidację danych.

Jeżeli wpisany kod zgadza się z kodem zapisanym na sztywno w kontrolerze następuje uruchomienie przekaźnika.

Jak?

Poniżej kod umożliwiający obsługę Formularza HTML wysłanego metodą POST:
Używa biblioteki UIPEthernet dla kompatybilności z ENC28J60.

#include <UIPEthernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip( 19,135,197,202 );
IPAddress gateway( 19,135,197,193 );
IPAddress subnet( 255, 255, 255, 224 );
EthernetServer server(80);

const String code = "1234";
String Post;

void setup()
{
  Serial.begin(57600);
  pinMode(8, OUTPUT); //relay
  Ethernet.begin(mac, ip, dns, gateway, subnet);
  delay(2000);
  server.begin();

  Serial.println("setup finished");
}

void loop()
{
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      while (client.available()) {
        char c = client.read();
        if (c == '\n' && currentLineIsBlank) {
          // Obsługa HTTP POST - Pobranie danych
          while (client.available())
          {
            c = client.read();
            Post += c; 
          }
          // Analiza HTTP POST
          Serial.println(Post);
          Serial.println(Post.indexOf(code));
          if (Post.indexOf(code) > -1) {
            digitalWrite(8, HIGH);
            delay(1000);
            digitalWrite(8, LOW);
          }
          // Kasowanie Zmiennej POST i wysłanie danych do klienta
          Post=""; 
          client.println("HTTP/1.0 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<HTML><BODY>");
          client.println("<FORM METHOD=\"post\">");
          client.println("Access Code: <INPUT TYPE=\"TEXT\" NAME=\"Code\">");
          client.println("<INPUT TYPE=\"SUBMIT\" NAME=\"submit\">");
          client.println("</FORM>");
          client.stop();
        }
        else 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;
        }
      }
    }
    Serial.println("Disconnected");
  }
}

Problemy

Podczas testów pojawił się problem z zawieszaniem się arduino, prawdopodobnie jest to problem z portem ethernet. Zostało to rozwiązane przez zastosowanie watchdoga.

Komentarze

Prześlij komentarz