diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 86d90fe..c8ed165 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -3,18 +3,13 @@ stages:
cache:
paths:
- - firmware
+ - .piolibdeps
-before_script:
- - "pip install -U platformio"
-
-firmware-build:
+build-examples:
stage: build
- image: python:2.7-stretch
+ image: registry.gitlab.com/wirelos/contraption-pipeline/platformio:v1
script:
- platformio lib --global install painlessMesh ArduinoJson TaskScheduler PubSubClient ESPAsyncTCP AsyncTCP "ESP Async WebServer"
+ - platformio ci --lib="." --board=esp12e src/examples/basic/
- platformio ci --lib="." --board=esp12e src/examples/mesh/
- artifacts:
- paths:
- - .pioenvs/esp12e/firmware.bin
- - .pioenvs/esp12e/spiffs.bin
\ No newline at end of file
+ - platformio ci --lib="." --board=esp12e src/examples/mqttBridge/
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index acf27a5..30a0ad1 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,6 +1,6 @@
{
"terminal.integrated.env.linux": {
- "PATH": "/home/master/.platformio/penv/bin:/home/master/.platformio/penv:/home/master/bin:/home/master/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin",
+ "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",
"PLATFORMIO_CALLER": "vscode"
},
"files.associations": {
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..fe0651c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,8 @@
+# InterCat
+Our entry for the make-zürich 2018 teacher's calling challenge.
+Unfortunately we couldn't get as far as we wanted, so there is no documentation or anything usefull for the uninitiated.
+If you want more information, please contact me directly.
+Maybe we will follow up on the project and add more information, in case someone is interested.
+
+Anyway: all source code is available in the git repository.
+The different mesh node types can be checked out from the branches.
\ No newline at end of file
diff --git a/library.json b/library.json
index fb64f8b..1ec316d 100644
--- a/library.json
+++ b/library.json
@@ -1,7 +1,7 @@
{
"name": "sprocket-core",
"keywords": "esp8266, sprocket, stack",
- "description": "Core stack for sprockets",
+ "description": "Core stack for Sprockets",
"authors":
{
"name": "Patrick Balsiger",
@@ -14,5 +14,12 @@
"url": "https://gitlab.com/wirelos/sprocket-core/"
},
"frameworks": "arduino",
- "platforms": "espressif8266"
+ "platforms": "espressif8266",
+ "examples": "examples/*",
+ "export": {
+ "exclude":
+ [
+ "firmware/"
+ ]
+ }
}
\ No newline at end of file
diff --git a/platformio.ini b/platformio.ini
index 9b9a1c6..972848a 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -9,7 +9,7 @@
; http://docs.platformio.org/page/projectconf.html
[platformio]
-env_default = meshMqttBridge
+env_default = button
[common]
framework = arduino
@@ -22,6 +22,7 @@ lib_deps =
ESP Async WebServer
ESPAsyncTCP
TaskScheduler
+ painlessMesh
[env:build]
src_filter = +<*> -
@@ -34,12 +35,13 @@ upload_speed = ${common.upload_speed}
monitor_baud = ${common.monitor_baud}
framework = ${common.framework}
lib_deps = ${common.lib_deps}
+
#build_flags = -DLED_PIN=2 -g
;upload_port = /dev/ttyUSB0
;upload_port = 192.168.1.168
[env:basic]
-src_filter = +<*> + - -
+src_filter = +<*> - - +
platform = ${common.platform}
board = ${common.board}
upload_speed = ${common.upload_speed}
@@ -48,22 +50,39 @@ framework = ${common.framework}
lib_deps = ${common.lib_deps}
[env:mesh]
-src_filter = +<*> + - -
+src_filter = +<*> - - +
platform = ${common.platform}
board = ${common.board}
upload_speed = ${common.upload_speed}
monitor_baud = ${common.monitor_baud}
framework = ${common.framework}
lib_deps = ${common.lib_deps}
- painlessMesh
[env:meshMqttBridge]
-src_filter = +<*> + - -
+src_filter = +<*> - - +
platform = espressif8266
board = esp12e
upload_speed = ${common.upload_speed}
monitor_baud = ${common.monitor_baud}
framework = ${common.framework}
lib_deps = ${common.lib_deps}
- painlessMesh
- PubSubClient
\ No newline at end of file
+ PubSubClient
+
+[env:illucat]
+src_filter = +<*> - - +
+platform = ${common.platform}
+board = ${common.board}
+upload_speed = ${common.upload_speed}
+monitor_baud = ${common.monitor_baud}
+framework = ${common.framework}
+lib_deps = ${common.lib_deps}
+ Adafruit NeoPixel
+
+[env:button]
+src_filter = +<*> - - +
+platform = ${common.platform}
+board = ${common.board}
+upload_speed = ${common.upload_speed}
+monitor_baud = ${common.monitor_baud}
+framework = ${common.framework}
+lib_deps = ${common.lib_deps}
\ No newline at end of file
diff --git a/src/MeshNet.cpp b/src/MeshNet.cpp
new file mode 100644
index 0000000..92ebfd6
--- /dev/null
+++ b/src/MeshNet.cpp
@@ -0,0 +1,53 @@
+#include "MeshNet.h"
+
+MeshNet::MeshNet(MeshConfig cfg) : Network() {
+ config = cfg;
+}
+
+Network* MeshNet::init(){
+
+ Serial.println("init mesh");
+ //mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on
+ mesh.setDebugMsgTypes( config.debugTypes );
+ mesh.init( config.meshSSID, config.meshPassword, scheduler, config.meshPort, WIFI_AP_STA, config.channel );
+
+ //mesh.onReceive(bind(&MeshNet::receivedCallback,this, _1, _2));
+ mesh.onNewConnection(bind(&MeshNet::newConnectionCallback, this, _1));
+ mesh.onChangedConnections(bind(&MeshNet::changedConnectionCallback, this));
+ mesh.onNodeTimeAdjusted(bind(&MeshNet::nodeTimeAdjustedCallback, this, _1));
+
+ if(config.stationMode){
+ Serial.println("connect station");
+ mesh.stationManual(config.stationSSID, config.stationPassword);
+ mesh.setHostname(config.hostname);
+ }
+
+ return this;
+}
+
+void MeshNet::sendTo(uint32_t target, String msg){
+ mesh.sendSingle(target, msg);
+}
+
+void MeshNet::broadcast(String msg){
+ mesh.sendBroadcast(msg);
+}
+void MeshNet::update(){
+ // only needed when no scheduler was passed to mesh.init
+ mesh.update();
+}
+void MeshNet::receivedCallback( uint32_t from, String &msg ) {
+ Serial.printf("--> Received from %u msg=%s\n", from, msg.c_str());
+}
+
+void MeshNet::newConnectionCallback(uint32_t nodeId) {
+ Serial.printf("--> New Connection, nodeId = %u\n", nodeId);
+}
+
+void MeshNet::changedConnectionCallback() {
+ Serial.printf("--> Changed connections %s\n",mesh.subConnectionJson().c_str());
+}
+
+void MeshNet::nodeTimeAdjustedCallback(int32_t offset) {
+ Serial.printf("--> Adjusted time %u. Offset = %d\n", mesh.getNodeTime(),offset);
+}
\ No newline at end of file
diff --git a/src/MeshNet.h b/src/MeshNet.h
index 93ada93..1275655 100644
--- a/src/MeshNet.h
+++ b/src/MeshNet.h
@@ -4,6 +4,7 @@
#include
#include
#include "Network.h"
+
using namespace std;
using namespace std::placeholders;
@@ -22,59 +23,18 @@ struct MeshConfig {
class MeshNet : public Network {
public:
painlessMesh mesh;
-
MeshConfig config;
- MeshNet(MeshConfig cfg) : Network() {
- config = cfg;
- }
-
- Network* init(){
-
- Serial.println("init mesh");
- //mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on
- mesh.setDebugMsgTypes( config.debugTypes );
- mesh.init( config.meshSSID, config.meshPassword, scheduler, config.meshPort, WIFI_AP_STA, config.channel );
-
- //mesh.onReceive(bind(&MeshNet::receivedCallback,this, _1, _2));
- mesh.onNewConnection(bind(&MeshNet::newConnectionCallback, this, _1));
- mesh.onChangedConnections(bind(&MeshNet::changedConnectionCallback, this));
- mesh.onNodeTimeAdjusted(bind(&MeshNet::nodeTimeAdjustedCallback, this, _1));
-
- if(config.stationMode){
- Serial.println("connect station");
- mesh.stationManual(config.stationSSID, config.stationPassword);
- mesh.setHostname(config.hostname);
- }
-
- return this;
- }
- Network* connect(){
- return this;
- }
- void broadcast(String msg){
- mesh.sendBroadcast(msg);
- }
- void update(){
- // only needed when no scheduler was passed to mesh.init
- mesh.update();
- }
- void receivedCallback( uint32_t from, String &msg ) {
- Serial.printf("startHere: Received from %u msg=%s\n", from, msg.c_str());
- }
-
- void newConnectionCallback(uint32_t nodeId) {
- id = nodeId;
- Serial.printf("--> startHere: New Connection, nodeId = %u\n", nodeId);
- }
-
- void changedConnectionCallback() {
- Serial.printf("Changed connections %s\n",mesh.subConnectionJson().c_str());
- }
-
- void nodeTimeAdjustedCallback(int32_t offset) {
- Serial.printf("Adjusted time %u. Offset = %d\n", mesh.getNodeTime(),offset);
- }
+ MeshNet(MeshConfig cfg);
+ Network* init();
+
+ void broadcast(String msg);
+ void sendTo(uint32_t target, String msg);
+ void update(); // only needed when no scheduler was passed to mesh.init
+ void receivedCallback( uint32_t from, String &msg );
+ void newConnectionCallback(uint32_t nodeId);
+ void changedConnectionCallback();
+ void nodeTimeAdjustedCallback(int32_t offset);
};
#endif
\ No newline at end of file
diff --git a/src/Sprocket.cpp b/src/Sprocket.cpp
index 23d180a..2a70fb6 100644
--- a/src/Sprocket.cpp
+++ b/src/Sprocket.cpp
@@ -23,8 +23,7 @@ Sprocket* Sprocket::join(Network& net){
Serial.println("join network");
net.init(&scheduler);
net.connect();
- activate(&scheduler, &net);
- return this;
+ return activate(&scheduler, &net);
}
Sprocket* Sprocket::addTask(Task& tsk){
diff --git a/src/Sprocket.h b/src/Sprocket.h
index b8f9a76..6d485b8 100644
--- a/src/Sprocket.h
+++ b/src/Sprocket.h
@@ -20,11 +20,11 @@ class Sprocket {
Sprocket(SprocketConfig);
Sprocket* init(SprocketConfig);
Sprocket* join(Network&);
- Sprocket* addTask(Task&); // REMOVE ??
+ Sprocket* addTask(Task&);
virtual void loop();
virtual Sprocket* activate();
- virtual Sprocket* activate(Scheduler*) {}
- virtual Sprocket* activate(Scheduler*, Network*) {}
+ virtual Sprocket* activate(Scheduler*) { return this; }
+ virtual Sprocket* activate(Scheduler*, Network*) { return this; }
};
#endif
\ No newline at end of file
diff --git a/src/examples/basic/ExampleApp.h b/src/examples/basic/ExampleApp.h
index a27fdfe..7a21f8d 100644
--- a/src/examples/basic/ExampleApp.h
+++ b/src/examples/basic/ExampleApp.h
@@ -3,7 +3,6 @@
//#include "Sprocket.h"
#include
-#include
#include
using namespace std;
@@ -12,7 +11,7 @@ using namespace std::placeholders;
class ExampleApp : public Sprocket {
public:
Task someTask;
- ExampleApp() {
+ ExampleApp(SprocketConfig cfg) : Sprocket(cfg) {
Serial.println("joo");
}
Sprocket* activate(Scheduler* scheduler) {
diff --git a/src/examples/basic/basic.cpp b/src/examples/basic/basic.cpp
index 8b5f2b1..5eac4d8 100644
--- a/src/examples/basic/basic.cpp
+++ b/src/examples/basic/basic.cpp
@@ -1,21 +1,13 @@
#define _TASK_SLEEP_ON_IDLE_RUN
#define _TASK_STD_FUNCTION
-
-#include
-#include "ExampleApp.h"
-
#define SERIAL_BAUD_RATE 115200
#define STARTUP_DELAY 3000
-SprocketConfig config = { STARTUP_DELAY, SERIAL_BAUD_RATE };
+#include "ExampleApp.h"
-ExampleApp sprocket;
+ExampleApp sprocket({ STARTUP_DELAY, SERIAL_BAUD_RATE });
void setup() {
-
- delay(STARTUP_DELAY);
-
- sprocket.init(config);
sprocket.activate();
}
diff --git a/src/examples/button/Button.h b/src/examples/button/Button.h
new file mode 100644
index 0000000..f26d90a
--- /dev/null
+++ b/src/examples/button/Button.h
@@ -0,0 +1,47 @@
+ #ifndef __MESH_APP__
+#define __MESH_APP__
+
+#include
+#include
+#include
+
+using namespace std;
+using namespace std::placeholders;
+
+class Button : public Sprocket {
+ public:
+ Task btnTask;
+ MeshNet* net;
+ int pin;
+ Button(SprocketConfig cfg) : Sprocket(cfg) {}
+ Sprocket* activate(Scheduler* scheduler, Network* network) {
+ pin = D2;
+ pinMode(pin, INPUT_PULLUP);
+ net = static_cast(network);
+ net->mesh.onReceive(bind(&Button::receivedCallback,this, _1, _2));
+ btnTask.set(TASK_MILLISECOND * 500, TASK_FOREVER,
+ bind(&Button::readPin, this, net));
+ scheduler->addTask(btnTask);
+ btnTask.enable();
+ } using Sprocket::activate;
+
+ void readPin(MeshNet* network){
+ if(digitalRead(pin)){
+ Serial.println("btn pressed");
+ network->broadcast("EE1B2E");
+ }
+ }
+
+ void receivedCallback( uint32_t from, String &msg ) {
+ Serial.printf("button: Received from %u msg=%s\n", from, msg.c_str());
+ // respond in receive callback can cause an endless loop when all nodes run the same firmware
+ //String foo = String("cheerz back to ") + String(from);
+ //net->broadcast(foo);
+ }
+ void loop() {
+ net->update();
+ scheduler.execute();
+ }
+};
+
+#endif
\ No newline at end of file
diff --git a/src/examples/button/config.h b/src/examples/button/config.h
new file mode 100644
index 0000000..c27cb09
--- /dev/null
+++ b/src/examples/button/config.h
@@ -0,0 +1,25 @@
+#ifndef __MESH_CONFIG__
+#define __MESH_CONFIG__
+
+// Scheduler config
+#define _TASK_SLEEP_ON_IDLE_RUN
+#define _TASK_STD_FUNCTION
+
+// Chip config
+#define SERIAL_BAUD_RATE 115200
+#define STARTUP_DELAY 3000
+
+// Mesh config
+#define STATION_MODE 0
+#define WIFI_CHANNEL 11
+#define MESH_PORT 5555
+#define MESH_PREFIX "whateverYouLike"
+#define MESH_PASSWORD "somethingSneaky"
+#define STATION_SSID "Th1ngs4P"
+#define STATION_PASSWORD "th3r31sn0sp00n"
+#define HOSTNAME "mesh-node"
+#define MESH_DEBUG_TYPES ERROR | STARTUP | CONNECTION
+
+#define BUTTON_PIN D2
+
+#endif
\ No newline at end of file
diff --git a/src/examples/button/main.cpp b/src/examples/button/main.cpp
new file mode 100644
index 0000000..061f47f
--- /dev/null
+++ b/src/examples/button/main.cpp
@@ -0,0 +1,20 @@
+#include "config.h"
+#include "MeshNet.h"
+#include "Button.h"
+
+MeshNet net({
+ STATION_MODE, WIFI_CHANNEL,
+ MESH_PORT, MESH_PREFIX, MESH_PASSWORD,
+ STATION_SSID, STATION_PASSWORD, HOSTNAME,
+ MESH_DEBUG_TYPES
+});
+Button sprocket({ STARTUP_DELAY, SERIAL_BAUD_RATE });
+
+void setup() {
+ sprocket.join(net);
+}
+
+void loop() {
+ sprocket.loop();
+ yield();
+}
\ No newline at end of file
diff --git a/src/examples/illucat/Illucat.h b/src/examples/illucat/Illucat.h
new file mode 100644
index 0000000..0991f6c
--- /dev/null
+++ b/src/examples/illucat/Illucat.h
@@ -0,0 +1,45 @@
+#ifndef __MESH_APP__
+#define __MESH_APP__
+
+#include
+#include
+#include
+#include "NeoPattern.h"
+
+using namespace std;
+using namespace std::placeholders;
+
+struct NeoPixelConfig {
+ int pin;
+ int length;
+};
+
+class Illucat : public Sprocket {
+ public:
+ MeshNet* net;
+ NeoPattern* pixels;
+ Illucat(SprocketConfig cfg, NeoPixelConfig pixelCfg) : Sprocket(cfg) {
+ pixels = new NeoPattern(pixelCfg.length, pixelCfg.pin, NEO_GRB + NEO_KHZ800, [](int pixels){});
+ }
+ Sprocket* activate(Scheduler* scheduler, Network* network) {
+ net = static_cast(network);
+ net->mesh.onReceive(bind(&Illucat::messageReceived,this, _1, _2));
+ // TODO default rainbow task
+ } using Sprocket::activate;
+
+ void messageReceived( uint32_t from, String &msg ) {
+ Serial.printf("illucat: received from %u msg=%s\n", from, msg.c_str());
+ setHexColor(msg.c_str());
+ }
+ void setHexColor(const char *hex){
+ int r, g, b;
+ sscanf(hex, "%02x%02x%02x", &r, &g, &b);
+ pixels->ColorSet(pixels->Color(r,g,b));
+ }
+ void loop() {
+ net->update();
+ scheduler.execute();
+ }
+};
+
+#endif
\ No newline at end of file
diff --git a/src/examples/illucat/NeoPattern.h b/src/examples/illucat/NeoPattern.h
new file mode 100644
index 0000000..f2b1a58
--- /dev/null
+++ b/src/examples/illucat/NeoPattern.h
@@ -0,0 +1,304 @@
+#ifndef __NeoPattern_H_INCLUDED__
+#define __NeoPattern_H_INCLUDED__
+
+#include
+
+/**
+ * NeoPattern by Bill Earl
+ * https://learn.adafruit.com/multi-tasking-the-arduino-part-3/overview
+ */
+
+// Pattern types supported:
+enum pattern { NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE };
+// 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; // which pattern is running
+ direction Direction; // direction to run the pattern
+
+ unsigned long Interval; // milliseconds between updates
+ unsigned long lastUpdate; // last update of position
+
+ uint32_t Color1, Color2; // What colors are in use
+ uint16_t TotalSteps; // total number of steps in the pattern
+ uint16_t Index; // current step within the pattern
+ uint16_t completed = 0;
+
+ void (*OnComplete)(int); // Callback on completion of pattern
+
+ // 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)
+ {
+ OnComplete = callback;
+ }
+
+ // Update the pattern
+ void Update()
+ {
+ if((millis() - lastUpdate) > Interval) // time to update
+ {
+ lastUpdate = millis();
+ 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:
+ break;
+ }
+ }
+ }
+
+ // Increment the Index and reset at the end
+ void Increment()
+ {
+ completed = 0;
+ if (Direction == FORWARD)
+ {
+ Index++;
+ if (Index >= TotalSteps)
+ {
+ Index = 0;
+ if (OnComplete != NULL)
+ {
+ completed = 1;
+ OnComplete(numPixels()); // call the comlpetion callback
+ }
+ }
+ }
+ else // Direction == REVERSE
+ {
+ --Index;
+ if (Index <= 0)
+ {
+ Index = TotalSteps-1;
+ if (OnComplete != NULL)
+ {
+ completed = 1;
+ OnComplete(numPixels()); // call the comlpetion callback
+ }
+ }
+ }
+ }
+
+ // 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)
+ {
+ 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
\ No newline at end of file
diff --git a/src/examples/illucat/config.h b/src/examples/illucat/config.h
new file mode 100644
index 0000000..f099c01
--- /dev/null
+++ b/src/examples/illucat/config.h
@@ -0,0 +1,29 @@
+#ifndef __MESH_CONFIG__
+#define __MESH_CONFIG__
+
+// Scheduler config
+#define _TASK_SLEEP_ON_IDLE_RUN
+#define _TASK_STD_FUNCTION
+
+// Chip config
+#define SERIAL_BAUD_RATE 115200
+#define STARTUP_DELAY 3000
+
+// Mesh config
+#define STATION_MODE 0
+#define WIFI_CHANNEL 11
+#define MESH_PORT 5555
+#define MESH_PREFIX "whateverYouLike"
+#define MESH_PASSWORD "somethingSneaky"
+#define STATION_SSID "Th1ngs4P"
+#define STATION_PASSWORD "th3r31sn0sp00n"
+#define HOSTNAME "mesh-node"
+#define MESH_DEBUG_TYPES ERROR | STARTUP | CONNECTION
+
+// illucat
+#define LED_STRIP_PIN D2
+#define LED_STRIP_LENGTH 8
+#define LED_STRIP_BRIGHTNESS 32
+
+
+#endif
\ No newline at end of file
diff --git a/src/examples/illucat/main.cpp b/src/examples/illucat/main.cpp
new file mode 100644
index 0000000..9c12dbf
--- /dev/null
+++ b/src/examples/illucat/main.cpp
@@ -0,0 +1,21 @@
+#include "config.h"
+#include "MeshNet.h"
+#include "Illucat.h"
+
+MeshNet net({
+ STATION_MODE, WIFI_CHANNEL,
+ MESH_PORT, MESH_PREFIX, MESH_PASSWORD,
+ STATION_SSID, STATION_PASSWORD, HOSTNAME,
+ MESH_DEBUG_TYPES
+});
+Illucat sprocket({ STARTUP_DELAY, SERIAL_BAUD_RATE },
+ { LED_STRIP_PIN, LED_STRIP_LENGTH });
+
+void setup() {
+ sprocket.join(net);
+}
+
+void loop() {
+ sprocket.loop();
+ yield();
+}
\ No newline at end of file
diff --git a/src/examples/mesh/MeshApp.h b/src/examples/mesh/MeshApp.h
index ecdc851..8c8d28c 100644
--- a/src/examples/mesh/MeshApp.h
+++ b/src/examples/mesh/MeshApp.h
@@ -12,19 +12,19 @@ class MeshApp : public Sprocket {
public:
Task someTask;
MeshNet* net;
-
+ MeshApp(SprocketConfig cfg) : Sprocket(cfg) {}
Sprocket* activate(Scheduler* scheduler, Network* network) {
net = static_cast(network);
net->mesh.onReceive(bind(&MeshApp::receivedCallback,this, _1, _2));
// add a task that sends stuff to the mesh
someTask.set(TASK_SECOND * 5, TASK_FOREVER,
- bind(&MeshApp::advertise, this, net));
+ bind(&MeshApp::heartbeat, this, net));
scheduler->addTask(someTask);
someTask.enable();
} using Sprocket::activate;
- void advertise(MeshNet* network){
- String msg = "Hi, my name is " + String(network->id);
+ void heartbeat(MeshNet* network){
+ String msg = "{ \"payload \": 1 }";
network->broadcast(msg);
}
diff --git a/src/examples/mesh/config.h b/src/examples/mesh/config.h
new file mode 100644
index 0000000..a9cd7eb
--- /dev/null
+++ b/src/examples/mesh/config.h
@@ -0,0 +1,23 @@
+#ifndef __MESH_CONFIG__
+#define __MESH_CONFIG__
+
+// Scheduler config
+#define _TASK_SLEEP_ON_IDLE_RUN
+#define _TASK_STD_FUNCTION
+
+// Chip config
+#define SERIAL_BAUD_RATE 115200
+#define STARTUP_DELAY 3000
+
+// Mesh config
+#define STATION_MODE 0
+#define WIFI_CHANNEL 11
+#define MESH_PORT 5555
+#define MESH_PREFIX "whateverYouLike"
+#define MESH_PASSWORD "somethingSneaky"
+#define STATION_SSID "Th1ngs4P"
+#define STATION_PASSWORD "th3r31sn0sp00n"
+#define HOSTNAME "mesh-node"
+#define MESH_DEBUG_TYPES ERROR | STARTUP | CONNECTION
+
+#endif
\ No newline at end of file
diff --git a/src/examples/mesh/mesh.cpp b/src/examples/mesh/mesh.cpp
index 05fa00e..655fbbd 100644
--- a/src/examples/mesh/mesh.cpp
+++ b/src/examples/mesh/mesh.cpp
@@ -1,26 +1,17 @@
-#define _TASK_SLEEP_ON_IDLE_RUN
-#define _TASK_STD_FUNCTION
-
-#include "Network.h"
+#include "config.h"
#include "MeshNet.h"
-#include "Sprocket.h"
#include "MeshApp.h"
-#define SERIAL_BAUD_RATE 115200
-#define STARTUP_DELAY 3000
-
-SprocketConfig config = { STARTUP_DELAY, SERIAL_BAUD_RATE };
-
-MeshNet net;
-MeshApp sprocket;
+MeshNet net({
+ STATION_MODE, WIFI_CHANNEL,
+ MESH_PORT, MESH_PREFIX, MESH_PASSWORD,
+ STATION_SSID, STATION_PASSWORD, HOSTNAME,
+ MESH_DEBUG_TYPES
+});
+MeshApp sprocket({ STARTUP_DELAY, SERIAL_BAUD_RATE });
void setup() {
-
- delay(STARTUP_DELAY);
-
- sprocket.init(config);
sprocket.join(net);
-
}
void loop() {
diff --git a/src/examples/mqttBridge/MqttMeshBridge.h b/src/examples/mqttBridge/MqttMeshBridge.h
index 12733d1..9c775e8 100644
--- a/src/examples/mqttBridge/MqttMeshBridge.h
+++ b/src/examples/mqttBridge/MqttMeshBridge.h
@@ -34,16 +34,21 @@ class MqttMeshBridge : public Sprocket {
mqttConfig = cfg;
}
- Sprocket* activate(Scheduler* scheduler, Network* network) {
- Serial.println("activate MQTT bridge");
- net = static_cast(network);
- net->mesh.onReceive(bind(&MqttMeshBridge::receivedCallback,this, _1, _2));
- client = new PubSubClient(mqttConfig.brokerHost, mqttConfig.brokerPort, bind(&MqttMeshBridge::mqttCallback, this, _1, _2, _3), wifiClient);
+ Sprocket* activate(Scheduler* scheduler){
enableConnectTask(scheduler);
enableProcessTask(scheduler);
return this;
}
+ Sprocket* activate(Scheduler* scheduler, Network* network) {
+ Serial.println("activate MQTT bridge");
+ net = static_cast(network);
+ net->mesh.onReceive(bind(&MqttMeshBridge::receivedCallback,this, _1, _2));
+ client = new PubSubClient(mqttConfig.brokerHost, mqttConfig.brokerPort, bind(&MqttMeshBridge::mqttCallback, this, _1, _2, _3), wifiClient);
+ return activate(scheduler);
+ }
+
+ private:
void enableConnectTask(Scheduler* scheduler) {
connectTask.set(TASK_SECOND * 5, TASK_FOREVER, bind(&MqttMeshBridge::connect, this));
scheduler->addTask(connectTask);
diff --git a/src/examples/mqttBridge/bridge.cpp b/src/examples/mqttBridge/bridge.cpp
index 8d6ea77..ed1776a 100644
--- a/src/examples/mqttBridge/bridge.cpp
+++ b/src/examples/mqttBridge/bridge.cpp
@@ -1,30 +1,7 @@
-#define _TASK_SLEEP_ON_IDLE_RUN
-#define _TASK_STD_FUNCTION
-
-#include
+#include "config.h"
+#include "MeshNet.h"
#include "MqttMeshBridge.h"
-// Chip config
-#define SERIAL_BAUD_RATE 115200
-#define STARTUP_DELAY 3000
-
-// Mesh config
-#define STATION_MODE 1
-#define WIFI_CHANNEL 11
-#define MESH_PORT 5555
-#define MESH_PREFIX "whateverYouLike"
-#define MESH_PASSWORD "somethingSneaky"
-#define STATION_SSID "Th1ngs4P"
-#define STATION_PASSWORD "th3r31sn0sp00n"
-#define HOSTNAME "mqtt-mesh-bridge"
-#define MESH_DEBUG_TYPES ERROR | STARTUP | CONNECTION
-
-// Bridge config
-#define MQTT_CLIENT_NAME HOSTNAME
-#define MQTT_BROKER "iot.eclipse.org"
-#define MQTT_PORT 1883
-#define MQTT_TOPIC_ROOT "mesh/"
-
MeshNet net({
STATION_MODE, WIFI_CHANNEL,
MESH_PORT, MESH_PREFIX, MESH_PASSWORD,
diff --git a/src/examples/mqttBridge/config.h b/src/examples/mqttBridge/config.h
new file mode 100644
index 0000000..67b0c67
--- /dev/null
+++ b/src/examples/mqttBridge/config.h
@@ -0,0 +1,29 @@
+#ifndef __BRIDGE_CONFIG__
+#define __BRIDGE_CONFIG__
+
+// Scheduler config
+#define _TASK_SLEEP_ON_IDLE_RUN
+#define _TASK_STD_FUNCTION
+
+// Chip config
+#define SERIAL_BAUD_RATE 115200
+#define STARTUP_DELAY 3000
+
+// Mesh config
+#define STATION_MODE 1
+#define WIFI_CHANNEL 11
+#define MESH_PORT 5555
+#define MESH_PREFIX "wirelos_contraption"
+#define MESH_PASSWORD "th3r31sn0sp00n"
+#define STATION_SSID "Th1ngs4P"
+#define STATION_PASSWORD "th3r31sn0sp00n"
+#define HOSTNAME "sprocket"
+#define MESH_DEBUG_TYPES ERROR | STARTUP | CONNECTION
+
+// Bridge config
+#define MQTT_CLIENT_NAME HOSTNAME
+#define MQTT_BROKER "citadel.lan"
+#define MQTT_PORT 1883
+#define MQTT_TOPIC_ROOT "mesh"
+
+#endif
\ No newline at end of file
diff --git a/src/firmware/BaseSprocket.h b/src/firmware/BaseSprocket.h
new file mode 100644
index 0000000..9cb0398
--- /dev/null
+++ b/src/firmware/BaseSprocket.h
@@ -0,0 +1,38 @@
+#ifndef __BASE_SPROCKET__
+#define __BASE_SPROCKET__
+
+#include
+#include
+
+using namespace std;
+using namespace std::placeholders;
+
+// TODO remove someTask and replace with OTA stuff
+class BaseSprocket : public Sprocket {
+ public:
+ Task someTask;
+ MeshNet* net;
+ BaseSprocket(SprocketConfig cfg) : Sprocket(cfg) {
+
+ }
+ Sprocket* activate(Scheduler* scheduler, Network* network) {
+ net = static_cast(network);
+ net->mesh.onReceive(bind(&BaseSprocket::receivedCallback,this, _1, _2));
+ // add a task that sends stuff to the mesh
+ someTask.set(TASK_SECOND * 5, TASK_FOREVER,
+ bind(&BaseSprocket::heartbeat, this, net));
+ scheduler->addTask(someTask);
+ someTask.enable();
+ } using Sprocket::activate;
+
+ void heartbeat(MeshNet* network){
+ String msg = "{ \"alive \": 1 }";
+ network->broadcast(msg);
+ }
+
+ virtual void receivedCallback( uint32_t from, String &msg ) {
+ Serial.printf("RECV %u = %s\n", from, msg.c_str());
+ }
+};
+
+#endif
\ No newline at end of file
diff --git a/src/firmware/config.h b/src/firmware/config.h
new file mode 100644
index 0000000..0a19cd1
--- /dev/null
+++ b/src/firmware/config.h
@@ -0,0 +1,28 @@
+#ifndef __BRIDGE_CONFIG__
+#define __BRIDGE_CONFIG__
+
+// Scheduler config
+#define _TASK_SLEEP_ON_IDLE_RUN
+#define _TASK_STD_FUNCTION
+
+// Chip config
+#define SERIAL_BAUD_RATE 115200
+#define STARTUP_DELAY 3000
+
+// Mesh config
+#define STATION_MODE 0 // 1 = connect to AP using STATION params
+#define WIFI_CHANNEL 11
+#define MESH_PORT 5555
+#define MESH_PREFIX "wirelos_contraption"
+#define MESH_PASSWORD "th3r31sn0sp00n"
+#define STATION_SSID "Th1ngs4P"
+#define STATION_PASSWORD "th3r31sn0sp00n"
+#define HOSTNAME "sprocket"
+#define MESH_DEBUG_TYPES ERROR | STARTUP | CONNECTION
+
+#define MQTT_CLIENT_NAME HOSTNAME
+#define MQTT_BROKER "citadel.lan"
+#define MQTT_PORT 1883
+#define MQTT_TOPIC_ROOT "mesh"
+
+#endif
\ No newline at end of file
diff --git a/src/firmware/main.cpp b/src/firmware/main.cpp
new file mode 100644
index 0000000..ab78d91
--- /dev/null
+++ b/src/firmware/main.cpp
@@ -0,0 +1,23 @@
+#include "config.h"
+#include "MeshNet.h"
+#include "BaseSprocket.h"
+
+MeshNet net({
+ STATION_MODE, WIFI_CHANNEL,
+ MESH_PORT, MESH_PREFIX, MESH_PASSWORD,
+ STATION_SSID, STATION_PASSWORD, HOSTNAME,
+ MESH_DEBUG_TYPES
+});
+
+BaseSprocket sprocket(
+ { STARTUP_DELAY, SERIAL_BAUD_RATE }
+);
+
+void setup() {
+ sprocket.join(net);
+}
+
+void loop() {
+ sprocket.loop();
+ yield();
+}
\ No newline at end of file