PicoLighter Wifi Test
commit
eb17418214
@ -0,0 +1,5 @@
|
|||||||
|
.pio
|
||||||
|
.vscode/.browse.c_cpp.db*
|
||||||
|
.vscode/c_cpp_properties.json
|
||||||
|
.vscode/launch.json
|
||||||
|
.vscode/ipch
|
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||||
|
// for the documentation about the extensions.json format
|
||||||
|
"recommendations": [
|
||||||
|
"platformio.platformio-ide"
|
||||||
|
],
|
||||||
|
"unwantedRecommendations": [
|
||||||
|
"ms-vscode.cpptools-extension-pack"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"array": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"list": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"ranges": "cpp"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
# TODO List
|
||||||
|
|
||||||
|
1. Add basic HTML web UI to pass xLights check (strip data, pins, basic color picker ...)
|
||||||
|
2. Add support for other protocols (not super important, because everyone uses E1.31)
|
||||||
|
3. Control software or master node - Switch between software (LedFX vs xLights, OpenRGB, etc), basic lighting controls
|
||||||
|
4. Determine when to run FastLED.show() - on E1.31 sync? does all software support that? does this lib support that?
|
||||||
|
5. Test with real lights
|
||||||
|
6. Optocoupler vs level shifter
|
||||||
|
7. Design miniRIB PCB
|
||||||
|
8. Pick 24V PSU, enclosure, 24V strip choice
|
||||||
|
9. Placement - alu profiles, diffusers (13-20mm), heat sinking
|
||||||
|
10. Waterproofing - connectors
|
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
This directory is intended for project header files.
|
||||||
|
|
||||||
|
A header file is a file containing C declarations and macro definitions
|
||||||
|
to be shared between several project source files. You request the use of a
|
||||||
|
header file in your project source file (C, C++, etc) located in `src` folder
|
||||||
|
by including it, with the C preprocessing directive `#include'.
|
||||||
|
|
||||||
|
```src/main.c
|
||||||
|
|
||||||
|
#include "header.h"
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Including a header file produces the same results as copying the header file
|
||||||
|
into each source file that needs it. Such copying would be time-consuming
|
||||||
|
and error-prone. With a header file, the related declarations appear
|
||||||
|
in only one place. If they need to be changed, they can be changed in one
|
||||||
|
place, and programs that include the header file will automatically use the
|
||||||
|
new version when next recompiled. The header file eliminates the labor of
|
||||||
|
finding and changing all the copies as well as the risk that a failure to
|
||||||
|
find one copy will result in inconsistencies within a program.
|
||||||
|
|
||||||
|
In C, the usual convention is to give header files names that end with `.h'.
|
||||||
|
It is most portable to use only letters, digits, dashes, and underscores in
|
||||||
|
header file names, and at most one dot.
|
||||||
|
|
||||||
|
Read more about using header files in official GCC documentation:
|
||||||
|
|
||||||
|
* Include Syntax
|
||||||
|
* Include Operation
|
||||||
|
* Once-Only Headers
|
||||||
|
* Computed Includes
|
||||||
|
|
||||||
|
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
This directory is intended for project specific (private) libraries.
|
||||||
|
PlatformIO will compile them to static libraries and link into executable file.
|
||||||
|
|
||||||
|
The source code of each library should be placed in a an own separate directory
|
||||||
|
("lib/your_library_name/[here are source files]").
|
||||||
|
|
||||||
|
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||||
|
|
||||||
|
|--lib
|
||||||
|
| |
|
||||||
|
| |--Bar
|
||||||
|
| | |--docs
|
||||||
|
| | |--examples
|
||||||
|
| | |--src
|
||||||
|
| | |- Bar.c
|
||||||
|
| | |- Bar.h
|
||||||
|
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||||
|
| |
|
||||||
|
| |--Foo
|
||||||
|
| | |- Foo.c
|
||||||
|
| | |- Foo.h
|
||||||
|
| |
|
||||||
|
| |- README --> THIS FILE
|
||||||
|
|
|
||||||
|
|- platformio.ini
|
||||||
|
|--src
|
||||||
|
|- main.c
|
||||||
|
|
||||||
|
and a contents of `src/main.c`:
|
||||||
|
```
|
||||||
|
#include <Foo.h>
|
||||||
|
#include <Bar.h>
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
PlatformIO Library Dependency Finder will find automatically dependent
|
||||||
|
libraries scanning project source files.
|
||||||
|
|
||||||
|
More information about PlatformIO Library Dependency Finder
|
||||||
|
- https://docs.platformio.org/page/librarymanager/ldf.html
|
@ -0,0 +1,22 @@
|
|||||||
|
; PlatformIO Project Configuration File
|
||||||
|
;
|
||||||
|
; Build options: build flags, source filter
|
||||||
|
; Upload options: custom upload port, speed and extra flags
|
||||||
|
; Library options: dependencies, extra library storages
|
||||||
|
; Advanced options: extra scripting
|
||||||
|
;
|
||||||
|
; Please visit documentation for the other options and examples
|
||||||
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
|
[env:pico]
|
||||||
|
board = rpipicow
|
||||||
|
framework = arduino
|
||||||
|
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||||
|
board_build.core = earlephilhower
|
||||||
|
upload_port = /run/media/amelia/RPI-RP2/
|
||||||
|
monitor_speed = 115200
|
||||||
|
board_build.filesystem_size = 1m
|
||||||
|
board_build.f_cpu = 133000000L
|
||||||
|
board_flags = -DWIFICC=CYW43_COUNTRY_USA
|
||||||
|
lib_deps =
|
||||||
|
fastled/FastLED@^3.6.0
|
@ -0,0 +1,275 @@
|
|||||||
|
/*
|
||||||
|
* e131.cpp
|
||||||
|
*
|
||||||
|
* Project: E131 - E.131 (sACN) library for Arduino
|
||||||
|
* Copyright (c) 2015 Shelby Merrick
|
||||||
|
* http://www.forkineye.com
|
||||||
|
*
|
||||||
|
* This program is provided free for you to use in any way that you wish,
|
||||||
|
* subject to the laws and regulations where you are using it. Due diligence
|
||||||
|
* is strongly suggested before using this code. Please give credit where due.
|
||||||
|
*
|
||||||
|
* The Author makes no warranty of any kind, express or implied, with regard
|
||||||
|
* to this program or the documentation contained in this document. The
|
||||||
|
* Author shall not be liable in any event for incidental or consequential
|
||||||
|
* damages in connection with, or arising out of, the furnishing, performance
|
||||||
|
* or use of these programs.
|
||||||
|
*
|
||||||
|
* Modified to work on RP2040 by Amelia Deck
|
||||||
|
* This version will not run anymore on ESP32 due to changes to the includes.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "e131.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* E1.17 ACN Packet Identifier */
|
||||||
|
#ifdef ARDUINO_ARCH_AVR
|
||||||
|
const PROGMEM byte E131::ACN_ID[12] = { 0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 };
|
||||||
|
#else
|
||||||
|
const byte E131::ACN_ID[12] = { 0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Constructor */
|
||||||
|
E131::E131() {
|
||||||
|
#ifdef NO_DOUBLE_BUFFER
|
||||||
|
memset(pbuff1.raw, 0, sizeof(pbuff1.raw));
|
||||||
|
packet = &pbuff1;
|
||||||
|
pwbuff = packet;
|
||||||
|
#else
|
||||||
|
memset(pbuff1.raw, 0, sizeof(pbuff1.raw));
|
||||||
|
memset(pbuff2.raw, 0, sizeof(pbuff2.raw));
|
||||||
|
packet = &pbuff1;
|
||||||
|
pwbuff = &pbuff2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
stats.num_packets = 0;
|
||||||
|
stats.packet_errors = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void E131::initUnicast() {
|
||||||
|
delay(100);
|
||||||
|
udp.begin(E131_DEFAULT_PORT);
|
||||||
|
if (Serial) {
|
||||||
|
Serial.print(F("- Unicast port: "));
|
||||||
|
Serial.println(E131_DEFAULT_PORT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void E131::initMulticast(uint16_t universe, uint8_t n) {
|
||||||
|
delay(100);
|
||||||
|
IPAddress address = IPAddress(239, 255, ((universe >> 8) & 0xff),
|
||||||
|
((universe >> 0) & 0xff));
|
||||||
|
#ifdef INT_ESP8266
|
||||||
|
ip_addr_t ifaddr;
|
||||||
|
ip_addr_t multicast_addr;
|
||||||
|
|
||||||
|
ifaddr.addr = static_cast<uint32_t>(WiFi.localIP());
|
||||||
|
for (uint8_t i = 1; i < n; i++) {
|
||||||
|
multicast_addr.addr = static_cast<uint32_t>(IPAddress(239, 255,
|
||||||
|
(((universe + i) >> 8) & 0xff), (((universe + i) >> 0)
|
||||||
|
& 0xff)));
|
||||||
|
igmp_joingroup(&ifaddr, &multicast_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
udp.beginMulticast(WiFi.localIP(), address, E131_DEFAULT_PORT);
|
||||||
|
#endif
|
||||||
|
if (Serial) {
|
||||||
|
Serial.println(F("- Multicast Enabled"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****** START - Wireless ifdef block ******/
|
||||||
|
#if defined (INT_ESP8266) || defined (INT_WIFI)
|
||||||
|
|
||||||
|
/* WiFi Initialization */
|
||||||
|
int E131::initWiFi(const char *ssid, const char *passphrase) {
|
||||||
|
/* Switch to station mode and disconnect just in case */
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.disconnect();
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
if (Serial) {
|
||||||
|
Serial.println("");
|
||||||
|
Serial.print(F("Connecting to "));
|
||||||
|
Serial.print(ssid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (passphrase != NULL)
|
||||||
|
WiFi.begin(ssid, passphrase);
|
||||||
|
else
|
||||||
|
WiFi.begin(ssid);
|
||||||
|
|
||||||
|
uint32_t timeout = millis();
|
||||||
|
uint8_t retval = 1;
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(250);
|
||||||
|
if (Serial)
|
||||||
|
Serial.print(".");
|
||||||
|
if (millis() - timeout > WIFI_CONNECT_TIMEOUT) {
|
||||||
|
retval = 0;
|
||||||
|
if (Serial) {
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println(F("*** Failed to connect ***"));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void E131::begin(e131_listen_t type, uint16_t universe, uint8_t n) {
|
||||||
|
if (type == E131_UNICAST)
|
||||||
|
initUnicast();
|
||||||
|
if (type == E131_MULTICAST)
|
||||||
|
initMulticast(universe, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
int E131::begin(const char *ssid, const char *passphrase) {
|
||||||
|
if (initWiFi(ssid, passphrase)) {
|
||||||
|
if (Serial) {
|
||||||
|
Serial.println("");
|
||||||
|
Serial.print(F("Connected DHCP with IP: "));
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
}
|
||||||
|
initUnicast();
|
||||||
|
}
|
||||||
|
return WiFi.status();
|
||||||
|
}
|
||||||
|
|
||||||
|
int E131::begin(const char *ssid, const char *passphrase,
|
||||||
|
IPAddress ip, IPAddress netmask, IPAddress gateway, IPAddress dns) {
|
||||||
|
if (initWiFi(ssid, passphrase)) {
|
||||||
|
WiFi.config(ip, gateway, netmask, dns);
|
||||||
|
if (Serial) {
|
||||||
|
Serial.println("");
|
||||||
|
Serial.print(F("Connected with Static IP: "));
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
}
|
||||||
|
initUnicast();
|
||||||
|
}
|
||||||
|
return WiFi.status();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/****** END - Wireless ifdef block ******/
|
||||||
|
|
||||||
|
/****** START - ESP8266 ifdef block ******/
|
||||||
|
#if defined (INT_ESP8266)
|
||||||
|
int E131::beginMulticast(const char *ssid, const char *passphrase,
|
||||||
|
uint16_t universe, uint8_t n) {
|
||||||
|
if (initWiFi(ssid, passphrase)) {
|
||||||
|
if (Serial) {
|
||||||
|
Serial.println("");
|
||||||
|
Serial.print(F("Connected DHCP with IP: "));
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
}
|
||||||
|
initMulticast(universe, n);
|
||||||
|
}
|
||||||
|
return WiFi.status();
|
||||||
|
}
|
||||||
|
|
||||||
|
int E131::beginMulticast(const char *ssid, const char *passphrase,
|
||||||
|
uint16_t universe, IPAddress ip, IPAddress netmask,
|
||||||
|
IPAddress gateway, IPAddress dns, uint8_t n) {
|
||||||
|
if (initWiFi(ssid, passphrase)) {
|
||||||
|
WiFi.config(ip, dns, gateway, netmask);
|
||||||
|
if (Serial) {
|
||||||
|
Serial.println("");
|
||||||
|
Serial.print(F("Connected with Static IP: "));
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
}
|
||||||
|
initMulticast(universe, n);
|
||||||
|
}
|
||||||
|
return WiFi.status();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/****** END - ESP8266 ifdef block ******/
|
||||||
|
|
||||||
|
/****** START - Ethernet ifdef block ******/
|
||||||
|
#if defined (INT_ETHERNET)
|
||||||
|
|
||||||
|
/* Unicast Ethernet Initializers */
|
||||||
|
int E131::begin(uint8_t *mac) {
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
if (Serial) {
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println(F("Requesting Address via DHCP"));
|
||||||
|
Serial.print(F("- MAC: "));
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
Serial.print(mac[i], HEX);
|
||||||
|
Serial.println("");
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = Ethernet.begin(mac);
|
||||||
|
|
||||||
|
if (Serial) {
|
||||||
|
if (retval) {
|
||||||
|
Serial.print(F("- IP Address: "));
|
||||||
|
Serial.println(Ethernet.localIP());
|
||||||
|
} else {
|
||||||
|
Serial.println(F("** DHCP FAILED"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retval)
|
||||||
|
initUnicast();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void E131::begin(uint8_t *mac, IPAddress ip, IPAddress netmask,
|
||||||
|
IPAddress gateway, IPAddress dns) {
|
||||||
|
Ethernet.begin(mac, ip, dns, gateway, netmask);
|
||||||
|
if (Serial) {
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println(F("Static Configuration"));
|
||||||
|
Serial.println(F("- MAC: "));
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
Serial.print(mac[i], HEX);
|
||||||
|
Serial.print(F("- IP Address: "));
|
||||||
|
Serial.println(Ethernet.localIP());
|
||||||
|
}
|
||||||
|
|
||||||
|
initUnicast();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Multicast Ethernet Initializers */
|
||||||
|
int E131::beginMulticast(uint8_t *mac, uint16_t universe, uint8_t n) {
|
||||||
|
//TODO: Add ethernet multicast support
|
||||||
|
}
|
||||||
|
|
||||||
|
void E131::beginMulticast(uint8_t *mac, uint16_t universe,
|
||||||
|
IPAddress ip, IPAddress netmask, IPAddress gateway,
|
||||||
|
IPAddress dns, uint8_t n) {
|
||||||
|
//TODO: Add ethernet multicast support
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/****** END - Ethernet ifdef block ******/
|
||||||
|
|
||||||
|
void E131::dumpError(e131_error_t error) {
|
||||||
|
switch (error) {
|
||||||
|
case ERROR_ACN_ID:
|
||||||
|
Serial.print(F("INVALID PACKET ID: "));
|
||||||
|
for (int i = 0; i < sizeof(ACN_ID); i++)
|
||||||
|
Serial.print(pwbuff->acn_id[i], HEX);
|
||||||
|
Serial.println("");
|
||||||
|
break;
|
||||||
|
case ERROR_PACKET_SIZE:
|
||||||
|
Serial.println(F("INVALID PACKET SIZE: "));
|
||||||
|
break;
|
||||||
|
case ERROR_VECTOR_ROOT:
|
||||||
|
Serial.print(F("INVALID ROOT VECTOR: 0x"));
|
||||||
|
Serial.println(htonl(pwbuff->root_vector), HEX);
|
||||||
|
break;
|
||||||
|
case ERROR_VECTOR_FRAME:
|
||||||
|
Serial.print(F("INVALID FRAME VECTOR: 0x"));
|
||||||
|
Serial.println(htonl(pwbuff->frame_vector), HEX);
|
||||||
|
break;
|
||||||
|
case ERROR_VECTOR_DMP:
|
||||||
|
Serial.print(F("INVALID DMP VECTOR: 0x"));
|
||||||
|
Serial.println(pwbuff->dmp_vector, HEX);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,249 @@
|
|||||||
|
/*
|
||||||
|
* e131.h
|
||||||
|
*
|
||||||
|
* Project: E131 - E.131 (sACN) library for Arduino
|
||||||
|
* Copyright (c) 2015 Shelby Merrick
|
||||||
|
* http://www.forkineye.com
|
||||||
|
*
|
||||||
|
* This program is provided free for you to use in any way that you wish,
|
||||||
|
* subject to the laws and regulations where you are using it. Due diligence
|
||||||
|
* is strongly suggested before using this code. Please give credit where due.
|
||||||
|
*
|
||||||
|
* The Author makes no warranty of any kind, express or implied, with regard
|
||||||
|
* to this program or the documentation contained in this document. The
|
||||||
|
* Author shall not be liable in any event for incidental or consequential
|
||||||
|
* damages in connection with, or arising out of, the furnishing, performance
|
||||||
|
* or use of these programs.
|
||||||
|
*
|
||||||
|
* Modified to work on RP2040 by Amelia Deck
|
||||||
|
* This version will not run anymore on ESP32 due to changes to the includes.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef E131_H_
|
||||||
|
#define E131_H_
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
/* Network interface detection. WiFi for ESP8266 and Ethernet for AVR */
|
||||||
|
# include <WiFi.h>
|
||||||
|
//# include <WiFiMulti.h>
|
||||||
|
//# include <WiFiUdp.h>
|
||||||
|
# include <lwip/ip_addr.h>
|
||||||
|
# include <lwip/igmp.h>
|
||||||
|
# define _UDP WiFiUDP
|
||||||
|
# define INT_WIFI
|
||||||
|
|
||||||
|
#define NO_DOUBLE_BUFFER 1
|
||||||
|
/* Defaults */
|
||||||
|
#define E131_DEFAULT_PORT 5568
|
||||||
|
#define WIFI_CONNECT_TIMEOUT 15000 /* 15 seconds */
|
||||||
|
|
||||||
|
/* E1.31 Packet Offsets */
|
||||||
|
#define E131_ROOT_PREAMBLE_SIZE 0
|
||||||
|
#define E131_ROOT_POSTAMBLE_SIZE 2
|
||||||
|
#define E131_ROOT_ID 4
|
||||||
|
#define E131_ROOT_FLENGTH 16
|
||||||
|
#define E131_ROOT_VECTOR 18
|
||||||
|
#define E131_ROOT_CID 22
|
||||||
|
|
||||||
|
#define E131_FRAME_FLENGTH 38
|
||||||
|
#define E131_FRAME_VECTOR 40
|
||||||
|
#define E131_FRAME_SOURCE 44
|
||||||
|
#define E131_FRAME_PRIORITY 108
|
||||||
|
#define E131_FRAME_RESERVED 109
|
||||||
|
#define E131_FRAME_SEQ 111
|
||||||
|
#define E131_FRAME_OPT 112
|
||||||
|
#define E131_FRAME_UNIVERSE 113
|
||||||
|
|
||||||
|
#define E131_DMP_FLENGTH 115
|
||||||
|
#define E131_DMP_VECTOR 117
|
||||||
|
#define E131_DMP_TYPE 118
|
||||||
|
#define E131_DMP_ADDR_FIRST 119
|
||||||
|
#define E131_DMP_ADDR_INC 121
|
||||||
|
#define E131_DMP_COUNT 123
|
||||||
|
#define E131_DMP_DATA 125
|
||||||
|
|
||||||
|
/* E1.31 Packet Structure */
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
/* Root Layer */
|
||||||
|
uint16_t preamble_size;
|
||||||
|
uint16_t postamble_size;
|
||||||
|
uint8_t acn_id[12];
|
||||||
|
uint16_t root_flength;
|
||||||
|
uint32_t root_vector;
|
||||||
|
uint8_t cid[16];
|
||||||
|
|
||||||
|
/* Frame Layer */
|
||||||
|
uint16_t frame_flength;
|
||||||
|
uint32_t frame_vector;
|
||||||
|
uint8_t source_name[64];
|
||||||
|
uint8_t priority;
|
||||||
|
uint16_t reserved;
|
||||||
|
uint8_t sequence_number;
|
||||||
|
uint8_t options;
|
||||||
|
uint16_t universe;
|
||||||
|
|
||||||
|
/* DMP Layer */
|
||||||
|
uint16_t dmp_flength;
|
||||||
|
uint8_t dmp_vector;
|
||||||
|
uint8_t type;
|
||||||
|
uint16_t first_address;
|
||||||
|
uint16_t address_increment;
|
||||||
|
uint16_t property_value_count;
|
||||||
|
uint8_t property_values[513];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
uint8_t raw[638];
|
||||||
|
} e131_packet_t;
|
||||||
|
|
||||||
|
/* Error Types */
|
||||||
|
typedef enum {
|
||||||
|
ERROR_NONE,
|
||||||
|
ERROR_IGNORE,
|
||||||
|
ERROR_ACN_ID,
|
||||||
|
ERROR_PACKET_SIZE,
|
||||||
|
ERROR_VECTOR_ROOT,
|
||||||
|
ERROR_VECTOR_FRAME,
|
||||||
|
ERROR_VECTOR_DMP
|
||||||
|
} e131_error_t;
|
||||||
|
|
||||||
|
/* E1.31 Listener Types */
|
||||||
|
typedef enum {
|
||||||
|
E131_UNICAST,
|
||||||
|
E131_MULTICAST
|
||||||
|
} e131_listen_t;
|
||||||
|
|
||||||
|
/* Status structure */
|
||||||
|
typedef struct {
|
||||||
|
uint32_t num_packets;
|
||||||
|
uint32_t packet_errors;
|
||||||
|
IPAddress last_clientIP;
|
||||||
|
uint16_t last_clientPort;
|
||||||
|
} e131_stats_t;
|
||||||
|
|
||||||
|
class E131 {
|
||||||
|
private:
|
||||||
|
/* Constants for packet validation */
|
||||||
|
static const uint8_t ACN_ID[];
|
||||||
|
static const uint32_t VECTOR_ROOT = 4;
|
||||||
|
static const uint32_t VECTOR_FRAME = 2;
|
||||||
|
static const uint8_t VECTOR_DMP = 2;
|
||||||
|
|
||||||
|
e131_packet_t pbuff1; /* Packet buffer */
|
||||||
|
#ifndef NO_DOUBLE_BUFFER
|
||||||
|
e131_packet_t pbuff2; /* Double buffer */
|
||||||
|
#endif
|
||||||
|
e131_packet_t *pwbuff; /* Pointer to working packet buffer */
|
||||||
|
_UDP udp; /* UDP handle */
|
||||||
|
|
||||||
|
/* Internal Initializers */
|
||||||
|
int initWiFi(const char *ssid, const char *passphrase);
|
||||||
|
int initEthernet(uint8_t *mac, IPAddress ip, IPAddress netmask,
|
||||||
|
IPAddress gateway, IPAddress dns);
|
||||||
|
void initUnicast();
|
||||||
|
void initMulticast(uint16_t universe, uint8_t n = 1);
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint8_t *data; /* Pointer to DMX channel data */
|
||||||
|
uint16_t universe; /* DMX Universe of last valid packet */
|
||||||
|
e131_packet_t *packet; /* Pointer to last valid packet */
|
||||||
|
e131_stats_t stats; /* Statistics tracker */
|
||||||
|
|
||||||
|
E131();
|
||||||
|
|
||||||
|
/* Generic UDP listener, no physical or IP configuration */
|
||||||
|
void begin(e131_listen_t type, uint16_t universe = 1, uint8_t n = 1);
|
||||||
|
|
||||||
|
/****** START - Wireless ifdef block ******/
|
||||||
|
#if defined (INT_WIFI) || defined (INT_ESP8266)
|
||||||
|
/* Unicast WiFi Initializers */
|
||||||
|
int begin(const char *ssid, const char *passphrase);
|
||||||
|
int begin(const char *ssid, const char *passphrase,
|
||||||
|
IPAddress ip, IPAddress netmask, IPAddress gateway, IPAddress dns);
|
||||||
|
#endif
|
||||||
|
/****** END - Wireless ifdef block ******/
|
||||||
|
|
||||||
|
/****** START - ESP8266 ifdef block ******/
|
||||||
|
#if defined (INT_ESP8266)
|
||||||
|
/* Multicast WiFi Initializers -- ESP8266 Only */
|
||||||
|
int beginMulticast(const char *ssid, const char *passphrase,
|
||||||
|
uint16_t universe, uint8_t n = 1);
|
||||||
|
int beginMulticast(const char *ssid, const char *passphrase,
|
||||||
|
uint16_t universe, IPAddress ip, IPAddress netmask,
|
||||||
|
IPAddress gateway, IPAddress dns, uint8_t n = 1);
|
||||||
|
#endif
|
||||||
|
/****** END - ESP8266 ifdef block ******/
|
||||||
|
|
||||||
|
/****** START - Ethernet ifdef block ******/
|
||||||
|
#if defined (INT_ETHERNET)
|
||||||
|
/* Unicast Ethernet Initializers */
|
||||||
|
int begin(uint8_t *mac);
|
||||||
|
void begin(uint8_t *mac,
|
||||||
|
IPAddress ip, IPAddress netmask, IPAddress gateway, IPAddress dns);
|
||||||
|
|
||||||
|
/* Multicast Ethernet Initializers */
|
||||||
|
int beginMulticast(uint8_t *mac, uint16_t universe, uint8_t n = 1);
|
||||||
|
void beginMulticast(uint8_t *mac, uint16_t universe,
|
||||||
|
IPAddress ip, IPAddress netmask, IPAddress gateway,
|
||||||
|
IPAddress dns, uint8_t n = 1);
|
||||||
|
#endif
|
||||||
|
/****** END - Ethernet ifdef block ******/
|
||||||
|
|
||||||
|
/* Diag functions */
|
||||||
|
void dumpError(e131_error_t error);
|
||||||
|
|
||||||
|
/* Main packet parser */
|
||||||
|
inline uint16_t parsePacket() {
|
||||||
|
e131_error_t error;
|
||||||
|
uint16_t retval = 0;
|
||||||
|
|
||||||
|
int size = udp.parsePacket();
|
||||||
|
if (size) {
|
||||||
|
udp.readBytes(pwbuff->raw, size);
|
||||||
|
error = validate();
|
||||||
|
if (!error) {
|
||||||
|
#ifndef NO_DOUBLE_BUFFER
|
||||||
|
e131_packet_t *swap = packet;
|
||||||
|
packet = pwbuff;
|
||||||
|
pwbuff = swap;
|
||||||
|
#endif
|
||||||
|
universe = htons(packet->universe);
|
||||||
|
data = packet->property_values + 1;
|
||||||
|
retval = htons(packet->property_value_count) - 1;
|
||||||
|
stats.num_packets++;
|
||||||
|
stats.last_clientIP = udp.remoteIP();
|
||||||
|
stats.last_clientPort = udp.remotePort();
|
||||||
|
} else if (error == ERROR_IGNORE) {
|
||||||
|
// Do nothing
|
||||||
|
} else {
|
||||||
|
if (Serial)
|
||||||
|
dumpError(error);
|
||||||
|
stats.packet_errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Packet validater */
|
||||||
|
inline e131_error_t validate() {
|
||||||
|
#ifdef ARDUINO_ARCH_AVR
|
||||||
|
if (memcmp_P(pwbuff->acn_id, ACN_ID, sizeof(pwbuff->acn_id)))
|
||||||
|
#else
|
||||||
|
if (memcmp(pwbuff->acn_id, ACN_ID, sizeof(pwbuff->acn_id)))
|
||||||
|
#endif
|
||||||
|
return ERROR_ACN_ID;
|
||||||
|
if (htonl(pwbuff->root_vector) != VECTOR_ROOT)
|
||||||
|
return ERROR_VECTOR_ROOT;
|
||||||
|
if (htonl(pwbuff->frame_vector) != VECTOR_FRAME)
|
||||||
|
return ERROR_VECTOR_FRAME;
|
||||||
|
if (pwbuff->dmp_vector != VECTOR_DMP)
|
||||||
|
return ERROR_VECTOR_DMP;
|
||||||
|
if (pwbuff->property_values[0] != 0)
|
||||||
|
return ERROR_IGNORE;
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* E131_H_ */
|
@ -0,0 +1,362 @@
|
|||||||
|
// Includes
|
||||||
|
#include <WiFi.h>
|
||||||
|
//#include <WiFiServer.h>
|
||||||
|
#include <LEAmDNS.h>
|
||||||
|
#include <HTTPUpdateServer.h>
|
||||||
|
#include <WebServer.h>
|
||||||
|
#include "e131.h"
|
||||||
|
#include <FastLED.h>
|
||||||
|
|
||||||
|
// User configurable
|
||||||
|
|
||||||
|
const char* ssid = "iPhone 14"; // WiFi SSID
|
||||||
|
const char* password = "givemewifi"; // WiFi Password
|
||||||
|
const char* ntpserver = "pool.ntp.org"; // Address of NTP server. Example: pool.ntp.org
|
||||||
|
const char* HOSTNAME = "lighttest";
|
||||||
|
|
||||||
|
const char* update_path = "/firmware";
|
||||||
|
const char* update_username = "admin";
|
||||||
|
const char* update_password = "pico-stripper";
|
||||||
|
|
||||||
|
//#define DEBUG
|
||||||
|
// Total LED count
|
||||||
|
#define MAX_LEDS 50
|
||||||
|
|
||||||
|
#define LED_TYPE WS2812B
|
||||||
|
// Amount of color channels per pixel - i.e. RGB = 3, RGBW = 4
|
||||||
|
#define PIXEL_SIZE 3
|
||||||
|
|
||||||
|
// Number of LED strips connected
|
||||||
|
#define LED_STRIPS 1
|
||||||
|
|
||||||
|
// Define the data pin connection to each strip
|
||||||
|
// Only uncomment the strips you use
|
||||||
|
#define STRIP1 28
|
||||||
|
//#define STRIP2 0
|
||||||
|
//#define STRIP3 2
|
||||||
|
//#define STRIP4 3
|
||||||
|
//#define STRIP5 4
|
||||||
|
//#define STRIP6 5
|
||||||
|
//#define STRIP7 6
|
||||||
|
//#define STRIP8 7
|
||||||
|
|
||||||
|
#define RGB_ORDER RGB
|
||||||
|
|
||||||
|
// define how many LEDs / zones are in each strip
|
||||||
|
int strips[LED_STRIPS] = {50};
|
||||||
|
|
||||||
|
// Begin code
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define PRINTFUNC print
|
||||||
|
#define PRINTLNFUNC println
|
||||||
|
#else
|
||||||
|
#define PRINTFUNC
|
||||||
|
#define PRINTLNFUNC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int calculate[LED_STRIPS * 4];
|
||||||
|
int universes[LED_STRIPS * 4];
|
||||||
|
CRGB ledstrip[MAX_LEDS];
|
||||||
|
int pins[8];
|
||||||
|
|
||||||
|
// Networking
|
||||||
|
|
||||||
|
WebServer httpServer(80);
|
||||||
|
HTTPUpdateServer httpUpdater;
|
||||||
|
bool status = 0;
|
||||||
|
int blankcount = 0;
|
||||||
|
bool ready = 0;
|
||||||
|
struct tm timeinfo;
|
||||||
|
WiFiServer server(8000);
|
||||||
|
String clientbuffer = "";
|
||||||
|
String initinfo = "";
|
||||||
|
bool debug = 0;
|
||||||
|
bool printer = 1;
|
||||||
|
// Colors (RGB)
|
||||||
|
|
||||||
|
const uint8_t RED[PIXEL_SIZE]= {0x20, 0x00, 0x00};
|
||||||
|
const uint8_t ORANGE[PIXEL_SIZE]= {0x20, 0x10, 0x00};
|
||||||
|
const uint8_t YELLOW[PIXEL_SIZE]= {0x20, 0x20, 0x00};
|
||||||
|
const uint8_t GREEN[PIXEL_SIZE]= {0x00, 0x20, 0x00};
|
||||||
|
const uint8_t CYAN[PIXEL_SIZE]= {0x00, 0x20, 0x20};
|
||||||
|
const uint8_t BLUE[PIXEL_SIZE]= {0x00, 0x00, 0x20};
|
||||||
|
const uint8_t PURPLE[PIXEL_SIZE]= {0x20, 0x00, 0x20};
|
||||||
|
const uint8_t BLACK[PIXEL_SIZE]= {0x00, 0x00, 0x00};
|
||||||
|
const uint8_t WHITE[PIXEL_SIZE]= {0x20, 0x20, 0x20};
|
||||||
|
#define MAX_PIXELS_PER_UNIVERSE 512 / PIXEL_SIZE /* Number of pixels */
|
||||||
|
#define CHANNEL_START 1 /* Channel to start listening at */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
E131 e131;
|
||||||
|
|
||||||
|
template <class T> T print(T in) {
|
||||||
|
Serial.print(String(in));
|
||||||
|
if(printer) clientbuffer += String(in);
|
||||||
|
status = 1;
|
||||||
|
return (T)true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> T println(T in) {
|
||||||
|
Serial.println(String(in));
|
||||||
|
if(printer) {
|
||||||
|
clientbuffer += String(in);
|
||||||
|
clientbuffer += "\n";
|
||||||
|
}
|
||||||
|
status = 1;
|
||||||
|
return (T)true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_universe(int universe, uint8_t data[]) {
|
||||||
|
// universe starts at 0
|
||||||
|
|
||||||
|
PRINTFUNC("Universe: ");
|
||||||
|
PRINTLNFUNC(universe);
|
||||||
|
int offset = calculate[universe];
|
||||||
|
PRINTFUNC("Offset: ");
|
||||||
|
PRINTLNFUNC(offset);
|
||||||
|
int write_size = universes[universe];
|
||||||
|
PRINTFUNC("Length: ");
|
||||||
|
PRINTLNFUNC(write_size);
|
||||||
|
status = 0;
|
||||||
|
for (int i = 0; i < write_size; i++) {
|
||||||
|
int j = i * PIXEL_SIZE + (CHANNEL_START - 1);
|
||||||
|
if(debug) {
|
||||||
|
PRINTFUNC(data[j]);
|
||||||
|
PRINTFUNC(" ");
|
||||||
|
PRINTFUNC(data[j+1]);
|
||||||
|
PRINTFUNC(" ");
|
||||||
|
PRINTFUNC(data[j+2]);
|
||||||
|
PRINTFUNC(" ");
|
||||||
|
}
|
||||||
|
ledstrip[offset + i] = CRGB(data[j], data[j+1], data[j+2]);
|
||||||
|
//ledstrip[strip].setPixelColor(i + offset, data[j], data[j+1], data[j+2]);
|
||||||
|
}
|
||||||
|
status = 1;
|
||||||
|
//FastLED.show();
|
||||||
|
PRINTLNFUNC("Done writing.");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(22, OUTPUT);
|
||||||
|
digitalWrite(22, LOW); // Enable buffer output!
|
||||||
|
//pinMode(0, OUTPUT);
|
||||||
|
//digitalWrite(0, HIGH);
|
||||||
|
Serial.begin(115200);
|
||||||
|
delay(3000);
|
||||||
|
PRINTLNFUNC("========= PicoLighter v1.0 Initializing =========");
|
||||||
|
while (ready == 0) {
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Populate universes and offsets
|
||||||
|
int offsetcount = 0;
|
||||||
|
int currentsize = 0;
|
||||||
|
for (int i = 0; i < LED_STRIPS; i++) {
|
||||||
|
int tmp = strips[i];
|
||||||
|
|
||||||
|
PRINTFUNC("Strip ");
|
||||||
|
PRINTFUNC(i);
|
||||||
|
PRINTFUNC(", Pin ");
|
||||||
|
PRINTFUNC(pins[i]);
|
||||||
|
PRINTFUNC(", Light count ");
|
||||||
|
PRINTLNFUNC(tmp);
|
||||||
|
|
||||||
|
while(tmp > MAX_PIXELS_PER_UNIVERSE) {
|
||||||
|
universes[currentsize] = MAX_PIXELS_PER_UNIVERSE;
|
||||||
|
calculate[currentsize] = offsetcount;
|
||||||
|
|
||||||
|
PRINTFUNC(" Universe ");
|
||||||
|
PRINTFUNC(currentsize + 1);
|
||||||
|
PRINTFUNC(", Light count ");
|
||||||
|
PRINTFUNC(MAX_PIXELS_PER_UNIVERSE);
|
||||||
|
PRINTFUNC(", Size ");
|
||||||
|
PRINTLNFUNC(MAX_PIXELS_PER_UNIVERSE * PIXEL_SIZE);
|
||||||
|
offsetcount += MAX_PIXELS_PER_UNIVERSE;
|
||||||
|
currentsize += 1;
|
||||||
|
tmp -= MAX_PIXELS_PER_UNIVERSE;
|
||||||
|
}
|
||||||
|
universes[currentsize] = tmp;
|
||||||
|
calculate[currentsize] = offsetcount;
|
||||||
|
PRINTFUNC(" Universe ");
|
||||||
|
PRINTFUNC(currentsize + 1);
|
||||||
|
PRINTFUNC(", Light count ");
|
||||||
|
PRINTFUNC(tmp);
|
||||||
|
PRINTFUNC(", Size ");
|
||||||
|
PRINTLNFUNC(tmp * PIXEL_SIZE);
|
||||||
|
offsetcount += tmp;
|
||||||
|
currentsize += 1;
|
||||||
|
}
|
||||||
|
PRINTLNFUNC("========= PicoLighter v1.0 Initialized =========");
|
||||||
|
initinfo += clientbuffer;
|
||||||
|
//e131.beginMulticast(ssid, passphrase, UNIVERSE);
|
||||||
|
ready = 0;
|
||||||
|
printer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup1() {
|
||||||
|
pinMode(LED_BUILTIN, OUTPUT);
|
||||||
|
pinMode(32+1, OUTPUT);
|
||||||
|
digitalWrite(LED_BUILTIN, HIGH);
|
||||||
|
#ifdef STRIP1
|
||||||
|
FastLED.addLeds<LED_TYPE, STRIP1, RGB_ORDER>(ledstrip, calculate[0], strips[0]);
|
||||||
|
pins[0] = STRIP1;
|
||||||
|
#endif
|
||||||
|
#ifdef STRIP2
|
||||||
|
FastLED.addLeds<LED_TYPE, STRIP2, RGB_ORDER>(ledstrip, calculate[1], strips[1]);
|
||||||
|
pins[1] = STRIP2;
|
||||||
|
#endif
|
||||||
|
#ifdef STRIP3
|
||||||
|
FastLED.addLeds<LED_TYPE, STRIP3, RGB_ORDER>(ledstrip, calculate[2], strips[2]);
|
||||||
|
pins[2] = STRIP3;
|
||||||
|
#endif
|
||||||
|
#ifdef STRIP4
|
||||||
|
FastLED.addLeds<LED_TYPE, STRIP4, RGB_ORDER>(ledstrip, calculate[3], strips[3]);
|
||||||
|
pins[3] = STRIP4;
|
||||||
|
#endif
|
||||||
|
#ifdef STRIP5
|
||||||
|
FastLED.addLeds<LED_TYPE, STRIP5, RGB_ORDER>(ledstrip, calculate[4], strips[4]);
|
||||||
|
pins[4] = STRIP5;
|
||||||
|
#endif
|
||||||
|
#ifdef STRIP6
|
||||||
|
FastLED.addLeds<LED_TYPE, STRIP6, RGB_ORDER>(ledstrip, calculate[5], strips[5]);
|
||||||
|
pins[5] = STRIP6;
|
||||||
|
#endif
|
||||||
|
#ifdef STRIP7
|
||||||
|
FastLED.addLeds<LED_TYPE, STRIP7, RGB_ORDER>(ledstrip, calculate[6], strips[6]);
|
||||||
|
pins[6] = STRIP7;
|
||||||
|
#endif
|
||||||
|
#ifdef STRIP8
|
||||||
|
FastLED.addLeds<LED_TYPE, STRIP8, RGB_ORDER>(ledstrip, calculate[7], strips[7]);
|
||||||
|
pins[7] = STRIP8;
|
||||||
|
#endif
|
||||||
|
// Test all lights
|
||||||
|
for (int i = 0; i < MAX_LEDS; i++) {
|
||||||
|
ledstrip[i] = CRGB(130, 130, 130);
|
||||||
|
FastLED.show();
|
||||||
|
delay(30);
|
||||||
|
ledstrip[i] = CRGB(0, 0, 0);
|
||||||
|
}
|
||||||
|
FastLED.show();
|
||||||
|
delay(3000);
|
||||||
|
WiFi.noLowPowerMode();
|
||||||
|
if (e131.begin(ssid, password) != WL_CONNECTED) {
|
||||||
|
PRINTFUNC("Connection failed. Retrying.");
|
||||||
|
rp2040.reboot();
|
||||||
|
}
|
||||||
|
PRINTLNFUNC("Starting mDNS client.");
|
||||||
|
MDNS.begin(HOSTNAME);
|
||||||
|
httpUpdater.setup(&httpServer, update_path, update_username, update_password);
|
||||||
|
httpServer.begin();
|
||||||
|
MDNS.addService("http", "tcp", 80);
|
||||||
|
PRINTFUNC("OTA Updates enabled. Open http://");
|
||||||
|
PRINTFUNC(HOSTNAME);
|
||||||
|
PRINTFUNC(update_path);
|
||||||
|
PRINTFUNC(" in your browser and login with username ");
|
||||||
|
PRINTFUNC(update_username);
|
||||||
|
PRINTFUNC(" and password ");
|
||||||
|
PRINTLNFUNC(update_password);
|
||||||
|
server.begin();
|
||||||
|
ready = 1;
|
||||||
|
while (ready == 1) {
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
// If we get here, then WiFi is good to go
|
||||||
|
PRINTFUNC("Starting NTP client.");
|
||||||
|
NTP.begin(ntpserver);
|
||||||
|
NTP.waitSet([]() { PRINTFUNC("."); }, 15000);
|
||||||
|
time_t now = time(nullptr);
|
||||||
|
PRINTLNFUNC("");
|
||||||
|
gmtime_r(&now, &timeinfo);
|
||||||
|
PRINTFUNC("Current time: ");
|
||||||
|
PRINTFUNC(asctime(&timeinfo));
|
||||||
|
|
||||||
|
//rp2040.wdt_begin(8000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
/* Parse a packet and update pixels */
|
||||||
|
if(e131.parsePacket()) {
|
||||||
|
write_universe(e131.universe - 1, e131.data);
|
||||||
|
}
|
||||||
|
else if (blankcount > 1000) {
|
||||||
|
status = 0;
|
||||||
|
blankcount = 0;
|
||||||
|
} else {
|
||||||
|
blankcount ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop1() {
|
||||||
|
if(status == 1) {
|
||||||
|
FastLED.show();
|
||||||
|
}
|
||||||
|
httpServer.handleClient();
|
||||||
|
MDNS.update();
|
||||||
|
if (millis() % 100 > 50) { // reset LED
|
||||||
|
digitalWrite(LED_BUILTIN, HIGH);
|
||||||
|
}
|
||||||
|
else if (millis() % 100 < 50 && status == 1) {
|
||||||
|
//status = 0;
|
||||||
|
digitalWrite(LED_BUILTIN, LOW);
|
||||||
|
}
|
||||||
|
//status = 0;
|
||||||
|
//delay(50);
|
||||||
|
float temp = analogReadTemp();
|
||||||
|
if (temp > 50.0) {
|
||||||
|
PRINTLNFUNC("ERROR: Overtemperature triggered!");
|
||||||
|
rp2040.reboot();
|
||||||
|
}
|
||||||
|
WiFiClient client = server.available();
|
||||||
|
if (client) {
|
||||||
|
PRINTLNFUNC("Client connected");
|
||||||
|
clientbuffer = "";
|
||||||
|
printer = 1;
|
||||||
|
client.println(initinfo);
|
||||||
|
client.println("Press d + ENTER to toggle RGB debug.");
|
||||||
|
while (client.connected()) {
|
||||||
|
if(status == 1) {
|
||||||
|
FastLED.show();
|
||||||
|
}
|
||||||
|
httpServer.handleClient();
|
||||||
|
MDNS.update();
|
||||||
|
if (millis() % 100 > 50) { // reset LED
|
||||||
|
digitalWrite(LED_BUILTIN, HIGH);
|
||||||
|
}
|
||||||
|
else if (millis() % 100 < 50 && status == 1) {
|
||||||
|
//status = 0;
|
||||||
|
digitalWrite(LED_BUILTIN, LOW);
|
||||||
|
}
|
||||||
|
//status = 0;
|
||||||
|
//delay(50);
|
||||||
|
float temp = analogReadTemp(); // read temp in celsius
|
||||||
|
if (temp > 50.0) {
|
||||||
|
PRINTLNFUNC("ERROR: Overtemperature triggered!");
|
||||||
|
rp2040.reboot();
|
||||||
|
}
|
||||||
|
if(clientbuffer != (String) "") {
|
||||||
|
client.print(clientbuffer);
|
||||||
|
clientbuffer = "";
|
||||||
|
}
|
||||||
|
while(client.available()) {
|
||||||
|
char c = client.read();
|
||||||
|
if (c == 'd') {
|
||||||
|
if (debug == 1) {
|
||||||
|
debug = 0;
|
||||||
|
} else {
|
||||||
|
debug = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
client.stop();
|
||||||
|
printer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef UTIL_H_
|
||||||
|
#define UTIL_H_
|
||||||
|
|
||||||
|
#define htons(x) ( ((x) << 8) | (((x) >> 8)&0xFF) )
|
||||||
|
#define ntohs(x) htons(x)
|
||||||
|
|
||||||
|
#define htonl(x) ( ((x) << 24 & 0xFF000000UL) | \
|
||||||
|
((x) << 8 & 0x00FF0000UL) | \
|
||||||
|
((x) >> 8 & 0x0000FF00UL) | \
|
||||||
|
((x) >> 24 & 0x000000FFUL) )
|
||||||
|
#define ntohl(x) htonl(x)
|
||||||
|
|
||||||
|
#endif /* UTIL_H_ */
|
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
This directory is intended for PlatformIO Test Runner and project tests.
|
||||||
|
|
||||||
|
Unit Testing is a software testing method by which individual units of
|
||||||
|
source code, sets of one or more MCU program modules together with associated
|
||||||
|
control data, usage procedures, and operating procedures, are tested to
|
||||||
|
determine whether they are fit for use. Unit testing finds problems early
|
||||||
|
in the development cycle.
|
||||||
|
|
||||||
|
More information about PlatformIO Unit Testing:
|
||||||
|
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
Loading…
Reference in New Issue