Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 21 additions & 26 deletions firmware/src/IRKit/FullColorLed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,58 +17,53 @@
#include <Arduino.h>
#include "FullColorLed.h"
#include "timer.h"
#include "pins.h"

FullColorLed::FullColorLed(int pinR, int pinG, int pinB) :
pinR_(pinR),
pinG_(pinG),
pinB_(pinB),
FullColorLed::FullColorLed() :
blinkOn_(0),
isBlinking_(false),
blinkMode_(ALWAYS_ON),
blink_timer_(TIMER_OFF)
{
}

void FullColorLed::setLedColor(bool colorR, bool colorG, bool colorB) {
setLedColor(colorR, colorG, colorB, false);
}

void FullColorLed::setLedColor(bool colorR, bool colorG, bool colorB, bool blink) {
void FullColorLed::setLedColor(bool colorR, bool colorG, bool colorB, LightMode lightMode, uint8_t blinkTimeout) {
colorR_ = colorR;
colorG_ = colorG;
colorB_ = colorB;
isBlinking_ = blink;
blinkMode_ = lightMode;

blink_timer_ = TIMER_OFF;
}

void FullColorLed::setLedColor(bool colorR, bool colorG, bool colorB, bool blink, uint8_t blink_timeout) {
setLedColor( colorR, colorG, colorB, blink );

TIMER_START(blink_timer_, blink_timeout);
if (blinkTimeout > 0) {
TIMER_START(blink_timer_, blinkTimeout);
}
}

void FullColorLed::off() {
setLedColor( 0, 0, 0, false );
setLedColor( 0, 0, 0 );
}

void FullColorLed::onTimer() {
blinkOn_ = ! blinkOn_;

if ( blinkOn_ || ! isBlinking_ ) {
if ( blinkOn_ || (blinkMode_ == ALWAYS_ON) ) {
// not blinking = always on
digitalWrite(pinR_, colorR_);
digitalWrite(pinG_, colorG_);
digitalWrite(pinB_, colorB_);
digitalWrite(FULLCOLOR_LED_R, colorR_);
digitalWrite(FULLCOLOR_LED_G, colorG_);
digitalWrite(FULLCOLOR_LED_B, colorB_);
}
else {
digitalWrite(pinR_, LOW);
digitalWrite(pinG_, LOW);
digitalWrite(pinB_, LOW);
digitalWrite(FULLCOLOR_LED_R, LOW);
digitalWrite(FULLCOLOR_LED_G, LOW);
digitalWrite(FULLCOLOR_LED_B, LOW);
}

TIMER_TICK(blink_timer_);
if (TIMER_FIRED(blink_timer_)) {
TIMER_STOP(blink_timer_);
isBlinking_ = false;
if (blinkMode_ == BLINK_THEN_OFF) {
off();
} else if (blinkMode_ == BLINK_THEN_ON) {
blinkMode_ = ALWAYS_ON;
}
}
}
29 changes: 21 additions & 8 deletions firmware/src/IRKit/FullColorLed.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,34 @@
class FullColorLed
{
public:
FullColorLed(int pinR, int pinG, int pinB);
void setLedColor(bool colorR, bool colorG, bool colorB);
void setLedColor(bool colorR, bool colorG, bool colorB, bool blink);
void setLedColor(bool colorR, bool colorG, bool colorB, bool blink, uint8_t blink_timeout);

// The different modes for lighting the LED
typedef enum {
ALWAYS_ON = 0, // LED stays always on.
BLINK_THEN_ON = 1, // LED blinks, then stays on.
BLINK_THEN_OFF = 2 // LED blinks, then turns off.
} LightMode;

FullColorLed();

// Lights-up the LED with a specific color, with optional blinking parameters.
void setLedColor(
bool colorR,
bool colorG,
bool colorB,
LightMode lightMode = ALWAYS_ON,
uint8_t blinkTimeout = 0);

// Turns-off the LED
void off();

void onTimer();

private:
int pinR_;
int pinG_;
int pinB_;
bool colorR_;
bool colorG_;
bool colorB_;
bool isBlinking_; // defaults to off
LightMode blinkMode_; // defaults to ALWAYS_ON
volatile bool blinkOn_; // altered inside timer ISR
volatile uint8_t blink_timer_;
};
Expand Down
69 changes: 51 additions & 18 deletions firmware/src/IRKit/IRKit.ino
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@
#include "commands.h"
#include "version.h"
#include "log.h"
#include "config.h"

static struct long_press_button_state_t long_press_button_state;
static volatile uint8_t reconnect_timer = TIMER_OFF;
static char commands_data[COMMAND_QUEUE_SIZE];
static FullColorLed color( FULLCOLOR_LED_R, FULLCOLOR_LED_G, FULLCOLOR_LED_B );
static FullColorLed color;

struct RingBuffer commands;
GSwifi gs(&Serial1X);
Expand All @@ -59,7 +60,9 @@ void setup() {
pinMode(FULLCOLOR_LED_R, OUTPUT);
pinMode(FULLCOLOR_LED_G, OUTPUT);
pinMode(FULLCOLOR_LED_B, OUTPUT);
color.setLedColor( 1, 0, 0, false ); // red: error
if (config::ledFeedback < config::LED_OFF) {
color.setLedColor( 1, 0, 0, FullColorLed::ALWAYS_ON ); // red: error
}

//--- initialize long press button

Expand Down Expand Up @@ -163,7 +166,7 @@ void wifi_hardware_reset () {
}

void long_pressed() {
color.setLedColor( 1, 0, 0, false ); // red: error
color.setLedColor( 1, 0, 0, FullColorLed::ALWAYS_ON ); // red: error

keys.clear();
keys.save();
Expand Down Expand Up @@ -211,7 +214,14 @@ void process_commands() {
}

void on_irkit_ready() {
color.setLedColor( 0, 0, 1, false ); // blue: ready
// blue: ready
if (config::ledFeedback <= config::LED_VERBOSE) {
color.setLedColor( 0, 0, 1, FullColorLed::ALWAYS_ON );
} else if (config::ledFeedback <= config::LED_QUIET) {
color.setLedColor( 0, 0, 1, FullColorLed::BLINK_THEN_OFF, 1);
} else {
color.off();
}
}

void on_ir_receive() {
Expand All @@ -226,14 +236,24 @@ void on_ir_receive() {
}
int8_t cid = irkit_httpclient_post_messages();
if (cid >= 0) {
color.setLedColor( 0, 0, 1, true, 1 ); // received: blue blink for 1sec
if (config::ledFeedback <= config::LED_QUIET) {
FullColorLed::LightMode lightMode = (config::ledFeedback == config::LED_VERBOSE)? FullColorLed::BLINK_THEN_ON : FullColorLed::BLINK_THEN_OFF;
color.setLedColor( 0, 0, 1, lightMode, 1 ); // received: blue blink for 1sec
} else {
color.off();
}
}
}
}

void on_ir_xmit() {
MAINLOG_PRINTLN("i>");
color.setLedColor( 0, 0, 1, true, 1 ); // xmit: blue blink for 1sec
if (config::ledFeedback <= config::LED_QUIET) {
FullColorLed::LightMode lightMode = (config::ledFeedback == config::LED_VERBOSE)? FullColorLed::BLINK_THEN_ON : FullColorLed::BLINK_THEN_OFF;
color.setLedColor( 0, 0, 1, lightMode, 1 ); // xmit: blue blink for 1sec
} else {
color.off();
}
}

// inside ISR, be careful
Expand Down Expand Up @@ -272,15 +292,19 @@ void connect() {
keys.load();

if (keys.isWifiCredentialsSet()) {
color.setLedColor( 0, 1, 0, true ); // green blink: connecting
if (config::ledFeedback < config::LED_OFF) {
color.setLedColor( 0, 1, 0, FullColorLed::BLINK_THEN_ON ); // green blink: connecting
}

gs.join(keys.getSecurity(),
keys.getSSID(),
keys.getPassword());
}

if (gs.isJoined()) {
color.setLedColor( 0, 1, 1, true ); // cyan blink: setting up
if (config::ledFeedback < config::LED_OFF) {
color.setLedColor( 0, 1, 1, FullColorLed::BLINK_THEN_ON ); // cyan blink: setting up
}

keys.setWifiWasValid(true);
keys.save();
Expand All @@ -290,29 +314,38 @@ void connect() {
}

if (gs.isListening()) {
// start mDNS
gs.setupMDNS();

if (keys.isAPIKeySet() && ! keys.isValid()) {
irkit_httpclient_post_door();
}
else if (keys.isValid()) {

if (!config::useCloudControl) {
// No WAN access, we don't need to validate key, we're ready.
IR_state( IR_IDLE );
ring_put( &commands, COMMAND_START_POLLING );
on_irkit_ready();
} else {
// start mDNS
gs.setupMDNS();

if (keys.isAPIKeySet() && ! keys.isValid()) {
irkit_httpclient_post_door();
}
else if (keys.isValid()) {
IR_state( IR_IDLE );
ring_put( &commands, COMMAND_START_POLLING );
on_irkit_ready();
}
}
}
else {
keys.dump();

if (keys.wasWifiValid()) {
// retry
color.setLedColor( 1, 0, 0, false ); // red: error
if (config::ledFeedback < config::LED_OFF) {
color.setLedColor( 1, 0, 0, FullColorLed::ALWAYS_ON ); // red: error
}
TIMER_START(reconnect_timer, 5);
}
else {
keys.clear();
color.setLedColor( 1, 0, 0, true ); // red blink: listening for POST /wifi
color.setLedColor( 1, 0, 0, FullColorLed::BLINK_THEN_ON ); // red blink: listening for POST /wifi
gs.startLimitedAP();
if (gs.isLimitedAP()) {
gs.listen();
Expand Down
7 changes: 7 additions & 0 deletions firmware/src/IRKit/IRKitHTTPHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "timer.h"
#include "commands.h"
#include "log.h"
#include "config.h"

extern GSwifi gs;
extern Keys keys;
Expand Down Expand Up @@ -480,6 +481,12 @@ void irkit_http_on_timer() {
}

void irkit_http_loop() {

if (!config::useCloudControl) {
// Cloud control is currently disabled. No polling loop.
return;
}

// long poll
if (TIMER_FIRED(polling_timer)) {
TIMER_STOP(polling_timer);
Expand Down
46 changes: 46 additions & 0 deletions firmware/src/IRKit/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
Copyright (C) 2013-2014 Masakazu Ohtsuka

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CONFIG_H__
#define __CONFIG_H__

/*
* Exposes some general options for your IRKit device.
*/
namespace config {

// Different modes for the LED feedback.
typedef enum {
LED_VERBOSE = 0, // LED almost always-on to indicate the device status.
LED_QUIET = 1, // LED on during setup and blinks when receiving/sending commands. Off when the device is idle.
LED_SETUP_ONLY = 2, // LED on only during the setup, then always-off.
LED_OFF = 3 // /!\ This disables the LED completely.
} LedFeedbackProfile;

// Defines what kind of LED profile you want.
const LedFeedbackProfile ledFeedback = LED_QUIET;

// Enables/disables cloud-control through the "deviceapi.getirkit.com" server.
// If you use your IRKit device exclusively over your LAN, you can disable
// this option: the device won't send regular polling requests to the cloud server.
// This also lets you setup your device without internet access (no need for a valid device key).
const bool useCloudControl = true;

}

#endif // __CONFIG_H__