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
11 changes: 11 additions & 0 deletions project.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "src/software.h"

murxy::Software software;

void setup() {
software.initialize();
}

void loop() {
software.loop();
}
90 changes: 90 additions & 0 deletions src/LightShow/LightShow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include "LightShow.h"

namespace murxy {

void LightShow::initialize() {
for(uint8_t column = Columns::Left; column != Columns::Count; ++column) {
mLights[column].begin(getAddress(static_cast<Columns>(column)));
}
}

XSAA1064 &LightShow::operator[](Columns column) {
return mLights[column];
}
const XSAA1064 &LightShow::operator[](Columns column) const {
return mLights[column];
}

void LightShow::update() {
for (auto &light : mLights)
light.update();
}

void LightShow::clear() {
for (auto &light : mLights)
light.clear();
}

void LightShow::execute(uint16_t command) {
constexpr uint16_t TargetMask = 0b1000000000000000;
constexpr uint16_t ColumnMask = 0b0100000000000000;
constexpr uint16_t CommandMask = 0b0011000000000000;
constexpr uint16_t FromLedsMask = 0b0000111110000000;
constexpr uint16_t ToLedsMask = 0b0000000001111100;
constexpr uint16_t ValueMask = 0b0000000000000010;
constexpr uint16_t LinkMask = 0b0000000000000001;

enum Command {
Clear, Set, Range, All
};

static const auto check = [](uint16_t command, uint16_t mask) -> bool {
return (command & mask) != mask;
};

if (!check(command, TargetMask))
return;

const Columns column = static_cast<Columns>((command & ColumnMask) >> 14);
const Command cmd = static_cast<Command>((command & CommandMask) >> 12);
const bool enabled = (command & ValueMask) >> 1;
const bool hasLink = check(command, LinkMask);

switch(cmd) {
case Command::Clear: {
mLights[column].clear();
} break;
case Command::Set: {
const uint8_t position = ((command & FromLedsMask) >> 7);
mLights[column].set(position, enabled);
} break;
case Command::Range: {
const uint8_t from = ((command & FromLedsMask) >> 7);
const uint8_t to = ((command & ToLedsMask) >> 2);
mLights[column].set(from, to, enabled);
} break;
case Command::All: {
mLights[column].setAll(enabled);
}
}
mLights[column].set(XSAA1064::LinkLed, hasLink);
}

XSAA1064 *LightShow::begin() {
return mLights;
}
const XSAA1064 *LightShow::begin() const {
return mLights;
}
XSAA1064 *LightShow::end() {
return mLights + Columns::Count;
}
const XSAA1064 *LightShow::end() const {
return mLights + Columns::Count;
}

uint8_t LightShow::getAddress(Columns c) {
return 0b00111000 | (c << 0) | (c << 1);
}

} // namespace murxy
49 changes: 49 additions & 0 deletions src/LightShow/LightShow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#if !defined(__LIGHT_SHOW__)
#define __LIGHT_SHOW__

#include <XSAA1064.h>

namespace murxy {

class LightShow {
public:
enum Columns{ Left, Right, Count };

void initialize();

XSAA1064 &operator[](Columns column);
const XSAA1064 &operator[](Columns column) const;

/// @brief Update all light
void update();

/// @brief Clear all light including link light
void clear();

/**
* @brief Execute command
*
* @param command The data in format [T][C][CMD]
* Where is:
* T - Target. Have to be 0. Otherwise the command will be ignored
* C - Column. Left or right column
* CMD - Command. 0 - clear, 1 - set, 2 - set (range), 3 - all
* @see in documentation @link
*/
void execute(uint16_t command);

XSAA1064 *begin();
const XSAA1064 *begin() const;
XSAA1064 *end();
const XSAA1064 *end() const;

static uint8_t getAddress(Columns column);

private:
XSAA1064 mLights[Columns::Count];
};

} // namespace murxy


#endif
71 changes: 0 additions & 71 deletions src/serialParse.ino

This file was deleted.

86 changes: 86 additions & 0 deletions src/software.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include <Arduino.h>

#include "software.h"

namespace murxy {

const Software::Handler Software::mStateHandlers[] = {
&Software::onLoading,
&Software::onReady,
};

void Software::initialize() {
Serial.begin(9600);
mLightShow.initialize();
}

void Software::loop() {
(this->*mStateHandlers[mCurrentState])();
mLightShow.update();
}

void Software::onLoading() {
constexpr uint8_t count = 5;
static LightShow::Columns cur[count] = { LightShow::Columns::Left };
static uint8_t pos[count] = { 1, 2, 3, 4, 6 };

if (mTimer == 0) {
mTimer = millis();
mLightShow.clear();
}

uint8_t erasePos = 0;
for (uint8_t i = 0; i < count; ++i) {
uint8_t& position = pos[i];
LightShow::Columns& column = cur[i];
if (i == 0)
mLightShow[column].set(position, false);

if (column == LightShow::Columns::Left)
++position;
else
--position;

if (position > 0 && position < XSAA1064::ledCount()) {
mLightShow[column].set(position, true);
continue;
}

if (column == LightShow::Columns::Left)
column = LightShow::Columns::Right;
else
column = LightShow::Columns::Left;
}

delay(millis() / 100);
if (millis() - mTimer >= 5 * 1000)
setState(States::Ready);
}

void Software::onReady() {
if (mTimer == 0) {
for (auto &led : mLightShow)
led.set(XSAA1064::LinkLed);
mTimer = millis();
}

uint8_t byte = 0;
if (Serial.readBytes(&byte, 1) > 0) {
if (byte != 'B') return;
}

uint16_t command = 0;
size_t size = Serial.readBytes(reinterpret_cast<uint8_t*>(&command) + 1, 1);
size += Serial.readBytes(reinterpret_cast<uint8_t*>(&command) + 0, 1);
if (size == sizeof(command)) {
mLightShow.execute(command);
}
}

void Software::setState(States newState) {
mCurrentState = newState;
mLightShow.clear();
mTimer = 0;
}

} // namespace murxy
36 changes: 36 additions & 0 deletions src/software.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#if !defined(__SOFTWARE__)
#define __SOFTWARE__

#include "LightShow/LightShow.h"

namespace murxy {

class Software {
using Handler = void(Software::*)();
public:

void initialize();
void loop();

private:
enum States {
Loading,
Ready,
Count
};

States mCurrentState = States::Loading;
LightShow mLightShow;
uint32_t mTimer = 0;

void onLoading();
void onReady();

static const Handler mStateHandlers[States::Count];

void setState(States newState);
};

} // namespace murxy

#endif