Skip to content

Commit

Permalink
add optional support for WS2812 RGB LED, fixes #106
Browse files Browse the repository at this point in the history
specific indexes in the LED color time sequence are used for:

- dark separator indicates "start of sequence"
  (also used for LED init and re-init)

- color according to indications (3bits encoded via RGB color)
  (can be extended to show up to 32 indication bits)
  (dark if there is nothing to indicate)

- white separator indicates "start of radiation display"
  (also works as LED test, white = R on + G on + B on)

- color according to radiation (repeated, displayed most of the time)
  dark (unusually low / 0)
  green (normal)
  yellow (more than normal)
  red (much more than normal)
  • Loading branch information
ThomasWaldmann committed Feb 16, 2020
1 parent 8167eb7 commit b3d5503
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 0 deletions.
5 changes: 5 additions & 0 deletions multigeiger/multigeiger.ino
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

// for RGB LED
#include "status_led.h"

// Check if a CPU (board) with LoRa is selected. If not, deactivate SEND2LORA.
#if !((CPU==LORA) || (CPU==STICK))
Expand Down Expand Up @@ -553,6 +555,9 @@ void loop() {

Dose_Rate = Count_Rate * GMC_factor_uSvph; // ... and dose rate

// indicate status on RGB LED (if any)
indicate(Dose_Rate, I_TEST);

// calculate the radiation over the complete time from start
accumulated_Count_Rate = 0.0;
if (accumulated_time != 0) {
Expand Down
107 changes: 107 additions & 0 deletions multigeiger/status_led.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// show status indication via WS2812 RGB LED

#include "userdefines.h"

#if STATUS_LED==1 // we have a WS2812 RGB LED!

#include <NeoPixelBus.h>

#include "status_led.h"

#define PIXEL_COUNT 1
#define PIXEL_PIN 25

RgbColor red(255, 0, 0);
RgbColor green(0, 255, 0);
RgbColor blue(0, 0, 255);
RgbColor yellow(255, 255, 0);
RgbColor white(255, 255, 255);
RgbColor black(0, 0, 0);

static NeoPixelBus<NeoRgbFeature, Neo800KbpsMethod> LEDs(PIXEL_COUNT, PIXEL_PIN);

static RgbColor last_col = black;

static void set_LED(RgbColor col) {
if (col == last_col)
return; // nothing to change

LEDs.SetPixelColor(0, col); // only 1 LED at index 0
LEDs.Show();
last_col = col;
}

static void init_LED(void) {
LEDs.Begin(); // all LEDs off
LEDs.Show();
last_col = black; // consistency sw state == hw state
}

static void compute_color(unsigned int indication,
unsigned int mask_r, unsigned int mask_g, unsigned int mask_b,
RgbColor *color) {
// assign to *color depending on whether the r/g/b masked bits are set in the indication value
*color = RgbColor((indication & mask_r) ? 255 : 0,
(indication & mask_g) ? 255 : 0,
(indication & mask_b) ? 255 : 0)
}

#define IDX_W 2
#define CSL 30

void indicate(float radiation, unsigned int indication) {
// radiation [uSv/h] given to set the primary color R that is shown most of the time
// indication: 32 bit flags to indicate additional stuff, see status_led.h.
//
// this code will generate a time sequence of LED colors:
// index color
// ------------------------------------------------------
// 0 dark (LED init)
// 1 indication color 1
// ... reserved for more indications
// IDX_W white (LED test)
// ...+1 radiation color
// ... radiation color
// CSL-1 radiation color

RgbColor col;
static int index = 0; // index counting modulo COLOR_SEQUENCE_LENGTH

switch (index) {
case 0: // show a fixed dark separator after LED init
init_LED(); // (re-)init the LED
col = black;
break;
case 1:
// indication color 1: R G B
compute_color(indication, I_CONN_ERROR, I_TEST, I_HV_ERROR, &col);
break;
case IDX_W: // show a fixed white separator and LED test
col = white;
break;
default: // show radiation color
if (radiation > 1.0) {
col = red;
} else if (radiation > 0.2) {
col = yellow;
} else if (radiation > 0.01) {
col = green;
} else {
col = black;
}
}

set_LED(col);

if (++index == CSL)
index = 0;
}

#else // no STATUS_LED

void indicate(float radiation, unsigned int indication) {
// do nothing
}

#endif // STATUS_LED

15 changes: 15 additions & 0 deletions multigeiger/status_led.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// show status indication via WS2812 RGB LED

// indication value used to reset indications to "all off"
#define I_RESET 0
// indication value used to mask no bit, e.g. in compute_color
#define I_NONE 0

// indications, values are 32bit bit masks, valid values are 2^N
#define I_TEST 1 // reserved to test the indication code
#define I_HV_ERROR 2 // there is a problem with high voltage generation
#define I_CONN_ERROR 4 // there is a problem with the network connection

// indicate radiation and special indications via a color time sequence.
// you should call this in regular time intervals [e.g. 1s].
void indicate(float radiation, unsigned int indication);
3 changes: 3 additions & 0 deletions multigeiger/userdefines-example.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
// Note: The TTN configuration needs to be done in lorawan.cpp (starting at line 65).
#define SEND2LORA 0

// 0: no RGB status LED, 1: WS2812B status LED
#define STATUS_LED 1

// *********************************************************************************
// END of user changeable parameters. Do not edit beyond this point!
// *********************************************************************************
Expand Down
1 change: 1 addition & 0 deletions platformio-example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ lib_deps=
Adafruit BME280 Library
Adafruit Unified Sensor
IotWebConf
NeoPixelBus

0 comments on commit b3d5503

Please sign in to comment.