Implemented protocol and message handling
This commit is contained in:
parent
a5eab1427d
commit
06b5a0e720
22
module/src/config.h
Normal file
22
module/src/config.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Stairs lighting
|
||||||
|
* Copyright 2017 (c) Mark van Renswoude
|
||||||
|
*
|
||||||
|
* https://git.x2software.net/pub/Stairs
|
||||||
|
*/
|
||||||
|
#ifndef __config
|
||||||
|
#define __config
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// How long the display should stay on once it's idle and showing the
|
||||||
|
// current step numbers.
|
||||||
|
const uint32_t DisplayIdleTimeout = 5000;
|
||||||
|
|
||||||
|
// How long since the last packet before the communication icon shows
|
||||||
|
// as 'off'. Note that if a module is not configured for sensors and
|
||||||
|
// the light doesn't change either there will be no communication,
|
||||||
|
// so no need to panic immediately.
|
||||||
|
const uint32_t CommIdleTimeout = 1000;
|
||||||
|
|
||||||
|
#endif
|
@ -6,10 +6,12 @@
|
|||||||
*/
|
*/
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include <Fonts/FreeSans12pt7b.h>
|
#include <Fonts/FreeSans12pt7b.h>
|
||||||
#include "global.h"
|
#include "config.h"
|
||||||
#include "icons.h"
|
#include "icons.h"
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
#define WaitAnimationInterval 150
|
|
||||||
|
const uint8_t WaitAnimationInterval = 150;
|
||||||
|
|
||||||
|
|
||||||
void Display::init()
|
void Display::init()
|
||||||
@ -19,29 +21,45 @@ void Display::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Display::show(Screen screen)
|
void Display::update()
|
||||||
{
|
{
|
||||||
switch (screen)
|
switch (state)
|
||||||
{
|
{
|
||||||
case Screen::Blank:
|
case State::WaitingForComm:
|
||||||
off();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Screen::WaitingForComm:
|
|
||||||
drawWaitingForComm();
|
drawWaitingForComm();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Screen::ModuleIndex:
|
case State::Linking:
|
||||||
|
drawLinking();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case State::LinkingSet:
|
||||||
drawModuleIndex();
|
drawModuleIndex();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case State::DisplayModuleIndex:
|
||||||
|
if (currentTime - mLastStateChange >= DisplayIdleTimeout)
|
||||||
|
{
|
||||||
|
state = State::DisplayOff;
|
||||||
|
off();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
drawModuleIndex();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case State::DisplayOff:
|
||||||
|
off();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
setLastDrawnState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Display::drawWaitingForComm()
|
void Display::drawWaitingForComm()
|
||||||
{
|
{
|
||||||
uint32_t currentTime = millis();
|
if (mLastDrawnState == State::WaitingForComm && currentTime - mLastWaiting < WaitAnimationInterval)
|
||||||
if (mLastScreen == Screen::WaitingForComm && currentTime - mLastWaiting < WaitAnimationInterval)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
checkOn();
|
checkOn();
|
||||||
@ -58,7 +76,6 @@ void Display::drawWaitingForComm()
|
|||||||
if (mWaitAnimationStep > 3)
|
if (mWaitAnimationStep > 3)
|
||||||
mWaitAnimationStep = 0;
|
mWaitAnimationStep = 0;
|
||||||
|
|
||||||
mLastScreen = Screen::WaitingForComm;
|
|
||||||
mLastWaiting = currentTime;
|
mLastWaiting = currentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +83,7 @@ void Display::drawWaitingForComm()
|
|||||||
void Display::drawModuleIndex()
|
void Display::drawModuleIndex()
|
||||||
{
|
{
|
||||||
uint8_t moduleIndex = settings.getModuleIndex();
|
uint8_t moduleIndex = settings.getModuleIndex();
|
||||||
if (mLastScreen == Screen::ModuleIndex && mLastModuleIndex == moduleIndex)
|
if (mLastDrawnState == State::DisplayModuleIndex && mLastModuleIndex == moduleIndex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
checkOn();
|
checkOn();
|
||||||
@ -75,34 +92,61 @@ void Display::drawModuleIndex()
|
|||||||
drawCommIcon();
|
drawCommIcon();
|
||||||
|
|
||||||
mDisplay->setFont(&FreeSans12pt7b);
|
mDisplay->setFont(&FreeSans12pt7b);
|
||||||
mDisplay->setCursor(0, mDisplay->height());
|
mDisplay->setCursor(0, mDisplay->height() - 1);
|
||||||
|
|
||||||
// ToDo show numbers based on module index
|
if (moduleIndex == ModuleIndexUndefined)
|
||||||
|
{
|
||||||
|
mDisplay->print("Not set");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
uint8_t firstStep = (moduleIndex * 2) + 1;
|
uint8_t firstStep = (moduleIndex * 2) + 1;
|
||||||
mDisplay->print(firstStep);
|
mDisplay->print(firstStep);
|
||||||
mDisplay->print(" - ");
|
mDisplay->print(" - ");
|
||||||
mDisplay->print(firstStep + 1);
|
mDisplay->print(firstStep + 1);
|
||||||
|
}
|
||||||
|
|
||||||
mDisplay->display();
|
mDisplay->display();
|
||||||
|
}
|
||||||
|
|
||||||
mLastScreen = Screen::ModuleIndex;
|
|
||||||
mLastModuleIndex = moduleIndex;
|
void Display::drawLinking()
|
||||||
|
{
|
||||||
|
if (mLastDrawnState == State::Linking)
|
||||||
|
return;
|
||||||
|
|
||||||
|
checkOn();
|
||||||
|
mDisplay->clearDisplay();
|
||||||
|
drawTitle("Steps");
|
||||||
|
drawCommIcon();
|
||||||
|
|
||||||
|
mDisplay->setFont(&FreeSans12pt7b);
|
||||||
|
mDisplay->setCursor(0, mDisplay->height() - 1);
|
||||||
|
mDisplay->print("Click to set");
|
||||||
|
mDisplay->display();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Display::setLastDrawnState()
|
||||||
|
{
|
||||||
|
if (state != mLastDrawnState)
|
||||||
|
{
|
||||||
|
mLastDrawnState = state;
|
||||||
|
mLastStateChange = currentTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Display::off()
|
void Display::off()
|
||||||
{
|
{
|
||||||
if (mLastScreen != Screen::Blank)
|
if (mLastDrawnState != State::DisplayOff)
|
||||||
{
|
|
||||||
mDisplay->ssd1306_command(SSD1306_DISPLAYOFF);
|
mDisplay->ssd1306_command(SSD1306_DISPLAYOFF);
|
||||||
mLastScreen = Screen::Blank;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Display::checkOn()
|
void Display::checkOn()
|
||||||
{
|
{
|
||||||
if (mLastScreen == Screen::Blank)
|
if (mLastDrawnState == State::DisplayOff)
|
||||||
mDisplay->ssd1306_command(SSD1306_DISPLAYON);
|
mDisplay->ssd1306_command(SSD1306_DISPLAYON);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,8 +164,9 @@ void Display::drawTitle(const char* title)
|
|||||||
|
|
||||||
void Display::drawCommIcon()
|
void Display::drawCommIcon()
|
||||||
{
|
{
|
||||||
// ToDo show actual state depending on last received message (should never be more than half a second ago)
|
mDisplay->drawBitmap(mDisplay->width() - IconCommWidth, 0,
|
||||||
mDisplay->drawBitmap(mDisplay->width() - IconCommWidth, 0, IconCommOff, IconCommWidth, IconCommHeight, 1);
|
currentTime - comm.getPacketStartTime() <= CommIdleTimeout ? IconCommOn : IconCommOff,
|
||||||
|
IconCommWidth, IconCommHeight, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,21 +11,15 @@
|
|||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include <Adafruit_GFX.h>
|
#include <Adafruit_GFX.h>
|
||||||
#include "lib/Adafruit_SSD1306.h"
|
#include "lib/Adafruit_SSD1306.h"
|
||||||
|
#include "state.h"
|
||||||
|
|
||||||
enum struct Screen: uint8_t
|
|
||||||
{
|
|
||||||
Blank,
|
|
||||||
WaitingForComm,
|
|
||||||
ModuleIndex
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Display
|
class Display
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Adafruit_SSD1306* mDisplay;
|
Adafruit_SSD1306* mDisplay;
|
||||||
Screen mLastScreen = Screen::Blank;
|
State mLastDrawnState = State::DisplayOff;
|
||||||
|
uint32_t mLastStateChange;
|
||||||
uint8_t mLastModuleIndex;
|
uint8_t mLastModuleIndex;
|
||||||
uint32_t mLastWaiting;
|
uint32_t mLastWaiting;
|
||||||
uint8_t mWaitAnimationStep = 0;
|
uint8_t mWaitAnimationStep = 0;
|
||||||
@ -38,10 +32,13 @@ class Display
|
|||||||
|
|
||||||
void drawWaitingForComm();
|
void drawWaitingForComm();
|
||||||
void drawModuleIndex();
|
void drawModuleIndex();
|
||||||
|
void drawLinking();
|
||||||
|
void off();
|
||||||
|
|
||||||
|
void setLastDrawnState();
|
||||||
public:
|
public:
|
||||||
void init();
|
void init();
|
||||||
void show(Screen screen);
|
void update();
|
||||||
void off();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -26,4 +26,6 @@ size_t serialWrite(const byte what)
|
|||||||
Settings settings;
|
Settings settings;
|
||||||
Display display;
|
Display display;
|
||||||
RS485 comm(serialRead, serialAvailable, serialWrite, 20);
|
RS485 comm(serialRead, serialAvailable, serialWrite, 20);
|
||||||
PCA9685 ledDriver;
|
PCA9685 pwmDriver;
|
||||||
|
State state = State::WaitingForComm;
|
||||||
|
uint32_t currentTime;
|
@ -11,10 +11,13 @@
|
|||||||
#include "lib/PCA9685.h"
|
#include "lib/PCA9685.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
|
#include "state.h"
|
||||||
|
|
||||||
extern Settings settings;
|
extern Settings settings;
|
||||||
extern Display display;
|
extern Display display;
|
||||||
extern RS485 comm;
|
extern RS485 comm;
|
||||||
extern PCA9685 ledDriver;
|
extern PCA9685 pwmDriver;
|
||||||
|
extern State state;
|
||||||
|
extern uint32_t currentTime;
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -8,16 +8,7 @@
|
|||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
|
#include "protocol.h"
|
||||||
|
|
||||||
enum struct State: uint8_t
|
|
||||||
{
|
|
||||||
WaitingForComm,
|
|
||||||
Connected
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
State currentState = State::WaitingForComm;
|
|
||||||
|
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
@ -27,7 +18,7 @@ void setup()
|
|||||||
// Set up I2C devices: the SSD1306 OLED display and PCA9685 LED PWM driver
|
// Set up I2C devices: the SSD1306 OLED display and PCA9685 LED PWM driver
|
||||||
Wire.begin();
|
Wire.begin();
|
||||||
display.init();
|
display.init();
|
||||||
ledDriver.setAddress(0x40);
|
pwmDriver.setAddress(0x40);
|
||||||
|
|
||||||
// At 16 Mhz we pick a baud rate with a very acceptable 0.2% error rate
|
// At 16 Mhz we pick a baud rate with a very acceptable 0.2% error rate
|
||||||
// Source: http://www.robotroom.com/Asynchronous-Serial-Communication-2.html
|
// Source: http://www.robotroom.com/Asynchronous-Serial-Communication-2.html
|
||||||
@ -35,22 +26,154 @@ void setup()
|
|||||||
comm.begin();
|
comm.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
void handleCommMessage();
|
||||||
|
void handlePing(uint8_t* data, uint8_t length);
|
||||||
|
void handleDisplayModuleIndex(uint8_t* data, uint8_t length);
|
||||||
|
void handleStartLink(uint8_t* data, uint8_t length);
|
||||||
|
void handleRequestLinkResponse(uint8_t* data, uint8_t length);
|
||||||
|
void handleStopLink(uint8_t* data, uint8_t length);
|
||||||
|
void handleSetPWM(uint8_t* data, uint8_t length);
|
||||||
|
void handleGetSensors(uint8_t* data, uint8_t length);
|
||||||
|
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
|
currentTime = millis();
|
||||||
|
|
||||||
if (comm.update())
|
if (comm.update())
|
||||||
|
handleCommMessage();
|
||||||
|
|
||||||
|
display.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void handleCommMessage()
|
||||||
|
{
|
||||||
|
uint8_t* data = comm.getData();
|
||||||
|
uint8_t length = comm.getLength();
|
||||||
|
|
||||||
|
if (length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (state == State::WaitingForComm)
|
||||||
|
state = State::DisplayModuleIndex;
|
||||||
|
|
||||||
|
uint8_t command = *data; data++; length--;
|
||||||
|
uint8_t moduleIndex = ModuleIndexUndefined;
|
||||||
|
|
||||||
|
if (command & MaskModuleCommand)
|
||||||
{
|
{
|
||||||
// TODO get data
|
if (!settings.hasModuleIndex())
|
||||||
currentState = State::Connected;
|
// We're not linked yet
|
||||||
|
return;
|
||||||
|
|
||||||
|
moduleIndex = *data; data++; length--;
|
||||||
|
|
||||||
|
if (settings.getModuleIndex() != moduleIndex)
|
||||||
|
// This message is meant for another module
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (currentState)
|
switch (command)
|
||||||
{
|
{
|
||||||
case State::WaitingForComm:
|
case CommandPing: handlePing(data, length); break;
|
||||||
display.show(Screen::WaitingForComm);
|
case CommandDisplayModuleIndex: handleDisplayModuleIndex(data, length); break;
|
||||||
break;
|
case CommandStartLink: handleStartLink(data, length); break;
|
||||||
|
case ResponseRequestLink: handleRequestLinkResponse(data, length); break;
|
||||||
|
case CommandStopLink: handleStopLink(data, length); break;
|
||||||
|
case CommandSetPWM: handleSetPWM(data, length); break;
|
||||||
|
case CommandGetSensors: handleGetSensors(data, length); break;
|
||||||
|
|
||||||
case State::Connected:
|
default:
|
||||||
display.show(Screen::ModuleIndex);
|
if (command & MaskModuleCommand)
|
||||||
break;
|
{
|
||||||
|
// Sender expects a response from us
|
||||||
|
const uint8_t msg[] = { ResponseUhmWhat, moduleIndex };
|
||||||
|
comm.sendMsg(msg, sizeof(msg));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handlePing(uint8_t* data, uint8_t length)
|
||||||
|
{
|
||||||
|
const uint8_t msg[] = { ResponsePing, settings.getModuleIndex() };
|
||||||
|
comm.sendMsg(msg, sizeof(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handleDisplayModuleIndex(uint8_t* data, uint8_t length)
|
||||||
|
{
|
||||||
|
if (state == State::DisplayOff)
|
||||||
|
state = State::DisplayModuleIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handleStartLink(uint8_t* data, uint8_t length)
|
||||||
|
{
|
||||||
|
state = State::Linking;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handleRequestLinkResponse(uint8_t* data, uint8_t length)
|
||||||
|
{
|
||||||
|
if (length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (state != State::Linking)
|
||||||
|
return;
|
||||||
|
|
||||||
|
settings.setModuleIndex(*data);
|
||||||
|
state = State::LinkingSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handleStopLink(uint8_t* data, uint8_t length)
|
||||||
|
{
|
||||||
|
if (state == State::Linking || state == State::LinkingSet)
|
||||||
|
state = State::DisplayModuleIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handleSetPWM(uint8_t* data, uint8_t length)
|
||||||
|
{
|
||||||
|
if (length < 5)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint8_t flags = *data; data++;
|
||||||
|
uint16_t value1 = *(reinterpret_cast<uint16_t*>(data)); data += 2;
|
||||||
|
uint16_t value2 = *(reinterpret_cast<uint16_t*>(data)); data += 2;
|
||||||
|
|
||||||
|
pwmDriver.setPWM(0, value1);
|
||||||
|
pwmDriver.setPWM(1, value2);
|
||||||
|
|
||||||
|
if (flags & SetPWMFlagModuleLEDs)
|
||||||
|
{
|
||||||
|
pwmDriver.setPWM(2, value1);
|
||||||
|
pwmDriver.setPWM(3, value2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pwmDriver.setPWM(2, 0);
|
||||||
|
pwmDriver.setPWM(3, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t msg[] = { ResponseSetPWM, settings.getModuleIndex() };
|
||||||
|
comm.sendMsg(msg, sizeof(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handleGetSensors(uint8_t* data, uint8_t length)
|
||||||
|
{
|
||||||
|
// TODO get sensor values
|
||||||
|
|
||||||
|
uint8_t sensor1 = 0;
|
||||||
|
uint8_t sensor2 = 0;
|
||||||
|
|
||||||
|
const uint8_t msg[] = { ResponseSetPWM, settings.getModuleIndex(), sensor1, sensor2 };
|
||||||
|
comm.sendMsg(msg, sizeof(msg));
|
||||||
|
}
|
||||||
|
149
module/src/protocol.h
Normal file
149
module/src/protocol.h
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* Stairs lighting
|
||||||
|
* Copyright 2017 (c) Mark van Renswoude
|
||||||
|
*
|
||||||
|
* https://git.x2software.net/pub/Stairs
|
||||||
|
*/
|
||||||
|
#ifndef __protocol
|
||||||
|
#define __protocol
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are three classes of messages, these masks provide a way to identify
|
||||||
|
* unknown messages if the protocol ever changes.
|
||||||
|
*
|
||||||
|
* MaskBroadcastCommand: commands which do not expect a response
|
||||||
|
* MaskModuleCommand: commands which do expect a command. respond with ResponseUhmWhat to satisfy the response requirement.
|
||||||
|
* MaskResponse: responses to commands
|
||||||
|
*/
|
||||||
|
const uint8_t MaskBroadcastCommand = 0b10000000;
|
||||||
|
const uint8_t MaskModuleCommand = 0b11000000;
|
||||||
|
const uint8_t MaskResponse = 0b01000000;
|
||||||
|
|
||||||
|
const uint8_t ResponseUhmWhat = 0x00 | MaskResponse;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ping:
|
||||||
|
* Aimed at a specific module, which must respond with a
|
||||||
|
* ResponsePing message.
|
||||||
|
*
|
||||||
|
* Request:
|
||||||
|
* [0] CommandPing
|
||||||
|
* [1] Module index
|
||||||
|
*
|
||||||
|
* Response:
|
||||||
|
* [0] ResponsePing
|
||||||
|
* [1] Module index
|
||||||
|
*/
|
||||||
|
const uint8_t CommandPing = 0x01 | MaskModuleCommand;
|
||||||
|
const uint8_t ResponsePing = CommandPing | MaskResponse;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Display module index:
|
||||||
|
* Broadcast to all modules which should turn on their display
|
||||||
|
* and show the current settings. No response is expected.
|
||||||
|
*
|
||||||
|
* Request:
|
||||||
|
* [0] CommandDisplayModuleIndex
|
||||||
|
*/
|
||||||
|
const uint8_t CommandDisplayModuleIndex = 0x02 | MaskBroadcastCommand;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start linking:
|
||||||
|
* Broadcast to all modules which should change to link mode.
|
||||||
|
* During link mode the master will disable all other communication,
|
||||||
|
* allowing the module to respond at will in response to user input.
|
||||||
|
*
|
||||||
|
* Each module should send a CommandRequestLink message when user input
|
||||||
|
* is provided.
|
||||||
|
*
|
||||||
|
* Request:
|
||||||
|
* [0] CommandStartLink
|
||||||
|
*
|
||||||
|
* Response (eventually):
|
||||||
|
* See CommandRequestLink
|
||||||
|
*/
|
||||||
|
const uint8_t CommandStartLink = 0x10 | MaskBroadcastCommand;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Request link:
|
||||||
|
* Sent by a module when user input is provided to link this module
|
||||||
|
* as the next in line. All other modules should disable sending this
|
||||||
|
* message until the currently requesting module receives a response.
|
||||||
|
*
|
||||||
|
* The master must respond with the new module index, which the
|
||||||
|
* module must apply and store immediately.
|
||||||
|
*
|
||||||
|
* Request:
|
||||||
|
* [0] CommandRequestLink
|
||||||
|
*
|
||||||
|
* Response:
|
||||||
|
* [0] ResponseRequestLink
|
||||||
|
* [1] New module index
|
||||||
|
*/
|
||||||
|
const uint8_t CommandRequestLink = 0x11 | MaskBroadcastCommand;
|
||||||
|
const uint8_t ResponseRequestLink = CommandRequestLink | MaskResponse;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stop linking:
|
||||||
|
* Broadcast to all modules when the master takes back control
|
||||||
|
* over the communication line. No response is expected.
|
||||||
|
*
|
||||||
|
* Request:
|
||||||
|
* [0] CommandStopLink
|
||||||
|
*/
|
||||||
|
const uint8_t CommandStopLink = 0x12 | MaskBroadcastCommand;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set PWM value:
|
||||||
|
* Aimed at a specific module, which must apply the specified
|
||||||
|
* PWM values to the LED strips and respond with a
|
||||||
|
* ResponseSetPWM message.
|
||||||
|
*
|
||||||
|
* Request:
|
||||||
|
* [0] CommandSetPWM
|
||||||
|
* [1] Module index
|
||||||
|
* [2] Flags, see below
|
||||||
|
* [3,4] PWM value for step 1 (0-4095, uint16_t)
|
||||||
|
* [5,6] PWM value for step 2 (0-4095, uint16_t)
|
||||||
|
*
|
||||||
|
* Response:
|
||||||
|
* [0] ResponseSetPWM
|
||||||
|
* [1] Module index
|
||||||
|
*/
|
||||||
|
const uint8_t CommandSetPWM = 0x20 | MaskModuleCommand;
|
||||||
|
const uint8_t ResponseSetPWM = CommandSetPWM | MaskResponse;
|
||||||
|
|
||||||
|
// If included, the on-board verification LEDs should light up with
|
||||||
|
// the specified PWM values as well. Otherwise they should be off.
|
||||||
|
const uint8_t SetPWMFlagModuleLEDs = 0x01;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get sensor values:
|
||||||
|
* Aimed at a specific module, which must response with a
|
||||||
|
* ResponseGetSensors message containing the current sensor states.
|
||||||
|
*
|
||||||
|
* Request:
|
||||||
|
* [0] CommandGetSensors
|
||||||
|
* [1] Module index
|
||||||
|
*
|
||||||
|
* Response:
|
||||||
|
* [0] ResponseGetSensors
|
||||||
|
* [1] Module index
|
||||||
|
* [2] Analog (0-255) or digital (0, 255) value for sensor 1
|
||||||
|
* [3] Analog (0-255) or digital (0, 255) value for sensor 2
|
||||||
|
*/
|
||||||
|
const uint8_t CommandGetSensors = 0x30 | MaskModuleCommand;
|
||||||
|
const uint8_t ResponseGetSensors = CommandGetSensors | MaskResponse;
|
||||||
|
|
||||||
|
#endif
|
@ -8,10 +8,6 @@
|
|||||||
#include <EEPROM.h>
|
#include <EEPROM.h>
|
||||||
|
|
||||||
|
|
||||||
const uint8_t ModuleIndexUndefined = 0xff;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// First byte is 0xAA to recognize uninitialised EEPROM
|
// First byte is 0xAA to recognize uninitialised EEPROM
|
||||||
const uint8_t EEPROMHeader = 0xAA;
|
const uint8_t EEPROMHeader = 0xAA;
|
||||||
const uint8_t EEPROMCurrentVersion = 1;
|
const uint8_t EEPROMCurrentVersion = 1;
|
||||||
@ -40,6 +36,12 @@ void Settings::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Settings::hasModuleIndex()
|
||||||
|
{
|
||||||
|
return mModuleIndex != ModuleIndexUndefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t Settings::getModuleIndex(void)
|
uint8_t Settings::getModuleIndex(void)
|
||||||
{
|
{
|
||||||
return mModuleIndex;
|
return mModuleIndex;
|
||||||
@ -52,5 +54,5 @@ void Settings::setModuleIndex(uint8_t index)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
mModuleIndex = index;
|
mModuleIndex = index;
|
||||||
EEPROM.put(EEPROMAddressModuleIndex, mModuleIndex);
|
// ToDo re-enable: EEPROM.put(EEPROMAddressModuleIndex, mModuleIndex);
|
||||||
}
|
}
|
@ -8,8 +8,9 @@
|
|||||||
#define __settings
|
#define __settings
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
extern const uint8_t ModuleIndexUndefined;
|
const uint8_t ModuleIndexUndefined = 0xff;
|
||||||
|
|
||||||
|
|
||||||
class Settings
|
class Settings
|
||||||
@ -20,6 +21,7 @@ class Settings
|
|||||||
public:
|
public:
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
bool hasModuleIndex();
|
||||||
uint8_t getModuleIndex();
|
uint8_t getModuleIndex();
|
||||||
void setModuleIndex(uint8_t index);
|
void setModuleIndex(uint8_t index);
|
||||||
};
|
};
|
||||||
|
19
module/src/state.h
Normal file
19
module/src/state.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Stairs lighting
|
||||||
|
* Copyright 2017 (c) Mark van Renswoude
|
||||||
|
*
|
||||||
|
* https://git.x2software.net/pub/Stairs
|
||||||
|
*/
|
||||||
|
#ifndef __state
|
||||||
|
#define __state
|
||||||
|
|
||||||
|
enum struct State: uint8_t
|
||||||
|
{
|
||||||
|
WaitingForComm,
|
||||||
|
Linking,
|
||||||
|
LinkingSet,
|
||||||
|
DisplayModuleIndex,
|
||||||
|
DisplayOff
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user