17 Commits

11 changed files with 180 additions and 26 deletions

10
.gitignore vendored
View File

@ -1,13 +1,7 @@
/Release/
.vscode/
~*
*~
# generated files, will be regenerated by CI script
libraries/includes/configuration.cpp
libraries/includes/configuration.h
# release targets, will be generated by CI script
sketch.esp8266.esp8266.nodemcu.bin
sketch.esp8266.esp8266.nodemcu.elf
sketch/sketch.esp8266.esp8266.nodemcu.bin
sketch/sketch.esp8266.esp8266.nodemcu.elf

View File

@ -4,7 +4,7 @@ stages:
build:
stage: build
image: registry.gitlab.com/wolutator/build-env-arduino:latest
image: registry.hottis.de/dockerized/build-env-arduino:latest
tags:
- hottis
- linux
@ -25,7 +25,7 @@ build:
release:
stage: release
image: registry.gitlab.com/wolutator/base-build-env
image: registry.hottis.de/dockerized/base-build-env
tags:
- hottis
- linux
@ -36,6 +36,10 @@ release:
refs:
- release
script:
- gitlabreleaseuploader.py -p $PRIVATE_TOKEN -i $CI_PROJECT_ID -u $CI_PROJECT_URL
-f sketch.esp8266.esp8266.nodemcu.bin -F releaseInfo.json -T $CI_COMMIT_REF_NAME
- gitlabreleaseuploader.py -p $PRIVATE_TOKEN
-i $CI_PROJECT_ID -u $CI_PROJECT_URL
-f sketch.esp8266.esp8266.nodemcu.bin
-F releaseInfo.json
-T $CI_COMMIT_REF_NAME -c
-I $CI_SERVER_URL

36
build.sh Executable file
View File

@ -0,0 +1,36 @@
#!/bin/bash
if [ "$1" == "" ]; then
echo "Give one of the targets: build, clean, upload"
echo "If you want to use a project directory different"
echo "than the current directory, give it as a second"
echo "argument."
exit 1
fi
if [ "$2" != "" ]; then
PROJECT_DIR=$2
else
PROJECT_DIR=$PWD
fi
if [ "$1" == "build" ]; then
pushd $PROJECT_DIR/libraries/esp8266boilerplate/ConfigGenerator && ./configGen.sh && popd
env ARDUINO_SKETCHBOOK_DIR=$PROJECT_DIR arduino-cli compile --fqbn=esp8266:esp8266:nodemcu $PROJECT_DIR/sketch
cp sketch/sketch.esp8266.esp8266.nodemcu.* .
elif [ "$1" == "clean" ]; then
for D in libraries/includes/configuration.h libraries/includes/configuration.cpp sketch/sketch.esp8266.esp8266.nodemcu.bin sketch/sketch.esp8266.esp8266.nodemcu.elf sketch.esp8266.esp8266.nodemcu.bin sketch.esp8266.esp8266.nodemcu.elf; do
echo -n "About to delete $D ... "
rm $PROJECT_DIR/$D && echo "done"
done
elif [ "$1" == "upload" ]; then
echo "About to upload to device"
esptool.py --port /dev/ttyUSB1 write_flash 0 sketch.esp8266.esp8266.nodemcu.bin
else
echo "Unknown subcommand '$1'"
exit 1
fi

View File

@ -8,7 +8,7 @@
#ifndef DEFINES_H_
#define DEFINES_H_
#define DEBUG
// #define DEBUG
@ -41,7 +41,7 @@
#endif
#endif
#define NUM_OF_LEDs 32
#define NUM_OF_LEDs 300
#endif /* DEFINES_H_ */

View File

@ -1,4 +1,82 @@
export ARDUINO_SKETCHBOOK_DIR=~/rgbled
arduino-cli compile --debug --fqbn=esp8266:esp8266:nodemcu ~/rgbled/sketch
# RgbLed - A Project and a Sample Project for multiple concepts
## The Project itself
This thing serves as a controller for smart RGB leds like WS2811, WS2812, PL9823 or others. For this purpose it utilizes the Adafruit Neopixel library.
It receives commands via MQTT to send related code sequences to chains of those leds. It supports two commands, which it receives via two MQTT topics it subscribes.
The simple ``command`` accepts one or two arguments. When only one argument is given, this argument has to be a number between 0 and 255 and is interpreted as brightness. All three colors of all connected leds are driven with that value. When two arguments are given, the first argument is interpreted as the number of the led to drive, starting with 0 and the second argument is again the brightness.
The ``colorCommand`` accepts one, two, three or four arguments. With only one argument, this argument is interpreted as a color word (on or white, off, warmwhite, red, green, blue, purple, yellow). All connected leds will be driven with the given color combination. With two arguments, the first one is the led number, the second one is the color word. Three arguments have to be 8 bit numbers to control the color channels of all connected leds. With four arguments the first argument is the led number, the remaining three are again red, green and blue values.
## Sample Project for ...
### ... a project to be used together with the ``build-env-arduino`` docker image
The ``build-env-arduino`` docker image, which can be loaded using the image name ``registry.gitlab.com/wolutator/build-env-arduino:latest`` is a tinned or preserved build environment for boards supported by the Arduino development system. Currently ``arduino:avr`` and ``esp8266:esp8266`` are supported by this image.
It is maintained in to the project [https://gitlab.com/wolutator/build-env-arduino].
A preserved build environment, which easily can be installed or simply loaded for many developers in exactly the same way and which can easily be archived is a major topic is professional software engineering. If you have a team of lots of developers you don't want to waste time by letting everyone install his or her development environment manually, finally ending up with minor to major differences which makes it hard to compare or integrate software or let one developer investigate a bug another developer found. Furthermore you want to be able, especially in an industrial environment, to pick a development environment from the shelve to investigate and fix an issue reported in a years-old software. Both can be achieved with preserved environments.
This preserved Arduino build environment uses the Arduino CLI tool, which can be found at [https://downloads.arduino.cc/arduino-cli/arduino-cli-latest-linux64.tar.bz2] and which is discussed here [https://blog.arduino.cc/2018/08/24/announcing-the-arduino-command-line-interface-cli/].
This Arduino CLI tool expects your projects to be stored in the common ``sketchbook`` folder, where also the common (used by all projects) ``libraries`` folder is located. This is not my cup of tea. You want my projects separated from each other, together with all dependent libraries.
So, I created the following directory structure of my project repository:
RepoRoot/
|
+--- sketch/
| |
| +--- sketch.ino
| +--- application.cpp
| +--- application.h
|
+--- libraries/
| |
| +--- library1/
| |
| +--- library2/
| |
| +--- includes/
|
+--- .gitignore
+--- .gitlab-ci.yml
+--- readme.md
To make the Arduino CLI use this structure, I point the variable ``ARDUINO_SKETCHBOOK_DIR`` to it, so the commandline to build a project is
env ARDUINO_SKETCHBOOK_DIR=$PROJECT_DIR arduino-cli compile --fqbn=esp8266:esp8266:nodemcu $PROJECT_DIR/sketch
The Arduino system expects a file with the extension ``.ino`` and same name as the directory within the sketchbook directory. Since in my setup every project lifes in a separate sketchbook directory, I call the directory with the main application sources ``sketch`` and the accordingly the ``ino``-file ``sketch.ino``. This file contain the typical main functions of each Arduino project, which are ``setup`` and ``loop``.
In my projects, I do not put any meaningful code into the ``ino``, I have everything in the companion ``cpp`` file, which is usually ``application.cpp`` (with its friend ``application.h``)
When the Arduino system trys to find some included ``.h`` it has a powerful strategy, which works without any ``CFLAGS`` variable with ``-I`` options. It works just by convention. Thus, it searches in the Arduino core folders, in the ``sketch`` folder itself and in all subfolders of the ``libraries`` folder. For this reason I put a ``includes`` folder into the ``libraries`` folder where I place all header files, which are shared between the main application (the "sketch") and some libraries.
This approach can easily be implemented in a Gitlab CI script:
build:
stage: build
image: registry.gitlab.com/wolutator/build-env-arduino:latest
variables:
GIT_SUBMODULE_STRATEGY: recursive
artifacts:
paths:
- sketch.esp8266.esp8266.nodemcu.bin
script:
- env ARDUINO_SKETCHBOOK_DIR=$CI_PROJECT_DIR arduino-cli compile --fqbn=esp8266:esp8266:nodemcu $CI_PROJECT_DIR/sketch
- cp sketch/sketch.esp8266.esp8266.nodemcu.* .
### Uploading to the target
In a final step the CI script will put the generated firmware binary into the Gitlab release area.
It can be downloaded there and uploaded to the device using the ``esptool.py``.
esptool.py -p /dev/ttyUSB0 write_flash 0x0 sketch.esp8266.esp8266.nodemcu.bin

View File

@ -1,8 +1,8 @@
{
"releaseTag": "v1.0.3",
"releaseTag": "v1.0.8",
"createReleaseTag": "true",
"releaseName": "more LEDs",
"description": "supports up to 32 LEDs"
"releaseName": "colorPattern and watchdog",
"description": "introduce the colorPattern config option (swap R and G) and use the mqtt boilerplate code with watchdog support"
}

View File

@ -11,8 +11,10 @@ configItems = [
{"label":"MQTT Topic Color Command", "key":"mqttTopicColorCommand", "type":"C", "length":64, "default":"IoT/RgbLed1/ColorCommand"},
{"label":"MQTT Topic Command", "key":"mqttTopicCommand", "type":"C", "length":64, "default":"IoT/RgbLed1/Command"},
{"label":"MQTT DebugTopic", "key":"mqttDebugTopic", "type":"C", "length":64, "default":"IoT/RgbLed1/Debug"},
{"label":"MQTT WatchdogTopic", "key":"mqttWatchdogTopic", "type":"C", "length":64, "default":"IoT/Watchdog"},
{"label":"Color pattern (rgb=0, grb=1", "key":"colorPattern", "type":"I", "default":0},
{"label":"DebugMode", "key":"debugMode", "type":"I", "default":0}
]
magic = 3235774470
magic = 3235774471
appName = "ESP8266 based RGB-LED-Light"

View File

@ -102,9 +102,25 @@ void subscribeApplication() {
static void setColor(int8_t ledNumber, uint8_t red, uint8_t green, uint8_t blue) {
static void setColor(int16_t ledNumber, uint8_t x, uint8_t y, uint8_t z) {
uint8_t red, green, blue;
switch (configBlock.colorPattern) {
case 1:
red = y;
green = x;
blue = z;
break;
case 0:
default:
red = x;
green = y;
blue = z;
break;
}
if (ledNumber == -1) {
for (uint8_t i = 0; i < NUM_OF_LEDs; i++) {
for (uint16_t i = 0; i < NUM_OF_LEDs; i++) {
#ifdef WS2811
leds[i].r = red;
leds[i].g = green;
@ -188,13 +204,14 @@ void callbackApplication(char *topic, uint8_t tokenCnt, char **tokens) {
void setupApplication() {
mqttSetup();
#ifdef WS2811
FastLED.addLeds<NEOPIXEL, PIXEL_PIN>(leds, NUM_OF_LEDs);
#endif
#ifdef PL9823
pixels.begin();
for (uint8_t i = 0; i < NUM_OF_LEDs; i++) {
for (uint16_t i = 0; i < NUM_OF_LEDs; i++) {
pixels.setPixelColor(i, pixels.Color(0,0,0));
}
pixels.show();

23
test/test.py Normal file
View File

@ -0,0 +1,23 @@
import paho.mqtt.client as mqtt
RGB_TOPIC = 'IoT/RgbLedStripe/ColorCommand'
client = mqtt.Client(client_id = 'test1')
client.connect("172.16.2.16", 1883, 60)
i = 0
while True:
client.loop()
i += 1
if i == 300:
i = 0
client.publish(RGB_TOPIC, "{0} 0 0 255".format(i))
client.publish(RGB_TOPIC, "{0} 0 255 0".format(i+1))
client.publish(RGB_TOPIC, "{0} 255 0 0".format(i+2))
client.publish(RGB_TOPIC, "{0} 0 0 0".format(i))