PicoLighter Wifi Test

simple-crash-test
Cole Deck 4 months ago
commit eb17418214

5
.gitignore vendored

@ -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…
Cancel
Save