mirror of
https://gitlab.com/zwirbel/illucat.git
synced 2025-12-18 18:55:50 +01:00
Compare commits
65 Commits
release-1.
...
branch/doc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
354564cf62 | ||
|
|
2fa6fadac6 | ||
|
|
212baf7660 | ||
| 7fb97d164a | |||
| 8573b3d5c4 | |||
|
|
b04e1d83de | ||
|
|
77c9c5f169 | ||
|
|
0394c21459 | ||
|
|
349b40990d | ||
|
|
7c1db449b6 | ||
|
|
9a75c0d0db | ||
|
|
e620529157 | ||
| a25f50d40c | |||
| ade966a77c | |||
|
|
fb98bef55b | ||
| b24077de52 | |||
| efa9849f1b | |||
| f7ba31c2d2 | |||
| 62186af303 | |||
| 6f1afc1bc1 | |||
| f754e7640f | |||
| 4e69dbc471 | |||
| 4c6f1ba365 | |||
| b05d2d4fde | |||
| 91566eca43 | |||
|
|
6e63a18a53 | ||
| ae1f468969 | |||
| abc902d5a6 | |||
| f4e87685fb | |||
|
|
aa2713517f | ||
| 47a68e6ce4 | |||
| 3a45f8626e | |||
| 73495201eb | |||
| 722f725bad | |||
| 11959ea30b | |||
| 8db6698690 | |||
| 418d5e18fd | |||
| 2c94dfe83d | |||
| 48ab6fca1a | |||
| f3df87ed96 | |||
|
|
099ba3fe70 | ||
| edfd0ebcb7 | |||
|
|
7c2df13381 | ||
| 2ea9c02571 | |||
| 5a0225b040 | |||
| a039e591da | |||
| a940903bd3 | |||
| 299f7dae65 | |||
| 99dbd8379b | |||
| d4d40428cc | |||
| 7fa3683ca6 | |||
| a8d5cae284 | |||
| a916e542fb | |||
| 6fc5908761 | |||
|
|
afd13ca661 | ||
|
|
09915ca94b | ||
| 2a21775524 | |||
| 0e13508158 | |||
| 75a4e3e94c | |||
| b91255fe85 | |||
| 207f90d60a | |||
| 0686895f33 | |||
| ffd76acb69 | |||
| 77d92155df | |||
| 2ba0684982 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,6 +1,3 @@
|
||||
.pioenvs
|
||||
.piolibdeps
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.pio
|
||||
.vscode
|
||||
data/config.json
|
||||
@@ -20,7 +20,6 @@ firmware:
|
||||
before_script:
|
||||
- pip install -U platformio
|
||||
script:
|
||||
- mv data/example.config.json data/config.json
|
||||
- pio run -t clean
|
||||
- pio run
|
||||
- pio run -t buildfs
|
||||
@@ -33,8 +32,8 @@ release:
|
||||
script:
|
||||
- pip install awscli
|
||||
- mkdir -p ${PROJECT_NAME}/${CI_COMMIT_TAG}
|
||||
- mv .pioenvs/build/firmware.bin ${PROJECT_NAME}/${CI_COMMIT_TAG}
|
||||
- mv .pioenvs/build/spiffs.bin ${PROJECT_NAME}/${CI_COMMIT_TAG}
|
||||
- mv .pioenvs/release/firmware.bin ${PROJECT_NAME}/${CI_COMMIT_TAG}
|
||||
- mv .pioenvs/release/spiffs.bin ${PROJECT_NAME}/${CI_COMMIT_TAG}
|
||||
- aws s3 --endpoint-url=https://$DO_SPACE_ENDPOINT cp ./ s3://$S3_BUCKET_NAME/ --recursive --exclude "*" --include "*.bin"
|
||||
artifacts:
|
||||
paths:
|
||||
|
||||
11
.project
Normal file
11
.project
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>illucat</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
12
.vscode/extensions.json
vendored
12
.vscode/extensions.json
vendored
@@ -1,7 +1,7 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
]
|
||||
}
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
]
|
||||
}
|
||||
|
||||
25
.vscode/settings.json
vendored
25
.vscode/settings.json
vendored
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"terminal.integrated.env.linux": {
|
||||
"PATH": "/home/master/.platformio/penv/bin:/home/master/.platformio/penv:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl",
|
||||
"PATH": "/home/master/.platformio/penv/bin:/home/master/.platformio/penv:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl",
|
||||
"PLATFORMIO_CALLER": "vscode"
|
||||
},
|
||||
"files.associations": {
|
||||
@@ -15,6 +15,27 @@
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"tuple": "cpp",
|
||||
"utility": "cpp"
|
||||
"utility": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"exception": "cpp",
|
||||
"fstream": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"numeric": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
}
|
||||
}
|
||||
3
Dockerfile
Normal file
3
Dockerfile
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM python:3.6-stretch as builder
|
||||
|
||||
RUN pip install -U platformio
|
||||
4
Makefile
Normal file
4
Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
build:
|
||||
docker build -t wirelos/platformio .
|
||||
run-workspace:
|
||||
docker run -it --rm -v $PWD:/project wirelos/platformio bash
|
||||
16
README.md
16
README.md
@@ -1,9 +1,21 @@
|
||||
# Illumination-Cat
|
||||
This is the brain of the the almighty Illumination-Cat.
|
||||
The Illumination-Cat (short IlluCat) is the collaborative work of several streams, ranging from 3D modeling, electronics and programming.
|
||||
Originating from the Chaos-Drucker Club with the idea of having
|
||||
a cool status indicator for 3D printers, the project grew beyond the original idea.
|
||||
|
||||
From the software point of view, the IlluCat is the exemplary model of the [Sprocket framework](https://gitlab.com/wirelos/sprocket-lib), implementing the various aspects and possibilities of the framework.
|
||||
IlluCat can embed several plugins, like web interface, MQTT, IRC or even mesh networking.
|
||||
As the framework supports easy integration of many available Arduino libraries, IlluCat can be easily customized to your needs. This repository contains some example implementations that you can use to build your own custom cat.
|
||||
|
||||
## OTA
|
||||
pio run -e build && \
|
||||
curl -v -F file=@.pioenvs/build/firmware.bin http://illucat.lan/update && \
|
||||
curl -X POST http://illucat.lan/restart
|
||||
|
||||
## Resources & Documentation
|
||||
[3D Model](https://www.thingiverse.com/thing:2974862)
|
||||
[Installation](https://gitlab.com/0x1d/illucat/blob/master/installation.md)
|
||||
[API](https://gitlab.com/0x1d/illucat/blob/master/api.md)
|
||||
[OctoPrint Stuff](https://github.com/FrYakaTKoP/simple-octo-ws2812)
|
||||
|
||||
[Sprocket framework](https://gitlab.com/wirelos/sprocket-lib)
|
||||
[Sprocket plugins](https://gitlab.com/wirelos)
|
||||
|
||||
2
api.md
2
api.md
@@ -27,7 +27,7 @@ All functionality can be used by sending messages to these topics.
|
||||
| pixels/brightness | Integer | Integer from 0 to 255 to set the overall brightness of the strip by bitshifting the current colors in memory. Use with caution as running the LEDs on full brightness requires a lot of power. |
|
||||
|
||||
## WebSocket
|
||||
Endpoint: /pixel
|
||||
Endpoint: /ws
|
||||
Send a JSON String containing the mandatory fields.
|
||||
|
||||
Example:
|
||||
|
||||
9
data/config/wifi.json
Normal file
9
data/config/wifi.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"stationMode": 1,
|
||||
"hostname": "bar-light",
|
||||
"apSSID": "bar-light",
|
||||
"apPassword": "th3r31sn0sp00n",
|
||||
"connectTimeout": 5000,
|
||||
"stationSSID": "UPC7823296",
|
||||
"stationPassword": "rthYx4Vnfeza"
|
||||
}u
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"stationMode": 0,
|
||||
"hostname": "illucat",
|
||||
"stationSSID": "MyWifi",
|
||||
"stationPassword": "myWifiPassword",
|
||||
"meshSSID": "illucat",
|
||||
"meshPassword": "illumination",
|
||||
"meshPort": 5555,
|
||||
"channel": 5
|
||||
}
|
||||
6
data/ircConfig.json
Normal file
6
data/ircConfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"ircServer": "chat.freenode.net",
|
||||
"ircPort": 6665,
|
||||
"ircNickname": "illucat",
|
||||
"ircUser": "illucat"
|
||||
}
|
||||
6
data/mqttConfig.json
Normal file
6
data/mqttConfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"mqttClientName" : "illucat1",
|
||||
"mqttBrokerHost" : "192.168.1.2",
|
||||
"mqttBrokerPort" : 1883,
|
||||
"mqttRootTopic" : "wirelos/illucat"
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"pin": 4,
|
||||
"length": 32,
|
||||
"brightness": 64,
|
||||
"updateInterval": 50,
|
||||
"length": 8,
|
||||
"brightness": 50,
|
||||
"updateInterval": 100,
|
||||
"defaultColor": 100
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB |
BIN
data/www/favicon.png
Normal file
BIN
data/www/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
@@ -2,10 +2,10 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>ESP Kit</title>
|
||||
<title>IlluCat</title>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" type="image/png" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" href="/favicon.png">
|
||||
<link rel="stylesheet" type="text/css" href="styles.css">
|
||||
<script src="script.js"></script>
|
||||
</head>
|
||||
@@ -21,8 +21,8 @@
|
||||
data-name="hue"
|
||||
data-topic="pixels/hue"
|
||||
data-default="0"
|
||||
data-external="/gradients.json"
|
||||
></li>
|
||||
data-external="/gradients.json">
|
||||
</li>
|
||||
<li class="form-row ParamColor"
|
||||
data-name="color"
|
||||
data-topic="pixels/color"
|
||||
@@ -39,7 +39,7 @@
|
||||
data-name="pattern"
|
||||
data-topic="pixels/pattern"
|
||||
data-default="0"
|
||||
data-entries='[{"text": "None", "value": "0"}, {"text": "Rainbow", "value": "1"}, {"text": "TheaterChase", "value": "2"}, {"text": "Color Wipe", "value": "3"}, {"text": "Scanner", "value": "4"}, {"text": "Fade", "value": "5"}]'
|
||||
data-entries='[{"text": "None", "value": "0"}, {"text": "Rainbow", "value": "1"}, {"text": "TheaterChase", "value": "2"}, {"text": "Color Wipe", "value": "3"}, {"text": "Scanner", "value": "4"}, {"text": "Fade", "value": "5"}, {"text": "Fire", "value": "6"}]'
|
||||
></li>
|
||||
<li class="form-row ParamSlider"
|
||||
data-name="brightness"
|
||||
@@ -60,19 +60,33 @@
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
<!-- <div class="settings container collapsible open">
|
||||
<span class="heading">IlluChat</span>
|
||||
<div class="content">
|
||||
<div class="Chat" data-name="Ruedi" data-label="foo" data-placeholder="msg" data-topic="out/chat/log"></div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="settings container collapsible">
|
||||
<span class="heading">Settings</span>
|
||||
<div class="content">
|
||||
<h2>Network</h2>
|
||||
<div class="Form" data-fileName="/config.json" data-name="configForm" data-from="/config.json" data-endpoint="/config"></div>
|
||||
<div class="Form" data-fileName="/config/wifi.json" data-name="configForm" data-from="/config/wifi.json" data-endpoint="/config"></div>
|
||||
<h2>NeoPixel</h2>
|
||||
<div class="Form" data-fileName="/pixelConfig.json" data-name="configForm" data-from="/pixelConfig.json" data-endpoint="/config"></div>
|
||||
<div class="Form" data-fileName="/pixelConfig.json" data-name="configForm" data-from="/pixelConfig.json" data-endpoint="/config"></div>
|
||||
<!-- <h2>MQTT</h2>
|
||||
<div class="Form" data-fileName="/mqttConfig.json" data-name="configForm" data-from="/mqttConfig.json" data-endpoint="/config"></div>
|
||||
<h2>IRC</h2>
|
||||
<div class="Form" data-fileName="/ircConfig.json" data-name="configForm" data-from="/ircConfig.json" data-endpoint="/config"></div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings container collapsible">
|
||||
<span class="heading">System</span>
|
||||
<div class="content">
|
||||
<div><label>Free Heap: </label><span class="js-heap"></span><span> bytes</span><br><br></div>
|
||||
<form method='POST' action='/update' enctype='multipart/form-data'>
|
||||
<input type='file' name='update'><input type='submit' value='Update'>
|
||||
</form>
|
||||
<br>
|
||||
<button class="js-restart">Restart</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
12245
data/www/script.js
12245
data/www/script.js
File diff suppressed because it is too large
Load Diff
BIN
data/www/script.js.gz
Normal file
BIN
data/www/script.js.gz
Normal file
Binary file not shown.
@@ -306,3 +306,24 @@ form .form-row input[type="checkbox"] {
|
||||
.sui select option {
|
||||
background: #333333;
|
||||
}
|
||||
.Chat .message-container {
|
||||
max-height: 200px;
|
||||
overflow: auto;
|
||||
}
|
||||
.Chat .message-container .messages {
|
||||
list-style-type: none;
|
||||
}
|
||||
.Chat .message-container .messages .user-label {
|
||||
color: lightblue;
|
||||
}
|
||||
.Chat .message-container .messages .user-label:before {
|
||||
color: #097479;
|
||||
content: '<';
|
||||
}
|
||||
.Chat .message-container .messages .user-label:after {
|
||||
color: #097479;
|
||||
content: '>';
|
||||
}
|
||||
.Chat .message-container .messages .message-text {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
39
include/readme.txt
Normal file
39
include/readme.txt
Normal file
@@ -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
|
||||
@@ -4,16 +4,14 @@
|
||||
- download and flash firmware and filesystem
|
||||
- or: rename example.config.json to config.json, build and upload it yourself
|
||||
|
||||
## Enduser Setup
|
||||
## Enduser Setup (Standalone)
|
||||
1. Scan for access points
|
||||
1. connect to illucat access point
|
||||
1. open web browser and navigate to the gateway IP
|
||||
1. change stationMode to 1 in the Settings section for connecting the cat to your own AP. leave it 0 to build a mesh.
|
||||
1. change stationSSID and stationPassword to match your AP settings
|
||||
1. change the NeoPixel settings according to your hardware. The pin needs to be specified as the pin id of your board, e.g. 4 = D2 on a Wemos D1 Mini.
|
||||
1. connect to the access point "illucat" with password "illumination"
|
||||
1. open a web browser and navigate to http://192.168.4.1
|
||||
1. To connect the cat to your own WiFi, open the "Settings" section and change "stationMode" to 1 and set "stationSSID" and "stationPassword" according to your own access point's credentials
|
||||
1. submit all changes
|
||||
1. hit restart under the System section
|
||||
1. illucat connects to your network and can be reached with http://illucat (or any other configured hostname)
|
||||
1. open the "System" section and hit "Restart"
|
||||
1. illucat connects to your network and can be reached through http://illucat (might take some time, depending on your DNS server)
|
||||
|
||||
|
||||
## Install and setup Python
|
||||
@@ -64,21 +62,6 @@ hint: you can crank the baudrate up to 921600 bps ;)
|
||||
|
||||
python -m esptool --port COM11 --baud 115200 write_flash 0x00000 firmware.bin 0x00300000 spiffs.bin
|
||||
|
||||
# Configuration after first boot
|
||||
|
||||
the esp will build a AP with ssid name **illu** and password **illumination**
|
||||
|
||||
when connected browse to **http://illucat**
|
||||
|
||||
now you can enter the SSID and Password of your WLAN and set StationMode to 1
|
||||
then press save and reset the esp)
|
||||
|
||||
the Cat should now joined your network
|
||||
|
||||
find the ip of your cat in your DHCP table
|
||||
|
||||
have fun
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,384 +0,0 @@
|
||||
/**
|
||||
* Original NeoPattern code by Bill Earl
|
||||
* https://learn.adafruit.com/multi-tasking-the-arduino-part-3/overview
|
||||
*
|
||||
* TODO
|
||||
* - cleanup the mess
|
||||
* - fnc table for patterns to replace switch case
|
||||
*
|
||||
* Custom modifications by 0x1d:
|
||||
* - default OnComplete callback that sets pattern to reverse
|
||||
* - separate animation update from timer; Update now updates directly, UpdateScheduled uses timer
|
||||
*/
|
||||
#ifndef __NeoPattern_INCLUDED__
|
||||
#define __NeoPattern_INCLUDED__
|
||||
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace std::placeholders;
|
||||
|
||||
// Pattern types supported:
|
||||
enum pattern
|
||||
{
|
||||
NONE = 0,
|
||||
RAINBOW_CYCLE = 1,
|
||||
THEATER_CHASE = 2,
|
||||
COLOR_WIPE = 3,
|
||||
SCANNER = 4,
|
||||
FADE = 5
|
||||
};
|
||||
// Patern directions supported:
|
||||
enum direction
|
||||
{
|
||||
FORWARD,
|
||||
REVERSE
|
||||
};
|
||||
|
||||
// NeoPattern Class - derived from the Adafruit_NeoPixel class
|
||||
class NeoPattern : public Adafruit_NeoPixel
|
||||
{
|
||||
public:
|
||||
// Member Variables:
|
||||
pattern ActivePattern = RAINBOW_CYCLE; // which pattern is running
|
||||
direction Direction = FORWARD; // direction to run the pattern
|
||||
|
||||
unsigned long Interval = 150; // milliseconds between updates
|
||||
unsigned long lastUpdate = 0; // last update of position
|
||||
|
||||
uint32_t Color1 = 0;
|
||||
uint32_t Color2 = 0; // What colors are in use
|
||||
uint16_t TotalSteps = 32; // total number of steps in the pattern
|
||||
uint16_t Index; // current step within the pattern
|
||||
uint16_t completed = 0;
|
||||
|
||||
// FIXME return current NeoPatternState
|
||||
void (*OnComplete)(int); // Callback on completion of pattern
|
||||
|
||||
uint8_t *frameBuffer;
|
||||
int bufferSize = 0;
|
||||
|
||||
// Constructor - calls base-class constructor to initialize strip
|
||||
NeoPattern(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)(int))
|
||||
: Adafruit_NeoPixel(pixels, pin, type)
|
||||
{
|
||||
frameBuffer = (uint8_t*)malloc(768);
|
||||
OnComplete = callback;
|
||||
TotalSteps = numPixels();
|
||||
}
|
||||
|
||||
NeoPattern(uint16_t pixels, uint8_t pin, uint8_t type)
|
||||
: Adafruit_NeoPixel(pixels, pin, type)
|
||||
{
|
||||
frameBuffer = (uint8_t*)malloc(768);
|
||||
TotalSteps = numPixels();
|
||||
}
|
||||
|
||||
void handleStream(uint8_t *data, size_t len)
|
||||
{
|
||||
//const uint16_t *data16 = (uint16_t *)data;
|
||||
bufferSize = len;
|
||||
memcpy(frameBuffer, data, len);
|
||||
}
|
||||
|
||||
void drawFrameBuffer(int w, uint8_t *frame, int length){
|
||||
for (int i = 0; i < length; i++){
|
||||
uint8_t r = frame[i];
|
||||
uint8_t g = frame[++i];
|
||||
uint8_t b = frame[++i];
|
||||
setPixelColor(i, r ,g, b);
|
||||
}
|
||||
}
|
||||
|
||||
void onCompleteDefault(int pixels)
|
||||
{
|
||||
//Serial.println("onCompleteDefault");
|
||||
// FIXME no specific code
|
||||
if (ActivePattern == THEATER_CHASE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Reverse();
|
||||
//Serial.println("pattern completed");
|
||||
}
|
||||
|
||||
// Update the pattern
|
||||
void Update()
|
||||
{
|
||||
switch (ActivePattern)
|
||||
{
|
||||
case RAINBOW_CYCLE:
|
||||
RainbowCycleUpdate();
|
||||
break;
|
||||
case THEATER_CHASE:
|
||||
TheaterChaseUpdate();
|
||||
break;
|
||||
case COLOR_WIPE:
|
||||
ColorWipeUpdate();
|
||||
break;
|
||||
case SCANNER:
|
||||
ScannerUpdate();
|
||||
break;
|
||||
case FADE:
|
||||
FadeUpdate();
|
||||
break;
|
||||
default:
|
||||
if(bufferSize > 0){
|
||||
drawFrameBuffer(TotalSteps, frameBuffer, bufferSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateScheduled()
|
||||
{
|
||||
if ((millis() - lastUpdate) > Interval) // time to update
|
||||
{
|
||||
lastUpdate = millis();
|
||||
Update();
|
||||
}
|
||||
}
|
||||
|
||||
// Increment the Index and reset at the end
|
||||
void Increment()
|
||||
{
|
||||
completed = 0;
|
||||
if (Direction == FORWARD)
|
||||
{
|
||||
Index++;
|
||||
if (Index >= TotalSteps)
|
||||
{
|
||||
Index = 0;
|
||||
completed = 1;
|
||||
if (OnComplete != NULL)
|
||||
{
|
||||
OnComplete(numPixels()); // call the comlpetion callback
|
||||
}
|
||||
else
|
||||
{
|
||||
onCompleteDefault(numPixels());
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Direction == REVERSE
|
||||
{
|
||||
--Index;
|
||||
if (Index <= 0)
|
||||
{
|
||||
Index = TotalSteps - 1;
|
||||
completed = 1;
|
||||
if (OnComplete != NULL)
|
||||
{
|
||||
OnComplete(numPixels()); // call the comlpetion callback
|
||||
}
|
||||
else
|
||||
{
|
||||
onCompleteDefault(numPixels());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse pattern direction
|
||||
void Reverse()
|
||||
{
|
||||
if (Direction == FORWARD)
|
||||
{
|
||||
Direction = REVERSE;
|
||||
Index = TotalSteps - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Direction = FORWARD;
|
||||
Index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize for a RainbowCycle
|
||||
void RainbowCycle(uint8_t interval, direction dir = FORWARD)
|
||||
{
|
||||
ActivePattern = RAINBOW_CYCLE;
|
||||
Interval = interval;
|
||||
TotalSteps = 255;
|
||||
Index = 0;
|
||||
Direction = dir;
|
||||
}
|
||||
|
||||
// Update the Rainbow Cycle Pattern
|
||||
void RainbowCycleUpdate()
|
||||
{
|
||||
for (int i = 0; i < numPixels(); i++)
|
||||
{
|
||||
setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
|
||||
}
|
||||
show();
|
||||
Increment();
|
||||
}
|
||||
|
||||
// Initialize for a Theater Chase
|
||||
void TheaterChase(uint32_t color1, uint32_t color2, uint16_t interval, direction dir = FORWARD)
|
||||
{
|
||||
ActivePattern = THEATER_CHASE;
|
||||
Interval = interval;
|
||||
TotalSteps = numPixels();
|
||||
Color1 = color1;
|
||||
Color2 = color2;
|
||||
Index = 0;
|
||||
Direction = dir;
|
||||
}
|
||||
|
||||
// Update the Theater Chase Pattern
|
||||
void TheaterChaseUpdate()
|
||||
{
|
||||
for (int i = 0; i < numPixels(); i++)
|
||||
{
|
||||
if ((i + Index) % 3 == 0)
|
||||
{
|
||||
setPixelColor(i, Color1);
|
||||
}
|
||||
else
|
||||
{
|
||||
setPixelColor(i, Color2);
|
||||
}
|
||||
}
|
||||
show();
|
||||
Increment();
|
||||
}
|
||||
|
||||
// Initialize for a ColorWipe
|
||||
void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD)
|
||||
{
|
||||
ActivePattern = COLOR_WIPE;
|
||||
Interval = interval;
|
||||
TotalSteps = numPixels();
|
||||
Color1 = color;
|
||||
Index = 0;
|
||||
Direction = dir;
|
||||
}
|
||||
|
||||
// Update the Color Wipe Pattern
|
||||
void ColorWipeUpdate()
|
||||
{
|
||||
setPixelColor(Index, Color1);
|
||||
show();
|
||||
Increment();
|
||||
}
|
||||
|
||||
// Initialize for a SCANNNER
|
||||
void Scanner(uint32_t color1, uint8_t interval)
|
||||
{
|
||||
ActivePattern = SCANNER;
|
||||
Interval = interval;
|
||||
TotalSteps = (numPixels() - 1) * 2;
|
||||
Color1 = color1;
|
||||
Index = 0;
|
||||
}
|
||||
|
||||
// Update the Scanner Pattern
|
||||
void ScannerUpdate()
|
||||
{
|
||||
for (int i = 0; i < numPixels(); i++)
|
||||
{
|
||||
if (i == Index) // Scan Pixel to the right
|
||||
{
|
||||
setPixelColor(i, Color1);
|
||||
}
|
||||
else if (i == TotalSteps - Index) // Scan Pixel to the left
|
||||
{
|
||||
setPixelColor(i, Color1);
|
||||
}
|
||||
else // Fading tail
|
||||
{
|
||||
setPixelColor(i, DimColor(getPixelColor(i)));
|
||||
}
|
||||
}
|
||||
show();
|
||||
Increment();
|
||||
}
|
||||
|
||||
// Initialize for a Fade
|
||||
void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD)
|
||||
{
|
||||
ActivePattern = FADE;
|
||||
Interval = interval;
|
||||
TotalSteps = steps;
|
||||
Color1 = color1;
|
||||
Color2 = color2;
|
||||
Index = 0;
|
||||
Direction = dir;
|
||||
}
|
||||
|
||||
// Update the Fade Pattern
|
||||
void FadeUpdate()
|
||||
{
|
||||
// Calculate linear interpolation between Color1 and Color2
|
||||
// Optimise order of operations to minimize truncation error
|
||||
uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
|
||||
uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps;
|
||||
uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;
|
||||
|
||||
ColorSet(Color(red, green, blue));
|
||||
show();
|
||||
Increment();
|
||||
}
|
||||
|
||||
// Calculate 50% dimmed version of a color (used by ScannerUpdate)
|
||||
uint32_t DimColor(uint32_t color)
|
||||
{
|
||||
// Shift R, G and B components one bit to the right
|
||||
uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
|
||||
return dimColor;
|
||||
}
|
||||
|
||||
// Set all pixels to a color (synchronously)
|
||||
void ColorSet(uint32_t color)
|
||||
{
|
||||
for (int i = 0; i < numPixels(); i++)
|
||||
{
|
||||
setPixelColor(i, color);
|
||||
}
|
||||
show();
|
||||
}
|
||||
|
||||
// Returns the Red component of a 32-bit color
|
||||
uint8_t Red(uint32_t color)
|
||||
{
|
||||
return (color >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
// Returns the Green component of a 32-bit color
|
||||
uint8_t Green(uint32_t color)
|
||||
{
|
||||
return (color >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
// Returns the Blue component of a 32-bit color
|
||||
uint8_t Blue(uint32_t color)
|
||||
{
|
||||
return color & 0xFF;
|
||||
}
|
||||
|
||||
// Input a value 0 to 255 to get a color value.
|
||||
// The colours are a transition r - g - b - back to r.
|
||||
uint32_t Wheel(byte WheelPos)
|
||||
{
|
||||
//if(WheelPos == 0) return Color(0,0,0);
|
||||
WheelPos = 255 - WheelPos;
|
||||
if (WheelPos < 85)
|
||||
{
|
||||
return Color(255 - WheelPos * 3, 0, WheelPos * 3);
|
||||
}
|
||||
else if (WheelPos < 170)
|
||||
{
|
||||
WheelPos -= 85;
|
||||
return Color(0, WheelPos * 3, 255 - WheelPos * 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
WheelPos -= 170;
|
||||
return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,96 +0,0 @@
|
||||
#ifndef __NEOPATTERN_STATE__
|
||||
#define __NEOPATTERN_STATE__
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include "NeoPattern_api_json.h"
|
||||
#include "NeoPattern_api_modes.cpp"
|
||||
#include "utils_print.h"
|
||||
#include "JsonStruct.h"
|
||||
|
||||
// TODO move ARRAY_LENGTH to core lib
|
||||
#define ARRAY_LENGTH(array) sizeof(array)/sizeof(array[0])
|
||||
|
||||
struct NeoPixelConfig : public JsonStruct {
|
||||
int pin;
|
||||
int length;
|
||||
int brightness;
|
||||
int updateInterval;
|
||||
int defaultColor;
|
||||
void mapJsonObject(JsonObject& root) {
|
||||
root["pin"] = pin;
|
||||
root["length"] = length;
|
||||
root["brightness"] = brightness;
|
||||
root["updateInterval"] = updateInterval;
|
||||
root["defaultColor"] = defaultColor;
|
||||
}
|
||||
void fromJsonObject(JsonObject& json) {
|
||||
pin = getIntAttrFromJson(json, "pin");
|
||||
length = getIntAttrFromJson(json, "length");
|
||||
brightness = getIntAttrFromJson(json, "brightness");
|
||||
updateInterval = getIntAttrFromJson(json, "updateInterval");
|
||||
defaultColor = getIntAttrFromJson(json, "defaultColor");
|
||||
}
|
||||
};
|
||||
|
||||
struct NeoPatternState : public JsonStruct {
|
||||
uint pattern = 0;
|
||||
uint color= 0;
|
||||
uint color2= 0;
|
||||
uint totalSteps = 16;
|
||||
uint brightness = 64;
|
||||
|
||||
void mapJsonObject(JsonObject& root) {
|
||||
root["pattern"] = pattern;
|
||||
root["color"] = color;
|
||||
root["color2"] = color2;
|
||||
root["totalSteps"] = totalSteps;
|
||||
root["brightness"] = brightness;
|
||||
|
||||
}
|
||||
// Map a json object to this struct.
|
||||
void fromJsonObject(JsonObject& json){
|
||||
if(!verifyJsonObject(json)){
|
||||
PRINT_MSG(Serial, "fromJsonObject", "cannot parse JSON");
|
||||
valid = 0;
|
||||
return;
|
||||
}
|
||||
color = getIntAttrFromJson(json, "color", color);
|
||||
color2 = getIntAttrFromJson(json, "color2", color2);
|
||||
pattern = getIntAttrFromJson(json, "pattern", pattern);
|
||||
brightness = getIntAttrFromJson(json, "brightness", brightness);
|
||||
totalSteps = getIntAttrFromJson(json, "totalSteps", totalSteps);
|
||||
valid = 1;
|
||||
};
|
||||
};
|
||||
|
||||
struct NeoPatternDto : public JsonStruct {
|
||||
uint mode;
|
||||
uint value;
|
||||
const char* valueStr;
|
||||
// ------------------------------------------------------------------------------------------
|
||||
//Check if given object is valid and contains fields: JSON_MODE_NODE, JSON_VALUE
|
||||
int verifyJsonObject(JsonObject& json){
|
||||
return json.success()
|
||||
&& json.containsKey(JSON_MODE_NODE)
|
||||
&& json.containsKey(JSON_VALUE);
|
||||
};
|
||||
void mapJsonObject(JsonObject& root) {
|
||||
root[JSON_MODE_NODE] = mode;
|
||||
root[JSON_VALUE] = value;
|
||||
}
|
||||
// Map a json object to this struct.
|
||||
void fromJsonObject(JsonObject& json){
|
||||
if(!verifyJsonObject(json)){
|
||||
PRINT_MSG(Serial, "fromJsonObject", "cannot parse JSON");
|
||||
valid = 0;
|
||||
return;
|
||||
}
|
||||
mode = atoi(json[JSON_MODE_NODE]);
|
||||
mode = mode < ARRAY_LENGTH(PIXEL_FNCS) ? mode : 0;
|
||||
value = json[JSON_VALUE];
|
||||
valueStr = json[JSON_VALUE];
|
||||
valid = 1;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
#ifndef __PIXEL_JSON_API__
|
||||
#define __PIXEL_JSON_API__
|
||||
/*
|
||||
modes: PIXELS_OFF = 0, COLOR_WHEEL_MODE = 1, COLOR_MODE = 2, PATTERN_MODE = 3
|
||||
patterns: NONE = 0, RAINBOW_CYCLE = 1, THEATER_CHASE = 2, COLOR_WIPE = 3, SCANNER = 4, FADE = 5
|
||||
{
|
||||
"mode": int,
|
||||
"value": int || String
|
||||
}
|
||||
*/
|
||||
|
||||
#define JSON_MODE_NODE "mode"
|
||||
#define JSON_VALUE "value"
|
||||
#define JSON_ACTION_NODE "action"
|
||||
|
||||
#endif
|
||||
@@ -1,64 +0,0 @@
|
||||
#ifndef __NEOPATTERN_API_MODES__
|
||||
#define __NEOPATTERN_API_MODES__
|
||||
|
||||
#include "NeoPattern.cpp"
|
||||
|
||||
enum PIXEL_MODE { PIXELS_OFF = 0, COLOR_WHEEL_MODE = 1, COLOR_MODE = 2, PATTERN_MODE = 3};
|
||||
typedef void (*PIXEL_FP)(NeoPattern*, const char *);
|
||||
|
||||
/*
|
||||
Array of function pointers to be used as lookup table using the int values of PIXEL_MODE.
|
||||
TODO header file + separate functions instead of lambdas
|
||||
*/
|
||||
const PIXEL_FP PIXEL_FNCS[] = {
|
||||
/*
|
||||
PIXESL_OFF
|
||||
Sets all pixels to black.
|
||||
*/
|
||||
[](NeoPattern* pixels, const char *color){
|
||||
pixels->clear();
|
||||
pixels->ColorSet(0);
|
||||
},
|
||||
/*
|
||||
COLOR_WHEEL_MODE
|
||||
Input: integer color from 0 to 155
|
||||
Uses the color wheel to set a color.
|
||||
If given integer is <= 1, set the color to black.
|
||||
By using this function, Color1 and Color2 is set on the pixels;
|
||||
Color1 = new color, Color2 = last color.
|
||||
*/
|
||||
[](NeoPattern* pixels, const char *color){
|
||||
int c1 = atoi(color);
|
||||
int c2 = pixels->Color1;
|
||||
pixels->Color1 = c1;
|
||||
pixels->Color2 = c2;
|
||||
pixels->ActivePattern = NONE;
|
||||
if(c1 <= 1) {
|
||||
pixels->ColorSet(0);
|
||||
return;
|
||||
}
|
||||
pixels->ColorSet(pixels->Wheel(c1));
|
||||
},
|
||||
/*
|
||||
COLOR_MODE
|
||||
sets the color from an rgb int
|
||||
*/
|
||||
[](NeoPattern* pixels, const char *color){
|
||||
pixels->ActivePattern = NONE;
|
||||
pixels->ColorSet(atoi(color));
|
||||
},
|
||||
/*
|
||||
PATTERN_MODE
|
||||
Input: id of the pattern
|
||||
Sets the active pattern on the strip.
|
||||
As every pattern has another API, all fields need to be set before, for example by using COLOR_WHEEL_MODE.
|
||||
*/
|
||||
[](NeoPattern* pixels, const char *id){
|
||||
pattern p = (pattern)atoi(id);
|
||||
//pixels->Interval = 50;
|
||||
//pixels->TotalSteps = pixels->numPixels();
|
||||
pixels->ActivePattern = p;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,25 +0,0 @@
|
||||
#include "utils_print.h"
|
||||
|
||||
int FORMAT_BUFFER_SIZE(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int result = vsnprintf(NULL, 0, format, args);
|
||||
va_end(args);
|
||||
return result + 1; // safe byte for \0
|
||||
}
|
||||
void PRINT_MSG(Print &out, const char* prefix, const char* format, ...) {
|
||||
if(SPROCKET_PRINT){
|
||||
out.print(String(prefix) + String(": "));
|
||||
char formatString[128], *ptr;
|
||||
strncpy_P( formatString, format, sizeof(formatString) ); // copy in from program mem
|
||||
// null terminate - leave last char since we might need it in worst case for result's \0
|
||||
formatString[ sizeof(formatString)-2 ]='\0';
|
||||
ptr=&formatString[ strlen(formatString)+1 ]; // our result buffer...
|
||||
va_list args;
|
||||
va_start (args,format);
|
||||
vsnprintf(ptr, sizeof(formatString)-1-strlen(formatString), formatString, args );
|
||||
va_end (args);
|
||||
formatString[ sizeof(formatString)-1 ]='\0';
|
||||
out.println(ptr);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef __SPROCKET_UTILS__
|
||||
#define __SPROCKET_UTILS__
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#ifndef SPROCKET_PRINT
|
||||
#define SPROCKET_PRINT 1
|
||||
#endif
|
||||
|
||||
// TODO move to sprocket
|
||||
|
||||
int FORMAT_BUFFER_SIZE(const char* format, ...);
|
||||
void PRINT_MSG(Print &out, const char* prefix, const char* format, ...);
|
||||
|
||||
#endif
|
||||
@@ -1,126 +0,0 @@
|
||||
#ifndef __WSUTILS_H___
|
||||
#define __WSUTILS_H___
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <AsyncWebSocket.h>
|
||||
#include <ESPAsyncTCP.h>
|
||||
|
||||
class WsUtils {
|
||||
public:
|
||||
static String parseFrame(AwsEventType type, void * arg, uint8_t *data, size_t len) {
|
||||
String msg = "";
|
||||
if(type == WS_EVT_DATA){
|
||||
AwsFrameInfo * info = (AwsFrameInfo*)arg;
|
||||
if(info->opcode == WS_TEXT){
|
||||
for(size_t i=0; i < info->len; i++) {
|
||||
msg += (char) data[i];
|
||||
}
|
||||
} else {
|
||||
char buff[3];
|
||||
for(size_t i=0; i < info->len; i++) {
|
||||
sprintf(buff, "%02x ", (uint8_t) data[i]);
|
||||
msg += buff ;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
static String parseFrameAsString(AwsEventType type, void * arg, uint8_t *data, size_t len, int start = 0) {
|
||||
String msg = "";
|
||||
if(type == WS_EVT_DATA){
|
||||
AwsFrameInfo * info = (AwsFrameInfo*)arg;
|
||||
//if(info->final && info->index == 0 && info->len == len){
|
||||
if(info->opcode == WS_TEXT){
|
||||
for(size_t i=start; i < info->len; i++) {
|
||||
msg += (char) data[i];
|
||||
}
|
||||
} else {
|
||||
char buff[3];
|
||||
for(size_t i=start; i < info->len; i++) {
|
||||
sprintf(buff, "%02x ", (uint8_t) data[i]);
|
||||
msg += buff ;
|
||||
}
|
||||
}
|
||||
|
||||
//}
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
/* static void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len) {
|
||||
if(type == WS_EVT_CONNECT){
|
||||
Serial.printf("ws[%s][%u] connect\n", server->url(), client->id());
|
||||
client->printf("Hello Client %u :)", client->id());
|
||||
client->ping();
|
||||
} else if(type == WS_EVT_DISCONNECT){
|
||||
Serial.printf("ws[%s][%u] disconnect: %u\n", server->url(), client->id());
|
||||
} else if(type == WS_EVT_ERROR){
|
||||
Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data);
|
||||
} else if(type == WS_EVT_PONG){
|
||||
Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:"");
|
||||
} else if(type == WS_EVT_DATA){
|
||||
AwsFrameInfo * info = (AwsFrameInfo*)arg;
|
||||
String msg = "";
|
||||
//the whole message is in a single frame and we got all of it's data
|
||||
if(info->final && info->index == 0 && info->len == len){
|
||||
Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len);
|
||||
|
||||
if(info->opcode == WS_TEXT){
|
||||
for(size_t i=0; i < info->len; i++) {
|
||||
msg += (char) data[i];
|
||||
}
|
||||
} else {
|
||||
char buff[3];
|
||||
for(size_t i=0; i < info->len; i++) {
|
||||
sprintf(buff, "%02x ", (uint8_t) data[i]);
|
||||
msg += buff ;
|
||||
}
|
||||
}
|
||||
Serial.printf("%s\n",msg.c_str());
|
||||
|
||||
if(info->opcode == WS_TEXT)
|
||||
client->text("I got your text message");
|
||||
else
|
||||
client->binary("I got your binary message");
|
||||
}
|
||||
//message is comprised of multiple frames or the frame is split into multiple packets
|
||||
else {
|
||||
if(info->index == 0){
|
||||
if(info->num == 0)
|
||||
Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary");
|
||||
Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len);
|
||||
}
|
||||
|
||||
Serial.printf("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", server->url(), client->id(), info->num, (info->message_opcode == WS_TEXT)?"text":"binary", info->index, info->index + len);
|
||||
|
||||
if(info->opcode == WS_TEXT){
|
||||
for(size_t i=0; i < info->len; i++) {
|
||||
msg += (char) data[i];
|
||||
}
|
||||
} else {
|
||||
char buff[3];
|
||||
for(size_t i=0; i < info->len; i++) {
|
||||
sprintf(buff, "%02x ", (uint8_t) data[i]);
|
||||
msg += buff ;
|
||||
}
|
||||
}
|
||||
Serial.printf("%s\n",msg.c_str());
|
||||
|
||||
if((info->index + len) == info->len){
|
||||
Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len);
|
||||
if(info->final){
|
||||
Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary");
|
||||
if(info->message_opcode == WS_TEXT)
|
||||
client->text("I got your text message");
|
||||
else
|
||||
client->binary("I got your binary message");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -13,24 +13,38 @@ env_default = build
|
||||
|
||||
[common]
|
||||
framework = arduino
|
||||
platform = espressif8266
|
||||
platform = espressif8266@2.0.4
|
||||
board = esp12e
|
||||
upload_speed = 921600
|
||||
monitor_baud = 115200
|
||||
lib_deps =
|
||||
Hash
|
||||
ESPAsyncTCP
|
||||
TaskScheduler
|
||||
SPIFFS
|
||||
painlessMesh
|
||||
ESP8266mDNS
|
||||
ArduinoOTA
|
||||
ArduinoJson
|
||||
ESP Async WebServer
|
||||
ESPAsyncTCP
|
||||
ArduinoJson@5.13.4
|
||||
Adafruit NeoPixel
|
||||
ESPAsyncTCP
|
||||
ESP8266mDNS
|
||||
ESP Async WebServer
|
||||
https://gitlab.com/wirelos/sprocket-lib.git#develop
|
||||
https://gitlab.com/wirelos/sprocket-plugin-neopixel.git
|
||||
|
||||
|
||||
[env:build-esp32]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
src_filter = +<*> -<var/> +<var/wifi/>
|
||||
upload_speed = ${common.upload_speed}
|
||||
monitor_baud = ${common.monitor_baud}
|
||||
framework = ${common.framework}
|
||||
build_flags = -DSPROCKET_PRINT=1
|
||||
lib_deps = ${common.lib_deps}
|
||||
https://gitlab.com/wirelos/sprocket-network-wifi.git#next
|
||||
https://gitlab.com/wirelos/sprocket-plugin-web.git#next
|
||||
|
||||
|
||||
[env:build]
|
||||
src_filter = +<*> -<var/> +<var/wifi/>
|
||||
platform = ${common.platform}
|
||||
board = ${common.board}
|
||||
upload_speed = ${common.upload_speed}
|
||||
@@ -39,9 +53,25 @@ framework = ${common.framework}
|
||||
build_flags = -Wl,-Teagle.flash.4m1m.ld
|
||||
-DSPROCKET_PRINT=1
|
||||
lib_deps = ${common.lib_deps}
|
||||
https://gitlab.com/wirelos/sprocket-core.git#develop
|
||||
https://gitlab.com/wirelos/sprocket-network-wifi.git#next
|
||||
https://gitlab.com/wirelos/sprocket-plugin-web.git#next
|
||||
|
||||
|
||||
[env:build-mesh]
|
||||
src_filter = +<*> -<var/> +<var/wifiMesh/>
|
||||
platform = ${common.platform}
|
||||
board = ${common.board}
|
||||
upload_speed = ${common.upload_speed}
|
||||
monitor_baud = ${common.monitor_baud}
|
||||
framework = ${common.framework}
|
||||
build_flags = -Wl,-Teagle.flash.4m1m.ld
|
||||
-DSPROCKET_PRINT=1
|
||||
lib_deps = ${common.lib_deps}
|
||||
https://gitlab.com/wirelos/painlessMesh.git
|
||||
https://gitlab.com/wirelos/sprocket-network-mesh.git#forked-mesh
|
||||
|
||||
[env:release]
|
||||
src_filter = +<*> -<var/> +<var/wifi/>
|
||||
platform = ${common.platform}
|
||||
board = ${common.board}
|
||||
upload_speed = ${common.upload_speed}
|
||||
@@ -50,16 +80,38 @@ framework = ${common.framework}
|
||||
build_flags = -Wl,-Teagle.flash.4m1m.ld
|
||||
-DSPROCKET_PRINT=0
|
||||
lib_deps = ${common.lib_deps}
|
||||
https://gitlab.com/wirelos/sprocket-core.git#master
|
||||
https://gitlab.com/wirelos/sprocket-network-wifi.git#next
|
||||
https://gitlab.com/wirelos/sprocket-plugin-web.git#next
|
||||
|
||||
|
||||
[env:nodemcu]
|
||||
[env:mqcatt]
|
||||
src_filter = +<*> -<var/> +<var/mqcatt/>
|
||||
platform = ${common.platform}
|
||||
board = nodemcu
|
||||
board = ${common.board}
|
||||
upload_speed = ${common.upload_speed}
|
||||
monitor_baud = ${common.monitor_baud}
|
||||
framework = ${common.framework}
|
||||
build_flags = -Wl,-Teagle.flash.4m1m.ld
|
||||
-DSPROCKET_PRINT=1
|
||||
lib_deps = ${common.lib_deps}
|
||||
https://gitlab.com/wirelos/sprocket-core.git#develop
|
||||
https://gitlab.com/wirelos/sprocket-network-wifi.git#next
|
||||
https://gitlab.com/wirelos/sprocket-plugin-web.git#next
|
||||
https://gitlab.com/wirelos/sprocket-plugin-mqtt.git#next
|
||||
PubSubClient
|
||||
|
||||
[env:illuchat]
|
||||
src_filter = +<*> -<var/> +<var/illuchat/>
|
||||
platform = ${common.platform}
|
||||
board = ${common.board}
|
||||
upload_speed = ${common.upload_speed}
|
||||
monitor_baud = ${common.monitor_baud}
|
||||
framework = ${common.framework}
|
||||
build_flags = -Wl,-Teagle.flash.4m1m.ld
|
||||
-DSPROCKET_PRINT=1
|
||||
lib_deps = ${common.lib_deps}
|
||||
https://gitlab.com/wirelos/sprocket-network-wifi.git#next
|
||||
https://gitlab.com/wirelos/sprocket-plugin-web.git#next
|
||||
https://gitlab.com/wirelos/sprocket-plugin-irc.git
|
||||
https://gitlab.com/wirelos/sprocket-plugin-mqtt.git#next
|
||||
PubSubClient
|
||||
ArduinoIRC
|
||||
|
||||
165
src/IlluCat.h
165
src/IlluCat.h
@@ -1,151 +1,38 @@
|
||||
#ifndef __MESH_APP__
|
||||
#define __MESH_APP__
|
||||
|
||||
#include <painlessMesh.h>
|
||||
#include <base/MeshSprocket.h>
|
||||
#include <MeshNet.h>
|
||||
#ifndef __ILLUCAT__
|
||||
#define __ILLUCAT__
|
||||
|
||||
#include "config.h"
|
||||
#include "NeoPattern.cpp"
|
||||
#include "NeoPatternDto.h"
|
||||
#include "NeoPattern_api_json.h"
|
||||
#include "NeoPattern_api_modes.cpp"
|
||||
#include "utils_print.h"
|
||||
#include "utils_ws.h"
|
||||
#include <plugins/WebSO.h>
|
||||
#include <plugins/OtaTcpPlugin.cpp>
|
||||
#include <plugins/WebServerPlugin.cpp>
|
||||
#include <plugins/WebConfigPlugin.cpp>
|
||||
#include <TaskScheduler.h>
|
||||
#include <Sprocket.h>
|
||||
|
||||
#include "WebServerConfig.h"
|
||||
#include "WebServerPlugin.h"
|
||||
#include "WebConfigPlugin.h"
|
||||
#include "WebApiPlugin.h"
|
||||
#include "PixelPlugin.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace std::placeholders;
|
||||
|
||||
class IlluCat : public MeshSprocket {
|
||||
public:
|
||||
NeoPattern* pixels;
|
||||
NeoPatternDto defaultState;
|
||||
NeoPatternDto state;
|
||||
AsyncWebServer* server;
|
||||
AsyncWebSocket* ws;
|
||||
AsyncWebSocket* wsStream;
|
||||
class IlluCat : public Sprocket
|
||||
{
|
||||
public:
|
||||
AsyncWebServer *server;
|
||||
SprocketConfig sprocketConfig;
|
||||
WebServerConfig webConfig;
|
||||
|
||||
NeoPixelConfig pixelConfig;
|
||||
SprocketConfig sprocketConfig;
|
||||
OtaConfig otaConfig;
|
||||
WebServerConfig webConfig;
|
||||
IlluCat(SprocketConfig cfg, WebServerConfig webCfg) : Sprocket(cfg)
|
||||
{
|
||||
sprocketConfig = cfg;
|
||||
webConfig = webCfg;
|
||||
server = new AsyncWebServer(webConfig.port);
|
||||
server->serveStatic(PIXEL_CONFIG_FILE, SPIFFS, "pixelConfig.json");
|
||||
addPlugin(new PixelPlugin());
|
||||
addPlugin(new WebServerPlugin(webConfig, server));
|
||||
addPlugin(new WebConfigPlugin(server));
|
||||
addPlugin(new WebApiPlugin(server));
|
||||
}
|
||||
|
||||
SprocketMessage currentMessage;
|
||||
|
||||
IlluCat(SprocketConfig cfg, OtaConfig otaCfg, WebServerConfig webCfg/* , NeoPixelConfig pixelCfg */) : MeshSprocket(cfg) {
|
||||
//pixelConfig = pixelCfg;
|
||||
|
||||
sprocketConfig = cfg;
|
||||
otaConfig = otaCfg;
|
||||
webConfig = webCfg;
|
||||
|
||||
pixelConfig.pin = 4;
|
||||
pixelConfig.length = 8;
|
||||
pixelConfig.brightness = 32;
|
||||
pixelConfig.updateInterval = 100;
|
||||
pixelConfig.defaultColor = 100;
|
||||
|
||||
}
|
||||
virtual void scanningAnimation() {
|
||||
pixels->Scanner(pixels->Wheel(COLOR_NOT_CONNECTED), pixelConfig.updateInterval);
|
||||
}
|
||||
virtual void defaultAnimation() {
|
||||
String defaultStr = String(defaultState.value);
|
||||
PIXEL_FNCS[defaultState.mode](pixels, defaultStr.c_str());
|
||||
}
|
||||
Sprocket* activate(Scheduler* scheduler, Network* network) {
|
||||
|
||||
net = static_cast<MeshNet*>(network);
|
||||
|
||||
// load config files from SPIFFS
|
||||
if(SPIFFS.begin()){
|
||||
pixelConfig.fromFile("/pixelConfig.json");
|
||||
defaultState.fromFile("/pixelState.json");
|
||||
state = defaultState;
|
||||
}
|
||||
|
||||
// initialize services
|
||||
pixels = new NeoPattern(pixelConfig.length, pixelConfig.pin, NEO_GRB + NEO_KHZ800);
|
||||
server = new AsyncWebServer(80);
|
||||
ws = new AsyncWebSocket("/pixel");
|
||||
wsStream = new AsyncWebSocket("/stream");
|
||||
|
||||
// add plugins
|
||||
addPlugin(new OtaTcpPlugin(otaConfig));
|
||||
addPlugin(new WebServerPlugin(webConfig, server));
|
||||
addPlugin(new WebConfigPlugin(server));
|
||||
addPlugin(new PixelPlugin(pixelConfig, pixels));
|
||||
defaultAnimation();
|
||||
|
||||
String softApPrt = "SoftAP IP: " + WiFi.softAPIP().toString();
|
||||
PRINT_MSG(Serial, SPROCKET_TYPE, softApPrt.c_str());
|
||||
|
||||
// TODO move to plugin
|
||||
// setup web stuff
|
||||
server->serveStatic("/pixelConfig.json", SPIFFS, "pixelConfig.json");
|
||||
server->on("/pixel/api", HTTP_POST, bind(&IlluCat::patternWebRequestHandler, this, _1));
|
||||
ws->onEvent(bind(&IlluCat::onWsEvent, this, _1, _2, _3, _4, _5, _6));
|
||||
server->addHandler(ws);
|
||||
wsStream->onEvent(bind(&IlluCat::onStream, this, _1, _2, _3, _4, _5, _6));
|
||||
server->addHandler(wsStream);
|
||||
|
||||
return MeshSprocket::activate(scheduler, network);
|
||||
} using MeshSprocket::activate;
|
||||
|
||||
// TODO move to utils
|
||||
String getRequestParameterOrDefault(AsyncWebServerRequest *request, String param, String defaultValue, bool isPost = true){
|
||||
if(request->hasParam(param, isPost)) {
|
||||
return request->getParam(param, isPost)->value();
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
void onStream(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len) {
|
||||
if(type == WS_EVT_DATA){
|
||||
PRINT_MSG(Serial, SPROCKET_TYPE, WsUtils::parseFrameAsString(type, arg, data, len, 0).c_str());
|
||||
pixels->ActivePattern = NONE;
|
||||
pixels->handleStream(data, len);
|
||||
}
|
||||
}
|
||||
|
||||
void patternWebRequestHandler(AsyncWebServerRequest *request) {
|
||||
PRINT_MSG(Serial, SPROCKET_TYPE, "POST /pixel/api");
|
||||
currentMessage.topic = getRequestParameterOrDefault(request, "topic", "");
|
||||
currentMessage.payload = getRequestParameterOrDefault(request, "payload", "");
|
||||
currentMessage.broadcast = atoi(getRequestParameterOrDefault(request, "broadcast", "0").c_str());
|
||||
String msg = currentMessage.toJsonString();
|
||||
publish(currentMessage.topic, currentMessage.payload);
|
||||
if(currentMessage.broadcast){
|
||||
net->mesh.sendBroadcast(msg);
|
||||
}
|
||||
request->send(200, "text/plain", msg);
|
||||
}
|
||||
|
||||
virtual void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len) {
|
||||
if(type == WS_EVT_DATA){
|
||||
String frame = WsUtils::parseFrameAsString(type, arg, data, len, 0);
|
||||
dispatch(0, frame);
|
||||
net->mesh.sendBroadcast(frame);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dispatch( uint32_t from, String &msg ) {
|
||||
currentMessage.fromJsonString(msg);
|
||||
if(currentMessage.valid){
|
||||
currentMessage.from = from;
|
||||
publish(currentMessage.topic, currentMessage.payload);
|
||||
}
|
||||
}
|
||||
|
||||
void loop(){
|
||||
MeshSprocket::loop();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,96 +0,0 @@
|
||||
#ifndef __PIXEL_PLUGIN__
|
||||
#define __PIXEL_PLUGIN__
|
||||
|
||||
#define _TASK_SLEEP_ON_IDLE_RUN
|
||||
#define _TASK_STD_FUNCTION
|
||||
|
||||
#include "TaskSchedulerDeclarations.h"
|
||||
#include "MeshNet.h"
|
||||
#include "Plugin.h"
|
||||
#include "NeoPatternDto.h"
|
||||
#include "NeoPattern.cpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace std::placeholders;
|
||||
|
||||
class PixelPlugin : public Plugin {
|
||||
private:
|
||||
NeoPixelConfig pixelConfig;
|
||||
NeoPattern* pixels;
|
||||
NeoPatternState state;
|
||||
public:
|
||||
Task animation;
|
||||
PixelPlugin(NeoPixelConfig cfg, NeoPattern* neoPattern){
|
||||
pixelConfig = cfg;
|
||||
pixels = neoPattern;
|
||||
pixels->begin();
|
||||
pixels->setBrightness(pixelConfig.brightness);
|
||||
|
||||
}
|
||||
void activate(Scheduler* userScheduler, Network* network){
|
||||
subscribe("pixels/colorWheel", bind(&PixelPlugin::colorWheel, this, _1));
|
||||
subscribe("pixels/color", bind(&PixelPlugin::setColor, this, _1));
|
||||
subscribe("pixels/color2", bind(&PixelPlugin::setColor2, this, _1));
|
||||
subscribe("pixels/pattern", bind(&PixelPlugin::setPattern, this, _1));
|
||||
subscribe("pixels/totalSteps", bind(&PixelPlugin::setTotalSteps, this, _1));
|
||||
subscribe("pixels/brightness", bind(&PixelPlugin::setBrightness, this, _1));
|
||||
subscribe("pixels/state", bind(&PixelPlugin::setState, this, _1));
|
||||
|
||||
animation.set(TASK_MILLISECOND * pixelConfig.updateInterval, TASK_FOREVER, bind(&PixelPlugin::animate, this));
|
||||
userScheduler->addTask(animation);
|
||||
animation.enable();
|
||||
PRINT_MSG(Serial, SPROCKET_TYPE, "NeoPixels activated");
|
||||
}
|
||||
|
||||
void setState(String msg) {
|
||||
PRINT_MSG(Serial, SPROCKET_TYPE, msg.c_str());
|
||||
state.fromJsonString(msg);
|
||||
//pixels->setBrightness(state.brightness);
|
||||
//pixels->ColorSet(state.color);
|
||||
pixels->Index = 0;
|
||||
pixels->Color1 = state.color;
|
||||
pixels->Color2 = state.color2;
|
||||
pixels->TotalSteps = state.totalSteps;
|
||||
pixels->ActivePattern = (pattern) state.pattern;
|
||||
pixels->Direction = FORWARD;
|
||||
}
|
||||
void colorWheel(String msg){
|
||||
int color = atoi(msg.c_str());
|
||||
pixels->ActivePattern = NONE;
|
||||
pixels->ColorSet(pixels->Wheel(color));
|
||||
}
|
||||
void setTotalSteps(String msg){
|
||||
pixels->TotalSteps = atoi(msg.c_str());
|
||||
}
|
||||
void setBrightness(String msg){
|
||||
int inVal = atoi(msg.c_str());
|
||||
pixels->setBrightness(inVal);
|
||||
pixels->show();
|
||||
}
|
||||
void setColor(String msg){
|
||||
pixels->ActivePattern = NONE;
|
||||
pixels->Color1 = atoi(msg.c_str());
|
||||
//if(pixels->ActivePattern == NONE){
|
||||
pixels->ColorSet(pixels->Color1);
|
||||
//}
|
||||
}
|
||||
void setColor2(String msg){
|
||||
pixels->Color2 = atoi(msg.c_str());
|
||||
}
|
||||
void setPattern(String msg){
|
||||
pixels->Index = 0;
|
||||
pixels->Direction = FORWARD;
|
||||
pixels->ActivePattern = (pattern)atoi(msg.c_str());
|
||||
}
|
||||
void animate(){
|
||||
pixels->Update();
|
||||
}
|
||||
void enable(){
|
||||
animation.enable();
|
||||
}
|
||||
void disable(){
|
||||
animation.disable();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
15
src/config.h
15
src/config.h
@@ -1,26 +1,32 @@
|
||||
#ifndef __MESH_CONFIG__
|
||||
#define __MESH_CONFIG__
|
||||
#ifndef __ILLUCAT_CONFIG__
|
||||
#define __ILLUCAT_CONFIG__
|
||||
|
||||
// Scheduler config
|
||||
#define _TASK_SLEEP_ON_IDLE_RUN
|
||||
#define _TASK_STD_FUNCTION
|
||||
#define _TASK_PRIORITY
|
||||
|
||||
// Chip config
|
||||
#define SPROCKET_TYPE "ILLUCAT"
|
||||
#define SERIAL_BAUD_RATE 115200
|
||||
#define STARTUP_DELAY 3000
|
||||
#define STARTUP_DELAY 1000
|
||||
|
||||
// Mesh config
|
||||
#define SPROCKET_MODE 0
|
||||
#define WIFI_CHANNEL 11
|
||||
#define MESH_PORT 5555
|
||||
#define AP_SSID "illucat"
|
||||
#define AP_PASSWORD "illumination"
|
||||
#define MESH_PREFIX "illucat-mesh"
|
||||
#define MESH_PASSWORD "th3r31sn0sp00n"
|
||||
#define STATION_SSID "MyAP"
|
||||
#define STATION_PASSWORD "th3r31sn0sp00n"
|
||||
#define HOSTNAME "illucat"
|
||||
#define CONNECT_TIMEOUT 10000
|
||||
#define MESH_DEBUG_TYPES ERROR | STARTUP | CONNECTION
|
||||
//ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE
|
||||
//#define MESH_DEBUG_TYPES ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE
|
||||
|
||||
#define PIXEL_CONFIG_FILE "/pixelConfig.json"
|
||||
|
||||
// OTA config
|
||||
#define OTA_PORT 8266
|
||||
@@ -30,6 +36,7 @@
|
||||
#define WEB_CONTEXT_PATH "/"
|
||||
#define WEB_DOC_ROOT "/www"
|
||||
#define WEB_DEFAULT_FILE "index.html"
|
||||
#define WEB_PORT 80
|
||||
|
||||
// NeoPixel
|
||||
#define LED_STRIP_PIN D2
|
||||
|
||||
25
src/main.cpp
25
src/main.cpp
@@ -1,25 +0,0 @@
|
||||
#include "config.h"
|
||||
#include "MeshNet.h"
|
||||
#include "IlluCat.h"
|
||||
|
||||
MeshNet net({
|
||||
SPROCKET_MODE, WIFI_CHANNEL,
|
||||
MESH_PORT, MESH_PREFIX, MESH_PASSWORD,
|
||||
STATION_SSID, STATION_PASSWORD, HOSTNAME,
|
||||
MESH_DEBUG_TYPES
|
||||
});
|
||||
IlluCat sprocket(
|
||||
{ STARTUP_DELAY, SERIAL_BAUD_RATE },
|
||||
{ OTA_PORT, OTA_PASSWORD },
|
||||
{ WEB_CONTEXT_PATH, WEB_DOC_ROOT, WEB_DEFAULT_FILE }/* ,
|
||||
{ LED_STRIP_PIN, LED_STRIP_LENGTH, LED_STRIP_BRIGHTNESS, LED_STRIP_UPDATE_INTERVAL, LED_STRIP_DEFAULT_COLOR } */
|
||||
);
|
||||
|
||||
void setup() {
|
||||
sprocket.join(net);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
sprocket.loop();
|
||||
yield();
|
||||
}
|
||||
62
src/var/illuchat/illuchat_config.h
Normal file
62
src/var/illuchat/illuchat_config.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef __ILLUCHAT_CONFIG__
|
||||
#define __ILLUCHAT_CONFIG__
|
||||
|
||||
// Scheduler config
|
||||
#define _TASK_SLEEP_ON_IDLE_RUN
|
||||
#define _TASK_STD_FUNCTION
|
||||
#define _TASK_PRIORITY
|
||||
|
||||
// Chip config
|
||||
#define SPROCKET_TYPE "ILLUCAT"
|
||||
#define SERIAL_BAUD_RATE 115200
|
||||
#define STARTUP_DELAY 1000
|
||||
|
||||
// Network config
|
||||
#define WIFI_MODE 0
|
||||
#define WIFI_CHANNEL 11
|
||||
#define AP_SSID "illucat"
|
||||
#define AP_PASSWORD "illumination"
|
||||
#define MESH_PREFIX "illucat-mesh"
|
||||
#define MESH_PASSWORD "th3r31sn0sp00n"
|
||||
#define STATION_SSID "MyAP"
|
||||
#define STATION_PASSWORD "th3r31sn0sp00n"
|
||||
#define HOSTNAME "illucat"
|
||||
#define CONNECT_TIMEOUT 10000
|
||||
|
||||
// config files
|
||||
#define PIXEL_CONFIG_FILE "/pixelConfig.json"
|
||||
#define MQTT_CONFIG_FILE "/mqttConfig.json"
|
||||
#define IRC_CONFIG_FILE "/ircConfig.json"
|
||||
|
||||
// NeoPixel
|
||||
#define LED_STRIP_PIN D2
|
||||
#define LED_STRIP_LENGTH 8
|
||||
#define LED_STRIP_BRIGHTNESS 48
|
||||
#define LED_STRIP_UPDATE_INTERVAL 200
|
||||
#define LED_STRIP_DEFAULT_COLOR 100
|
||||
#define COLOR_CONNECTED LED_STRIP_DEFAULT_COLOR
|
||||
#define COLOR_NOT_CONNECTED 255
|
||||
|
||||
#define IRC_SERVER "chat.freenode.net"
|
||||
#define IRC_PORT 6665
|
||||
#define IRC_NICKNAME ""
|
||||
#define IRC_USER ""
|
||||
|
||||
// OTA config
|
||||
#define OTA_PORT 8266
|
||||
#define OTA_PASSWORD ""
|
||||
|
||||
// WebServer
|
||||
#define WEB_CONTEXT_PATH "/"
|
||||
#define WEB_DOC_ROOT "/www"
|
||||
#define WEB_DEFAULT_FILE "index.html"
|
||||
#define WEB_PORT 80
|
||||
|
||||
// mqtt config
|
||||
#define MQTT_CLIENT_NAME "illucat"
|
||||
#define MQTT_HOST "192.168.1.2"
|
||||
#define MQTT_PORT 1883
|
||||
#define MQTT_ROOT_TOPIC "wirelos/led/illucat"
|
||||
|
||||
|
||||
#endif
|
||||
78
src/var/illuchat/main.cpp
Normal file
78
src/var/illuchat/main.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "illuchat_config.h"
|
||||
#include <WiFiNet.h>
|
||||
#include <Sprocket.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <WebServerConfig.h>
|
||||
#include <WebServerPlugin.h>
|
||||
#include <WebConfigPlugin.h>
|
||||
#include <WebApiPlugin.h>
|
||||
#include <PixelPlugin.h>
|
||||
#include <IrcPlugin.h>
|
||||
#include <MqttPlugin.h>
|
||||
|
||||
WiFiNet *network;
|
||||
Sprocket *sprocket;
|
||||
WebServerPlugin *webServerPlugin;
|
||||
WebConfigPlugin *webConfigPlugin;
|
||||
WebApiPlugin *webApiPlugin;
|
||||
PixelPlugin *pixelPlugin;
|
||||
IrcPlugin *ircPlugin;
|
||||
MqttPlugin *mqttPlugin;
|
||||
|
||||
void setup()
|
||||
{
|
||||
const char *chipName = String("Sprocket" + String(ESP.getChipId())).c_str();
|
||||
sprocket = new Sprocket({STARTUP_DELAY, SERIAL_BAUD_RATE});
|
||||
pixelPlugin = new PixelPlugin({LED_STRIP_PIN, LED_STRIP_LENGTH, LED_STRIP_BRIGHTNESS, LED_STRIP_UPDATE_INTERVAL});
|
||||
ircPlugin = new IrcPlugin({IRC_SERVER, IRC_PORT, chipName, chipName});
|
||||
mqttPlugin = new MqttPlugin({MQTT_CLIENT_NAME, MQTT_HOST, MQTT_PORT, MQTT_ROOT_TOPIC});
|
||||
webServerPlugin = new WebServerPlugin({WEB_CONTEXT_PATH, WEB_DOC_ROOT, WEB_DEFAULT_FILE, WEB_PORT});
|
||||
webConfigPlugin = new WebConfigPlugin(webServerPlugin->server);
|
||||
webApiPlugin = new WebApiPlugin(webServerPlugin->server);
|
||||
|
||||
sprocket->addPlugin(pixelPlugin);
|
||||
sprocket->addPlugin(webServerPlugin);
|
||||
sprocket->addPlugin(webConfigPlugin);
|
||||
sprocket->addPlugin(webApiPlugin);
|
||||
sprocket->addPlugin(ircPlugin);
|
||||
sprocket->addPlugin(mqttPlugin);
|
||||
|
||||
network = new WiFiNet(
|
||||
WIFI_MODE,
|
||||
STATION_SSID,
|
||||
STATION_PASSWORD,
|
||||
AP_SSID,
|
||||
AP_PASSWORD,
|
||||
HOSTNAME,
|
||||
CONNECT_TIMEOUT);
|
||||
network->connect();
|
||||
|
||||
webServerPlugin->server->serveStatic(PIXEL_CONFIG_FILE, SPIFFS, "pixelConfig.json");
|
||||
webServerPlugin->server->serveStatic(IRC_CONFIG_FILE, SPIFFS, "ircConfig.json");
|
||||
webServerPlugin->server->serveStatic(MQTT_CONFIG_FILE, SPIFFS, "mqttConfig.json");
|
||||
|
||||
sprocket->subscribe("irc/connected", [](String msg) {
|
||||
if (atoi(msg.c_str()))
|
||||
{
|
||||
sprocket->subscribe("irc/log", [](String msg) {
|
||||
PRINT_MSG(Serial, "CHAT", String("incoming: " + msg).c_str());
|
||||
webApiPlugin->ws->textAll(msg);
|
||||
});
|
||||
sprocket->subscribe("out/chat/log", [](String msg) {
|
||||
PRINT_MSG(Serial, "CHAT", String("outgoing: " + msg).c_str());
|
||||
sprocket->publish("irc/sendMessage", msg);
|
||||
webApiPlugin->ws->textAll("You:"+msg);
|
||||
});
|
||||
sprocket->publish("chat/connected", "");
|
||||
}
|
||||
});
|
||||
|
||||
sprocket->activate();
|
||||
sprocket->publish("irc/connect","");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
sprocket->loop();
|
||||
yield();
|
||||
}
|
||||
55
src/var/mqcatt/main.cpp
Normal file
55
src/var/mqcatt/main.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include "mqcatt_config.h"
|
||||
#include <WiFiNet.h>
|
||||
#include <Sprocket.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <WebServerConfig.h>
|
||||
#include <WebServerPlugin.h>
|
||||
#include <WebConfigPlugin.h>
|
||||
#include <WebApiPlugin.h>
|
||||
#include <PixelPlugin.h>
|
||||
#include <MqttPlugin.h>
|
||||
|
||||
WiFiNet *network;
|
||||
Sprocket *sprocket;
|
||||
WebServerPlugin *webServerPlugin;
|
||||
WebConfigPlugin *webConfigPlugin;
|
||||
WebApiPlugin *webApiPlugin;
|
||||
PixelPlugin *pixelPlugin;
|
||||
MqttPlugin *mqttPlugin;
|
||||
|
||||
void setup()
|
||||
{
|
||||
sprocket = new Sprocket({STARTUP_DELAY, SERIAL_BAUD_RATE});
|
||||
pixelPlugin = new PixelPlugin({LED_STRIP_PIN, LED_STRIP_LENGTH, LED_STRIP_BRIGHTNESS, LED_STRIP_UPDATE_INTERVAL});
|
||||
mqttPlugin = new MqttPlugin({MQTT_CLIENT_NAME, MQTT_HOST, MQTT_PORT, MQTT_ROOT_TOPIC});
|
||||
webServerPlugin = new WebServerPlugin({WEB_CONTEXT_PATH, WEB_DOC_ROOT, WEB_DEFAULT_FILE, WEB_PORT});
|
||||
webConfigPlugin = new WebConfigPlugin(webServerPlugin->server);
|
||||
webApiPlugin = new WebApiPlugin(webServerPlugin->server);
|
||||
sprocket->addPlugin(pixelPlugin);
|
||||
sprocket->addPlugin(webServerPlugin);
|
||||
sprocket->addPlugin(webConfigPlugin);
|
||||
sprocket->addPlugin(webApiPlugin);
|
||||
sprocket->addPlugin(mqttPlugin);
|
||||
|
||||
network = new WiFiNet(
|
||||
WIFI_MODE,
|
||||
STATION_SSID,
|
||||
STATION_PASSWORD,
|
||||
AP_SSID,
|
||||
AP_PASSWORD,
|
||||
HOSTNAME,
|
||||
CONNECT_TIMEOUT);
|
||||
network->connect();
|
||||
|
||||
webServerPlugin->server->serveStatic(PIXEL_CONFIG_FILE, SPIFFS, "pixelConfig.json");
|
||||
webServerPlugin->server->serveStatic(MQTT_CONFIG_FILE, SPIFFS, "mqttConfig.json");
|
||||
|
||||
sprocket->activate();
|
||||
sprocket->publish("pixels/pattern", "1");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
sprocket->loop();
|
||||
yield();
|
||||
}
|
||||
57
src/var/mqcatt/mqcatt_config.h
Normal file
57
src/var/mqcatt/mqcatt_config.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#ifndef __MQCATT_CONFIG__
|
||||
#define __MQCATT_CONFIG__
|
||||
|
||||
// Scheduler config
|
||||
#define _TASK_SLEEP_ON_IDLE_RUN
|
||||
#define _TASK_STD_FUNCTION
|
||||
#define _TASK_PRIORITY
|
||||
|
||||
// Chip config
|
||||
#define SPROCKET_TYPE "ILLUCAT"
|
||||
#define SERIAL_BAUD_RATE 115200
|
||||
#define STARTUP_DELAY 1000
|
||||
|
||||
// Network config
|
||||
#define WIFI_MODE 0
|
||||
#define WIFI_CHANNEL 11
|
||||
#define AP_SSID "illucat"
|
||||
#define AP_PASSWORD "illumination"
|
||||
#define MESH_PREFIX "illucat-mesh"
|
||||
#define MESH_PASSWORD "th3r31sn0sp00n"
|
||||
#define STATION_SSID "MyAP"
|
||||
#define STATION_PASSWORD "th3r31sn0sp00n"
|
||||
#define HOSTNAME "illucat"
|
||||
#define CONNECT_TIMEOUT 10000
|
||||
|
||||
// config files
|
||||
#define PIXEL_CONFIG_FILE "/pixelConfig.json"
|
||||
#define MQTT_CONFIG_FILE "/mqttConfig.json"
|
||||
|
||||
// NeoPixel
|
||||
#define LED_STRIP_PIN D2
|
||||
#define LED_STRIP_LENGTH 8
|
||||
#define LED_STRIP_BRIGHTNESS 48
|
||||
#define LED_STRIP_UPDATE_INTERVAL 200
|
||||
#define LED_STRIP_DEFAULT_COLOR 100
|
||||
#define COLOR_CONNECTED LED_STRIP_DEFAULT_COLOR
|
||||
#define COLOR_NOT_CONNECTED 255
|
||||
|
||||
|
||||
// OTA config
|
||||
#define OTA_PORT 8266
|
||||
#define OTA_PASSWORD ""
|
||||
|
||||
// mqtt config
|
||||
#define MQTT_CLIENT_NAME "illucat"
|
||||
#define MQTT_HOST "192.168.1.2"
|
||||
#define MQTT_PORT 1883
|
||||
#define MQTT_ROOT_TOPIC "wirelos/illucat"
|
||||
|
||||
// WebServer
|
||||
#define WEB_CONTEXT_PATH "/"
|
||||
#define WEB_DOC_ROOT "/www"
|
||||
#define WEB_DEFAULT_FILE "index.html"
|
||||
#define WEB_PORT 80
|
||||
|
||||
|
||||
#endif
|
||||
29
src/var/wifi/main.cpp
Normal file
29
src/var/wifi/main.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#include "config.h"
|
||||
#include "WiFiNet.h"
|
||||
#include "IlluCat.h"
|
||||
|
||||
WiFiNet *network;
|
||||
IlluCat *sprocket;
|
||||
|
||||
void setup()
|
||||
{
|
||||
sprocket = new IlluCat(
|
||||
{STARTUP_DELAY, SERIAL_BAUD_RATE},
|
||||
{WEB_CONTEXT_PATH, WEB_DOC_ROOT, WEB_DEFAULT_FILE, WEB_PORT});
|
||||
network = new WiFiNet(
|
||||
SPROCKET_MODE,
|
||||
STATION_SSID,
|
||||
STATION_PASSWORD,
|
||||
AP_SSID,
|
||||
AP_PASSWORD,
|
||||
HOSTNAME,
|
||||
CONNECT_TIMEOUT);
|
||||
network->connect();
|
||||
sprocket->activate();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
sprocket->loop();
|
||||
yield();
|
||||
}
|
||||
28
src/var/wifiMesh/main.cpp
Normal file
28
src/var/wifiMesh/main.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "config.h"
|
||||
#include "Sprocket.h"
|
||||
#include <MeshNetworkPlugin.cpp>
|
||||
#include "PixelPlugin.h"
|
||||
|
||||
Sprocket *sprocket;
|
||||
void setup()
|
||||
{
|
||||
sprocket = new Sprocket(
|
||||
{STARTUP_DELAY, SERIAL_BAUD_RATE});
|
||||
sprocket->addPlugin(new PixelPlugin(
|
||||
{LED_STRIP_PIN,
|
||||
LED_STRIP_LENGTH,
|
||||
LED_STRIP_BRIGHTNESS,
|
||||
LED_STRIP_UPDATE_INTERVAL}));
|
||||
sprocket->addPlugin(new MeshNetworkPlugin(
|
||||
{SPROCKET_MODE, WIFI_CHANNEL,
|
||||
MESH_PORT, MESH_PREFIX, MESH_PASSWORD,
|
||||
STATION_SSID, STATION_PASSWORD, HOSTNAME,
|
||||
MESH_DEBUG_TYPES}));
|
||||
sprocket->activate();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
sprocket->loop();
|
||||
yield();
|
||||
}
|
||||
Reference in New Issue
Block a user