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)

- white separator indicates "start of radiation display"

- 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 3, 2020
1 parent 0599416 commit 100b1f9
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 0 deletions.
8 changes: 8 additions & 0 deletions multigeiger/multigeiger.ino
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,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 @@ -356,6 +358,9 @@ void setup()
// OLED-Display
u8x8.begin();

// init RGB LED
indicate(0.0, I_RESET);

// set IO-Pins
pinMode (LED_BUILTIN, OUTPUT);
pinMode (PIN_HV_FET_OUTPUT, OUTPUT);
Expand Down Expand Up @@ -532,6 +537,9 @@ void loop()

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

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

// calculate the radiation over the complete time from start
accumulated_Count_Rate = 0.0;
if (accumulated_time != 0) {
Expand Down
105 changes: 105 additions & 0 deletions multigeiger/status_led.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// 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);

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

static RgbColor last_col = black;

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;
}

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

#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;
int r, g, b;
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:
r = indication & I_CONN_ERROR;
g = indication & I_TEST;
b = indication & I_HV_ERROR;
col = RgbColor(r ? 255 : 0, g ? 255 : 0, b ? 255 : 0);
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

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

// indication value used to reset indications to "all off"
#define I_RESET 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 once from setup() like this:
// indicate(0.0, I_RESET)
// you should call this in regular time intervals [e.g. 1s] from loop() like this:
// indicate(radiation_uSvh, indication)
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 @@ -57,6 +57,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

0 comments on commit 100b1f9

Please sign in to comment.