Skip to content

Instantly share code, notes, and snippets.

@dkarchmer
Last active February 20, 2019 01:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dkarchmer/97934423f3a819b3ad444684131b650a to your computer and use it in GitHub Desktop.
Save dkarchmer/97934423f3a819b3ad444684131b650a to your computer and use it in GitHub Desktop.
PODuino with multi-LED button
/* This project implements a multi-color (LED) button with the following specification:
*
* - Button starts as off, representing everything is good
* - A click changes the button to green and represents a request to start filling up a new order
* - The warehouse control can send a "receive" event, which turns color to light blue
* - Clicking button for more than 3sec resets button to off
* - Double click sets the button to red
*
*/
// You must install the IOTile Bridge.
// See https://github.com/iotile/poduino/blob/master/docs/installation/iotile-arduino-bridge.md
//
#include <IOTileBridgeMega.h>
#define kAttentionPin 39
#define kEventReceivedPin 3
#define kIotileStreamId 10
#define kButtonPin 8
#define kRedPin 7 // Gren Cable
#define kGreenPin 5 // Purple Cable
#define kBluePin 6 // Yellow Cable
#define kStateOff 0
#define kStateWhite 1 // Green for now
#define kStateLBlue 2 // Light Blue
#define kStateRed 3
#define kDebounceDelay 50 // the debounce time; increase if the output flickers
unsigned int currentState = kStateOff;
// onEvent Callback
void onEventReceived(unsigned int event);
// Bridge instantiation
IOTileBridge bridge(kAttentionPin, onEventReceived);
// Variables will change:
int buttonState = HIGH; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned short fastClickCount = 0;
unsigned long button_low_t0 = millis();
/*
* Description: Set LEDs to produce given color.
* Unfortunately, cannot really produce all colors with these LEDs
*/
void rgb(unsigned int red, unsigned int green, unsigned int blue) {
Serial.print("R=");
Serial.print(red);
Serial.print(" G=");
Serial.print(green);
Serial.print(" B=");
Serial.println(blue);
Serial.println("----------------");
analogWrite(kBluePin, blue);
analogWrite(kGreenPin, green);
analogWrite(kRedPin, red);
}
/*
* Description: Given a state, set the right LEDs to achieve a given color.
* Also broadcast the state via the IOTile controller
*/
void handleButtonAction(unsigned int state) {
if (state == kStateOff) {
Serial.println("StateOff - Off");
rgb(255, 255, 255);
} else if (state == kStateWhite) {
Serial.println("StateWhite - Green");
rgb(255, 200, 250);
} else if (state == kStateLBlue) {
Serial.println("StateLBlue - Light Blue");
rgb(255, 244, 220);
} else if (state == kStateRed) {
Serial.println("StateRed - Red");
rgb(100, 255, 255);
}
bridge.sendEvent(kIotileStreamId, state);
}
/*
* Description: Return true if the button has been pressed
*/
boolean buttonPressed(){
boolean press = LOW;
if (digitalRead(kButtonPin)==LOW) {
press = HIGH;
}
return press;
}
/*
* Description: This function will be called every time data is sent via the controller (BLE)
* With a computer with IOTile coretools installed, do
*
* iotile hw --port=bled112 connect 0x1c8 get 11 send_event 1
*
* This will set the state to kStateLBlue and turn on the LEDs to blue
*/
void onEventReceived(unsigned int event)
{
// Event number represents the desired state
// Serial.println("==>");
// Serial.print("onEventReceived: ");
// Serial.println(event);
if (event) {
currentState = kStateLBlue;
} else {
currentState = kStateOff;
}
handleButtonAction(currentState);
}
/*
* Description: Arduino Setup function
*/
void setup() {
pinMode(kEventReceivedPin, OUTPUT);
digitalWrite(kEventReceivedPin, LOW);
bridge.begin();
// Arduino Debug Terminal
Serial.begin(9600);
pinMode(kButtonPin, INPUT);
pinMode(kBluePin, OUTPUT);
pinMode(kGreenPin, OUTPUT);
pinMode(kRedPin, OUTPUT);
rgb(255, 255, 255);
currentState = kStateOff;
handleButtonAction(currentState);
}
/*
* Description: Arduino Loop function
*/
void loop() {
// read the state of the switch into a local variable:
int reading = digitalRead(kButtonPin);
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited long enough
// since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > kDebounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
// process new state if the new button state is HIGH
if (buttonState == HIGH) {
if (millis() - button_low_t0 >= 1800) {
// Pressing button more than 3sec -> Off
currentState = kStateOff;
} else {
if (fastClickCount >= 2) {
currentState = kStateRed;
} else {
currentState = kStateWhite;
}
}
handleButtonAction(currentState);
} else {
if (millis() - button_low_t0 < 500) {
fastClickCount += 1;
} else {
fastClickCount = 1;
}
button_low_t0 = millis();
}
}
}
// save the reading. Next time through the loop, it'll be the lastButtonState:
lastButtonState = reading;
bridge.checkReceivedEvents();
}
config controller
{
# Configure for 50 ms BLE broadcasts (set in 0.625 ms increments)
set 0x0001 to 80 as uint32_t;
}
# Listen to input 10, and copy its values to output 1
on input 10
{
copy => unbuffered 40;
}
# Outputs
broadcast streamer on unbuffered 40;

8kButtons

Configuring the Arduino

The Arduino part has to be configured as follows:

  1. This project assumes that a multi-color LED button is used similar to: adafruit.com
    • The button should be connected to the PODuino's pin 8 (with a pullup resistor)
    • The LEDs should be connected as follows: Green to Pin 5, Blue to Pin 6 and Red to Pin 7
  2. Install the IOTileBridgeMega library on the Arduino IDE. See iotile-arduino-bridge
  3. After installing the IOTileBridgeMega, load the 8kbuttons.ino code into the Arduino IDE and compile (Click "Verify") it to verify is correct.
  4. Connect the PODuino to the USB port, and make sure the Arduino IDE can see it. It should say: "Arduino/Genuino Mega or Mega 2560"
  5. Using the Arduino IDE, click on the "Upload" button to upload the code to the Arduino
  6. At this point, the PODuino should be programmed and the button should work

Configuring the IOTile

The IOTile portion has to be programmed with the right Sensor Graph:

  1. Save the 8kbuttons.sgf file to a folder in your computer and open the terminal on that folder
  2. Install the IOTile coretools using: iotile-coretools
  3. With the IOTile coretools installed, do
pip install --upgrade iotile-core iotile-transport-bled112 iotile-support-firm-arduino-bridge-0 iotile-support-con-nrf52832-2 iotile-support-lib-controller-3
# Replace <UUID> in following line with the ID in your PODuino (Hex number on sticker. Format: 0xYYY)
iotile-sgcompile sensor-graph.sgf -f snippet | iotile hw --port=bled112 connect <UUID> controller sensor_graph

If everything works (no errors), the device is now configured to broadcast the state of the button.

Changing states

You can play with the button to change to the white state (green light - as I was not able to get a white light), double click to go to Red, and click for 3sec to go back to off.

To emulate the gateway sending data to change the state to light blue, go to the IOTile core tool terminal and type

iotile hw --port=bled112 connect 0x1c8 get 11 send_event 1

You should see the light go to blue.

You can also check that the state is broadcasted using:

pip install -U iotile-gateway
# The following may be needed for a Mac to work
pip install -U asciimatics typedargs

iotile config set bled112:active-scan true

# The following should show any IOTile device broadcast data
iotile hw enable_broadcasting watch_broadcasts

Now play with the button to change states and you should see the state change

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment