Arduino web server library.

aWOT Build Status

Arduino web server library.

Documentation

1. Getting started

2. Guide

3. API Reference

Compatibility

The aWOT web server library has been designed to work with all Arduino compatible development boards and networking options. This also means that switching the board or changing from WiFi to Ethernet will require minimal changes. The examples directory shows you how to use the library with the most popular Ethernet and WiFi libraries

However there are few subtle differences that need to be taken into account. Also unfortunately some of the WiFi and Ethernet libraries have bugs that prevent the library from working properly.

Previously the library has been tested with:

  • Adafruit Feather M0 WiFi
  • Arduino UNO + WIZnet W5100
  • Arduino Mega + WIZnet W5100
  • Arduino Due + WIZnet W5100
  • Arduino MKR WiFi 1010 (see notes)
  • Teensy 3.0 + WIZnet W5200
  • Teensy 4.1 Ethernet (see notes)
  • ESP32 + Wiznet W5500 Ethernet (see notes)
  • ESP32 + LAN8270 Ethernet
  • ESP32 WiFi
  • ESP8266 WiFi

ESP32 and ESP8266 WiFi

In both of the ESP Arduino cores the WiFiClient closes the connection automatically in the class destructor. This means that the client.stop(), does not need to be explicitly called but you will need to take extra steps if you want to keep the connection alive.

ESP32 + Wiznet W5500

The current version of the ESP32 Arduino core uses a non standard version of the Server class. Until the ESP32 core is fixed you need to manually modify the begin function in the Server.h if you want to use the Ethernet library that is shipped with the core.

Bug report: https://github.com/espressif/arduino-esp32/issues/2704

Teensy 4.1 + Ethernet

The Teensy 4.1 Ethernet library currently has a bug that causes the connection to stall and reset when connections to the server are opened in fast phase. The bug has been verified but not fixed yet.

Bug report: https://github.com/vjmuzik/NativeEthernet/issues/7

Arduino UNO

Because of the limited RAM and ROM Arduino UNO is on the edge of being usable for anything more complicated. If you want to use this library together with the SD card or any JSON parsing library, pay attention that you do not run out of memory.

Examples

Hello World

#include <WiFi.h>
#include <aWOT.h>

WiFiServer server(80);
Application app;

void index(Request &req, Response &res) {
  res.print("Hello World!");
}

void setup() {
  Serial.begin(115200);

  WiFi.begin("ssid", "password");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(WiFi.localIP());

  app.get("/", &index);
  server.begin();
}

void loop() {  
  WiFiClient client = server.available();

  if (client.connected()) {
    app.process(&client);
    client.stop();
  }
}

Query parameters

// HTTP GET /cats?type=lolcat
void queryParams(Request &req, Response &res) {
  char type[64];
  req.query("type", type, 64);

  res.print(type); // "lolcat"
}

void setup() {
  // other setup ...
  app.get("/cats", &queryParams);
}

Route paramaters

// HTTP GET /cats/lolcat
void routeParams(Request &req, Response &res) {
  char catId[64];
  req.route("catId", catId, 64);

  res.print(catId);
}

void setup() {
  // other setup
  app.get("/cats/:catId", &routeParams);
}

Post parameters

void postParams(Request &req, Response &res) {
  char name[10];
  char value[64];

  while (req.left()) {
    req.form(name, 10, value, 64);
    res.print(name);
    res.print(": ");
    res.println(value);
  }
}

void setup() {
  // other setup

  app.post("/form", &postParams);
}

Reading and writing headers

char userAgentBuffer[200];

// HTTP GET /headers
void headers(Request &req, Response &res) {
  char * userAgent = req.get("User-Agent"); // "Mozilla/5.0 (Macintosh; Inte ...."

  res.set("Cookie", "lolcat"); // will set Cookie header value to "lolcat"
  res.print(userAgent);
}

void setup() {
  // other setup

  // header names are handled case insensitive
  app.header("User-Agent", userAgentBuffer, 200); 
  app.get("/useragent", &headers);
}

Routers

Application app;
Router cats;

void looooong(Request &req, Response &res) {
  res.print("looooong cat is long!");
}

void ceiling(Request &req, Response &res) {
  res.print("ceiling cat is watching you debug!");
}

void nyannyan(Request &req, Response &res) {
  for (int i = 0; i < 100; i++) {
      res.print("nyan ");
  }
}

void setup() {
  // other setup

  cats.get("/long", &looooong);
  cats.get("/ceiling", &ceiling);
  cats.get("/nyan", &nyannyan);

  app.use("/cats", &cats);
}

Reducing memory usage

If you need to reduce the memory consumption add #define LOW_MEMORY_MCU before you import the library. This will reduce the size of a few internal buffers. Normally this is only used for the smallest AVR boards but it can be enabled for others if needed.

Also use the P macro to place any strings in to the program memory instead of wasting the precious RAM.

P(longString) = "Lots of text here...";
res.printP(longString);

Acknowledgements

Based on Webduino, Copyright 2009-2014 Ben Combee, Ran Talbott, Christopher Lee, Martin Lormes, Francisco M Cuenca-Acuna

Licence

MIT

Comments
  • Upload files from browser and store them into LittleFS/SPIFFS/SD

    Upload files from browser and store them into LittleFS/SPIFFS/SD

    Hello, I found this library very useful for working with ethernet and WiFi at the same time. I have been able to serve files from SD (using ESP32+ SDcard reader) to the browser using one of your examples, but due to my lack of knowledge about how library works and data flow, I don't understand how to send files from browser to be stored in the SD (or SPIFFS etc..).

    I think it can be done in a similar way as OTA update, but I can't get it :( Is there any example?

    Thank you in advance. /Davide

  • Question on Functionality Using ESP32 and W5500

    Question on Functionality Using ESP32 and W5500

    SETUP: The build I have utilizes a W5500 wiznet 850io board with an ESP32-Wrover-E. I am programming currently with the latest ESP-IDF plugin for Arduino.

    PLAN: I was able to use the Wifi, Ethernet, Webserver, and SPI libraries to connect an HTML based site either with, without, or concurrently with Ethernet and WiFi by using a processor function of sorts on the client class. I am using HTTP protocols to gain user inputs/outputs from the website locally. I would like to use the file system uploader plugin for ESP32 with littleFS or FatFS to serve the webpages and to store the values in-between other serial communication I am parsing.

    SITUATION: This led me to the asynchronous library where the server.on() functions make manipulating the HTTP/HTML items easy. My issue is that when I tried to utilize the W5500 with the asynchronous library, it wouldn't open the server. I assume this is related to the issues with W5500 bypassing its internal TCP/IP engine and having to run in MAC RAW mode to function.

    QUESTION: My question is then, does the AWOT library contain functionality that would allow me to use a file system with functionality similar to the asynchronous webserver functions that I could then parse and send elsewhere over serial communication, while still being able to use either Ethernet or WiFi connection--I don't need both simultaneously?

  • Feature Request / Documentation Question: Custom 404 page / Default Route

    Feature Request / Documentation Question: Custom 404 page / Default Route

    Hello,

    I was recently evaluating your library to replace our custom Arduino HTTP Server implementation. Of all the libraries examined so far, yours is definitely the most polished, and certainly has better routing capabilities than the nested if statements ours uses. Please do not take my suggestions as thinking your library is "bad."

    We would like to be able to serve custom fallback pages, and I can not find a method to do so. Does this ability exist? If this is not possible, it would be a much appreciated feature.

    These are the three use cases we currently have, and why I believe it is important:

    • A custom 404 page.
    • A generic reply to OPTIONS requests with all the "Access-Control-Allow-..." headers as permissible as possible.
    • (Low priority) A "Method Not Allowed" page for non GET requests that do not match a page that supports them.

    Proposed Solution

    I believe replacing/appending return m_response.sendStatus(404); in "Application::m_process()" with a check for a custom "Router::Middleware" would easily enable this function.

  • Awot crash on slow network with esp8266 + ethernet

    Awot crash on slow network with esp8266 + ethernet

    We are using ethernet on esp8266 deployed on congested network, we often see the esp8266 crashing and upon debugging it points to awot while statements of the library, so we decided adding yield on every while statements with the client.available() and it fixed the frequent crash. We have realized the solution since slow network could make the response wait for too long and since using a while(client.available) without yield inside would potentially trigger wdt resets.

  • Is there a way I can use static files located on a sd card instead of directly using them via a header?

    Is there a way I can use static files located on a sd card instead of directly using them via a header?

    The generated header file of the static file are taking a lot of place. I am wondering if I could use them via a sd card with something like the sd card library to serve my static files.

  • Member functions as Middleware*

    Member functions as Middleware*

    Do somebody ever tried to build a library over this server? Since "ESPAsyncWiFiManager" is not working over Ethernet, I am trying to build my library for a Webmanager which works over Ethernet, but I can´t figure out how to pass member functions of my EthWebManager class as middlewares.

    I am trying with std::bind, here is a code snippet:

    void EthWebManager::auth(Request &req, Response &res) { char * authHeader = req.get("Authorization");

    if (!str_iseq(authHeader, encoded_login1.c_str()) && !str_iseq(authHeader, encoded_login2.c_str())) { res.set("WWW-Authenticate", "Basic realm="Secret Area""); res.sendStatus(401); res.end(); DEBUG_WM(F("Unauthenticated")); } }

    void EthWebManager::handleRoot(Request &req, Response &res) { String page = FPSTR(WFM_HTTP_HEAD); page.replace("{v}", "Home"); page += FPSTR(HTTP_SCRIPT); page += FPSTR(HTTP_STYLE); page += FPSTR(HTTP_HEAD_END); page += F("

    EthWebManager

    "); page += FPSTR(HTTP_PORTAL_OPTIONS); page += FPSTR(HTTP_END); res.set("Content-Type", "text/html"); res.print(page); }

    void EthWebManager::startEthManager() { server->begin(); delay(500); mainapp.header("Authorization", authBuffer, 200); mainapp.use(std::bind(&EthWebManager::auth, this, std::placeholders::_1, std::placeholders::_2)); auto callable = std::bind(&EthWebManager::handleRoot, this, std::placeholders::_1, std::placeholders::_2); mainapp.get("/", callable ); }

    But I keep getting these errors:

    lib\EthWebManager\src\EthWebManager.cpp: In member function 'void EthWebManager::startEthManager()': lib\EthWebManager\src\EthWebManager.cpp:361:98: error: no matching function for call to 'awot::Application::use(std::_Bind_helper<false, void (EthWebManager::)(awot::Request&, awot::Response&), EthWebManager, const std::_Placeholder<1>&, const std::_Placeholder<2>&>::type)' mainapp.use(std::bind(&EthWebManager::auth, this, std::placeholders::_1, std::placeholders::_2)); ^ In file included from lib\EthWebManager\src\EthWebManager.h:22:0, from lib\EthWebManager\src\EthWebManager.cpp:14: .pio\libdeps\m5stack-core-esp32\aWOT\src/aWOT.h:322:8: note: candidate: void awot::Application::use(const char*, awot::Router*) void use(const char* path, Router* router); ^ .pio\libdeps\m5stack-core-esp32\aWOT\src/aWOT.h:322:8: note: candidate expects 2 arguments, 1 provided .pio\libdeps\m5stack-core-esp32\aWOT\src/aWOT.h:323:8: note: candidate: void awot::Application::use(awot::Router*) void use(Router* router); ^ .pio\libdeps\m5stack-core-esp32\aWOT\src/aWOT.h:323:8: note: no known conversion for argument 1 from 'std::_Bind_helper<false, void (EthWebManager::)(awot::Request&, awot::Response&), EthWebManager, const std::_Placeholder<1>&, const std::_Placeholder<2>&>::type {aka std::_Bind<std::_Mem_fn<void (EthWebManager::)(awot::Request&, awot::Response&)>(EthWebManager, std::_Placeholder<1>, std::_Placeholder<2>)>}' to 'awot::Router*' .pio\libdeps\m5stack-core-esp32\aWOT\src/aWOT.h:324:8: note: candidate: void awot::Application::use(const char*, void ()(awot::Request&, awot::Response&)) void use(const char path, Router::Middleware* middleware); ^ .pio\libdeps\m5stack-core-esp32\aWOT\src/aWOT.h:324:8: note: candidate expects 2 arguments, 1 provided .pio\libdeps\m5stack-core-esp32\aWOT\src/aWOT.h:325:8: note: candidate: void awot::Application::use(void ()(awot::Request&, awot::Response&)) void use(Router::Middleware middleware); ^ .pio\libdeps\m5stack-core-esp32\aWOT\src/aWOT.h:325:8: note: no known conversion for argument 1 from 'std::_Bind_helper<false, void (EthWebManager::)(awot::Request&, awot::Response&), EthWebManager, const std::_Placeholder<1>&, const std::_Placeholder<2>&>::type {aka std::_Bind<std::_Mem_fn<void (EthWebManager::)(awot::Request&, awot::Response&)>(EthWebManager, std::_Placeholder<1>, std::_Placeholder<2>)>}' to 'void ()(awot::Request&, awot::Response&)' lib\EthWebManager\src\EthWebManager.cpp:363:29: error: no matching function for call to 'awot::Application::get(const char [2], std::_Bind<std::_Mem_fn<void (EthWebManager::)(awot::Request&, awot::Response&)>(EthWebManager*, std::_Placeholder<1>, std::_Placeholder<2>)>&)' mainapp.get("/", callable ); /* ^ In file included from lib\EthWebManager\src\EthWebManager.h:22:0, from lib\EthWebManager\src\EthWebManager.cpp:14: .pio\libdeps\m5stack-core-esp32\aWOT\src/aWOT.h:300:8: note: candidate: void awot::Application::get(const char*, void ()(awot::Request&, awot::Response&)) void get(const char path, Router::Middleware* middleware); ^ .pio\libdeps\m5stack-core-esp32\aWOT\src/aWOT.h:300:8: note: no known conversion for argument 2 from 'std::_Bind<std::_Mem_fn<void (EthWebManager::)(awot::Request&, awot::Response&)>(EthWebManager, std::_Placeholder<1>, std::_Placeholder<2>)>' to 'void ()(awot::Request&, awot::Response&)'
    .pio\libdeps\m5stack-core-esp32\aWOT\src/aWOT.h:301:8: note: candidate: void awot::Application::get(void (
    )(awot::Request&, awot::Response&)) void get(Router::Middleware* middleware); ^ .pio\libdeps\m5stack-core-esp32\aWOT\src/aWOT.h:301:8: note: candidate expects 1 argument, 2 provided *** [.pio\build\m5stack-core-esp32\lib4c6\EthWebManager\EthWebManager.cpp.o] Error 1

  • (Low Priority) Feature Request: support AVR far pointers  in `Response::writeP`

    (Low Priority) Feature Request: support AVR far pointers in `Response::writeP`

    Hello,

    I was recently evaluating your library to replace our custom Arduino HTTP Server implementation. Of all the libraries examined so far, yours is definitely the most polished, and certainly has better routing capabilities than the nested if statements ours uses. Please do not take my suggestions as thinking your library is "bad."

    This is a very low priority issue, but may help others as well.

    Background

    The AVR platform uses 16 bit pointers. To get around this issue, on larger microcontrollers the memory is paged. When using PROGMEM, or __attribute__((section(".fini7"))), the resulting pointer is only valid within that page of memory! "avr/pgmspace.h" provides a handy pgm_get_far_address macro to convert the pointer to a 32 bit pointer, which solves that issue. However, it requires a different function than the usual pgm_read_byte.

    Requested Code

    We would be extremely appreciative if you would add an overload of Response::writeP(const uint_farptr_t data, size_t length) that uses pgm_read_byte_far.

    If you are interested, I should be able to submit a pull request to resolve this issue.

  • Feature Request / Bug On Some Platforms:  Reduce memory footprint by wrapping all C strings in `F(...)`

    Feature Request / Bug On Some Platforms: Reduce memory footprint by wrapping all C strings in `F(...)`

    Hello,

    I was recently evaluating your library to replace our custom Arduino HTTP Server implementation. Of all the libraries examined so far, yours is definitely the most polished, and certainly has better routing capabilities than the nested if statements ours uses. Please do not take my suggestions as thinking your library is "bad."

    In the process of evaluating your library, I noticed that it uses 1398 bytes of RAM. I believe this is because, despite importing "Arduino.h", the library uses raw C strings for everything. Those strings are always stored in RAM, just sitting there doing nothing but taking up space.

    This limits what devices the library can be run on, and/or the amount of data processing that is available when using this library.

    Suggested Fix

    #include <WString.h> and then use F(<HttpStatus_reasonPhrase>). An alternate approach for some code is to use this repository, with sleight modifications.

  • 400 Bad Request

    400 Bad Request

    Hi,

    Another question for you. On page request randomly it seems, the library returns :
    400 Bad Request

    If you simply refresh the browser after a short wait it works fine. There seems to be no reason to this that I can tell. It just works sometimes and not others. There is no need to reset MCU or change anything, just wait a while and the requested resource will load.

    I have tried increasing RAM buffers in the header file, but that didn't really help.

    Do you have any other troubleshooting steps, or ideas what might cause this?

    Thanks, Sokkou

  • Can't get setting value from web

    Can't get setting value from web

    I can't set the parameters to change on the web from your library, can you show me, thank you very much.

    #if defined(ESP8266) #include <ESP8266WiFi.h> #else #include <WiFi.h> #include <Update.h> #endif #include <aWOT.h>

    #define WIFI_SSID "" #define WIFI_PASSWORD ""

    WiFiServer server(80); Application app;

    char contentType[100] {}; bool shouldRestart = false;

    void index(Request &req, Response &res) { res.set("Content-Type", "text/html");

    res.println(""); res.println(""); res.println("

    "); res.println(""); res.println(""); res.println("
    "); res.println(" "); res.println(""); res.println(""); }

    void updateup(Request &req, Response &res) { char * type = req.get("Content-Type"); Serial.println(type); // this part, What do i have to do to get the value from web, thank you very much .

    }

    void setup() { Serial.begin(115200);

    WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(WiFi.localIP());

    app.header("Content-Type", contentType, 100); app.get("/", &index); app.post("/update", &updateup); server.begin(); }

    void loop() { WiFiClient client = server.available();

    if (client.connected()) { app.process(&client); client.stop(); } } image

  • Parse Multiple Query parameters of POST request

    Parse Multiple Query parameters of POST request

    Hi LAsse,

    Thanks one more time for this library! I am having an unexpected behaviour with the parametrized function request::query to parse the data sent from a POST form, is there any exemple on this? Shorly, I can´t get the function to find any of the parameters in the url.

    Here is the part of my code, with plenty of Serial.prints to figure out what´s going on:

    void EthWebManager::handle_save(Request &req, Response &res) { String page = FPSTR(HTTP_BEGIN); page.replace("{pageTitle}","Settings received"); page += FPSTR(SETTINGS_RECEIVED_BODY); page += FPSTR(FOOTER); page += FPSTR(REDIRECT_SCRIPT); page.replace("{timeoutS}","12"); page.replace("{timeoutms}","12000"); page.replace("{target}","/"); page += FPSTR(HTML_END); res.set("Content-Type", "text/html"); res.print(page); Serial.println(req.readString()); for (unsigned int i = 0; i < _paramsCount; i++) { Serial.print("Looking for par: "); Serial.print(_params[i]->getName()); Serial.print(", old val: "); Serial.println(_params[i]->_value); Serial.println(req.query(_params[i]->getName(), _params[i]->_value, _params[i]->getValueLength())); Serial.print("New val: "); Serial.println(_params[i]->_value); } }

    Here is the corresponding serial output: SensorReleaseTime=10&Freelights=%2300ff00&Busylights=%23ff0000&PulseDuration=15&BusyPulseRange=120&Freepulserange=40&EthIP=192.168.5.240&EthGateway=192.168.5.1&EthSubnet=255.255.255.0&EthDNS=8.8.8.8&Pod1Ch1MAC=4C%3A75%3A25%3AC3%3A06%3A18&Pod1Ch2MAC=4C%3A75%3A25%3AC1%3AB1%3A08&Pod2Ch1MAC=AC%3A0B%3AFB%3A6E%3AF3%3A1C&Pod2Ch2MAC=4C%3A75%3A25%3AC1%3A61%3AF8&Pod3Ch1MAC=4C%3A75%3A25%3AC4%3A1D%3A88&Pod3Ch2MAC=4C%3A75%3A25%3AC1%3A2A%3A48&Usr=user&Pas=password&submit= Looking for par: SensorReleaseTime, old val: 10 0 New val: Looking for par: Freelights, old val: #00ff00 0 New val: Looking for par: Busylights, old val: #ff0000 0 New val: Looking for par: PulseDuration, old val: 15 0 New val: Looking for par: BusyPulseRange, old val: 120 0 New val: Looking for par: Freepulserange, old val: 40 0 New val: Looking for par: EthIP, old val: 192.168.5.240 0 New val: Looking for par: EthGateway, old val: 192.168.5.1 0 New val: Looking for par: EthSubnet, old val: 255.255.255.0 0 New val: Looking for par: EthDNS, old val: 8.8.8.8 0 New val: Looking for par: Pod1Ch1MAC, old val: 4C:75:25:C3:06:18 0 New val: Looking for par: Pod1Ch2MAC, old val: 4C:75:25:C1:B1:08 0 New val: Looking for par: Pod2Ch1MAC, old val: AC:0B:FB:6E:F3:1C 0 New val: Looking for par: Pod2Ch2MAC, old val: 4C:75:25:C1:61:F8 0 New val: Looking for par: Pod3Ch1MAC, old val: 4C:75:25:C4:1D:88 0 New val: Looking for par: Pod3Ch2MAC, old val: 4C:75:25:C1:2A:48 0 New val: Looking for par: Usr, old val: user 0 New val: Looking for par: Pas, old val: password 0 New val:

    You can see the complete query and the names I am asking the function to look for.

    Digging deeper I had a look at the declaration of your query function, I can´t really understand how it works, but looks like it is never entering the while loop. I have modified it to add a serial output:

    bool Request::query(const char *name, char *buffer, int bufferLength) { memset(buffer, 0, bufferLength);

    char *position = m_query; int nameLength = strlen(name);

    while ((position = strstr(position, name))) { Serial.println("QueryWhileLooping"); char previous = *(position - 1);

    if ((previous == '\0' || previous == '&') &&
        *(position + nameLength) == '=') {
      position = position + nameLength + 1;
      while (*position && *position != '&' && --bufferLength) {
        *buffer++ = *position++;
      }
    
      return bufferLength > 0;
    }
    
    position++;
    

    } Serial.println("Query exited while loop"); return false; }

    And it seems to confirm my hypotesis....

    SensorReleaseTime=10&Freelights=%2300ff00&Busylights=%23ff0000&PulseDuration=15&BusyPulseRange=120&Freepulserange=40&EthIP=192.168.5.240&EthGateway=192.168.5.1&EthSubnet=255.255.255.0&EthDNS=8.8.8.8&Pod1Ch1MAC=4C%3A75%3A25%3AC3%3A06%3A18&Pod1Ch2MAC=4C%3A75%3A25%3AC1%3AB1%3A08&Pod2Ch1MAC=AC%3A0B%3AFB%3A6E%3AF3%3A1C&Pod2Ch2MAC=4C%3A75%3A25%3AC1%3A61%3AF8&Pod3Ch1MAC=4C%3A75%3A25%3AC4%3A1D%3A88&Pod3Ch2MAC=4C%3A75%3A25%3AC1%3A2A%3A48&Usr=user&Pas=password&submit= Looking for par: SensorReleaseTime, old val: 10 Query exited while loop 0 New val: Looking for par: Freelights, old val: #00ff00 Query exited while loop 0 New val: Looking for par: Busylights, old val: #ff0000 Query exited while loop 0 New val: Looking for par: PulseDuration, old val: 15 Query exited while loop 0 New val: Looking for par: BusyPulseRange, old val: 120 Query exited while loop 0 New val: Looking for par: Freepulserange, old val: 40 Query exited while loop 0 New val: Looking for par: EthIP, old val: 192.168.5.240 Query exited while loop 0 New val: Looking for par: EthGateway, old val: 192.168.5.1 Query exited while loop 0 New val: Looking for par: EthSubnet, old val: 255.255.255.0 Query exited while loop 0 New val: Looking for par: EthDNS, old val: 8.8.8.8 Query exited while loop 0 New val: Looking for par: Pod1Ch1MAC, old val: 4C:75:25:C3:06:18 Query exited while loop 0 New val: Looking for par: Pod1Ch2MAC, old val: 4C:75:25:C1:B1:08 Query exited while loop 0 New val: Looking for par: Pod2Ch1MAC, old val: AC:0B:FB:6E:F3:1C Query exited while loop 0 New val: Looking for par: Pod2Ch2MAC, old val: 4C:75:25:C1:61:F8 Query exited while loop 0 New val: Looking for par: Pod3Ch1MAC, old val: 4C:75:25:C4:1D:88 Query exited while loop 0 New val: Looking for par: Pod3Ch2MAC, old val: 4C:75:25:C1:2A:48 Query exited while loop 0 New val: Looking for par: Usr, old val: user Query exited while loop 0 New val: Looking for par: Pas, old val: password Query exited while loop 0 New val: Now manually BusyPulseRange: Query exited while loop 0

Frontend web application to control an arduino

Arduino Smart Blinds Frontend web application to control an arduino This project aims at created a frontent web page that communicates with an arduino

Jan 23, 2022
Arduino library for making an IHC in or output module using an Arduino

Introduction This is an Arduino library for making an IHC in or output module using an Arduino. (IHC controller is a home automation controller made b

Mar 26, 2020
ArduinoIoTCloud library is the central element of the firmware enabling certain Arduino boards to connect to the Arduino IoT Cloud

ArduinoIoTCloud What? The ArduinoIoTCloud library is the central element of the firmware enabling certain Arduino boards to connect to the Arduino IoT

Dec 16, 2022
Server side minimalistic HTTP protocol implementation for the Arduino platform.

ArduinoHttpServer Server side minimalistic Object Oriented HTTP protocol implementation for the Arduino platform. ArduinoHttpServer is a simple HTTP r

Oct 17, 2022
Simple web interface builder for esp8266 and ESP32
Simple web interface builder for esp8266 and ESP32

GyverPortal Простой конструктор веб интерфейса для esp8266 и ESP32 Простой конструктор - делаем страницы без знаний HTML и CSS Библиотека является обё

Jan 8, 2023
The Approximate Library is a WiFi Arduino library for building proximate interactions between your Internet of Things and the ESP8266 or ESP32
The Approximate Library is a WiFi Arduino library for building proximate interactions between your Internet of Things and the ESP8266 or ESP32

The Approximate Library The Approximate library is a WiFi Arduino Library for building proximate interactions between your Internet of Things and the

Dec 7, 2022
Arduino library for controlling the MCP2515 in order to receive/transmit CAN frames.
Arduino library for controlling the MCP2515 in order to receive/transmit CAN frames.

107-Arduino-MCP2515 Arduino library for controlling the MCP2515 in order to receive/transmit CAN frames. This library is prepared to interface easily

Nov 16, 2022
Arduino library for interfacing with any GPS, GLONASS, Galileo or GNSS module and interpreting its NMEA messages.
Arduino library for interfacing with any GPS, GLONASS, Galileo or GNSS module and interpreting its NMEA messages.

107-Arduino-NMEA-Parser Arduino library for interfacing with any GPS, GLONASS, Galileo or GNSS module and interpreting its NMEA messages. This library

Jan 1, 2023
Arduino library for providing a convenient C++ interface for accessing UAVCAN.
Arduino library for providing a convenient C++ interface for accessing UAVCAN.

107-Arduino-UAVCAN Arduino library for providing a convenient C++ interface for accessing UAVCAN (v1.0-beta) utilizing libcanard. This library works f

Jan 2, 2023
Arduino, esp32 and esp8266 library for ABB (ex PowerOne) Aurora Inverter, implement a full methods to retrieve data from the Inverter via RS-485
Arduino, esp32 and esp8266 library for ABB (ex PowerOne) Aurora Inverter, implement a full methods to retrieve data from the Inverter via RS-485

ABB Aurora protocol You can refer the complete documentation on my site ABB Aurora PV inverter library for Arduino, esp8266 and esp32 I create this li

Nov 22, 2022
Arduino library for the MCP2515 CAN Controller

MCP2515 CAN Controller Library for Arduino Compatibility with the ACAN library This library is fully compatible with the Teensy 3.x ACAN library https

Dec 18, 2022
CAN / CANFD Arduino Library for Teensy 4.0

CAN Library for Teensy 4.0 / 4.1 It handles Controller Area Network (CAN) for CAN1, CAN2 and CAN3, and Controller Area Network with Flexible Data (CAN

Dec 9, 2022
Analog Devices Analog Digital Converter AD7173 Arduino library

AD7173-Arduino Analog Devices AD7173 analog digital converter Arduino library Mostly tested setup for this library: 1007 data rate external crystal co

Nov 20, 2022
Arduino library for nRF51822-based Adafruit Bluefruit LE modules

This library is for all nRF51 based Adafruit Bluefruit LE modules that use SPI or UART. Current nRF51 based Bluefruit LE products include: Bluefruit L

Nov 6, 2022
Arduino library for the Adafruit FONA

Adafruit FONA Library This library requires Arduino v1.0.6 or higher This is a library for the Adafruit FONA Cellular GSM Breakouts etc Designed speci

Dec 15, 2022
Arduino library to access Adafruit IO from WiFi, cellular, and ethernet modules.
Arduino library to access Adafruit IO from WiFi, cellular, and ethernet modules.

Adafruit IO Arduino Library This library provides a simple device independent interface for interacting with Adafruit IO using Arduino. It allows you

Dec 23, 2022
Arduino library for MQTT support

Adafruit MQTT Library Arduino library for MQTT support, including access to Adafruit IO. Works with the Adafruit FONA, Arduino Yun, ESP8266 Arduino pl

Jan 6, 2023
Arduino library for SPI and I2C access to the PN532 RFID/Near Field Communication chip

Adafruit-PN532 This is a library for the Adafruit PN532 NFC/RFID breakout boards This library works with the Adafruit NFC breakout https://www.adafrui

Dec 23, 2022
Arduino library for the Si4714 FM+RDS Transmitter in the Adafruit shop
Arduino library for the Si4714 FM+RDS Transmitter in the Adafruit shop

Adafruit-Si4713-Library This is the Adafruit FM Transmitter with RDS/RBDS Breakout - Si4713 library Tested and works great with the Adafruit Si4713 Br

Oct 26, 2022