Skip to content

Instantly share code, notes, and snippets.

@atrakeur
Last active March 15, 2016 12:08
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 atrakeur/9041da2d10c2d0fd7589 to your computer and use it in GitHub Desktop.
Save atrakeur/9041da2d10c2d0fd7589 to your computer and use it in GitHub Desktop.
#include "Origo.h"
#include "Brain.h"
int Brain::addModule(AbstractBrain * module)
{
DEBUG_PRINT("Brain: Adding module ");
DEBUG_PRINT(module->getName());
DEBUG_PRINT("\n");
BrainConfig* freeConfig = getFreeModuleConfig();
if (freeConfig == nullptr) {
DEBUG_PRINT("Brain: No more modules slots\n");
return BRAIN_ERROR_NO_MODULES;
}
freeConfig->enabled = true;
freeConfig->module = module;
return BRAIN_OK;
}
int Brain::removeModule(AbstractBrain * module)
{
DEBUG_PRINT("Brain: Removing module ");
DEBUG_PRINT(module->getName());
DEBUG_PRINT("");
BrainConfig* config = getModuleConfig(module);
config->enabled = false;
config->module = nullptr;
return BRAIN_OK;
}
void Brain::initialize()
{
DEBUG_PRINT("Brain: Initializing modules \n");
for (int i = 0; i < BRAIN_MAX_MODULES; i++) {
if (configs[i].enabled) {
DEBUG_PRINT("\tBrain: Initializing module ");
DEBUG_PRINT(configs[i].module->getName());
DEBUG_PRINT("\n");
configs[i].module->initialize();
}
}
}
void Brain::tick()
{
//Run module code
if (configs[nextModule].enabled && configs[nextModule].isDue()) {
executeModule(&configs[nextModule]);
}
//Jump to the next module available
for (int i = 1; i < BRAIN_MAX_MODULES; i++) {
int index = (nextModule + i) % BRAIN_MAX_MODULES;
if (configs[index].enabled && configs[index].isDue()) {
nextModule = index;
break;
}
}
}
void Brain::printModule(AbstractBrain * module, Print * output)
{
BrainConfig* moduleConfig = getModuleConfig(module);
if (moduleConfig == nullptr) {
return;
}
output->print("Brain: ");
output->print("\t\t");
output->print(moduleConfig->module->getName());
output->print("\t\t");
}
void Brain::printModules(Print * output)
{
output->print("Brain: ");
output->print("\t\t");
output->print("Name");
output->print("\t\t\t");
output->print("Run time");
output->print("\t");
output->print("Late Time");
output->print("\n");
for (int i = 0; i < BRAIN_MAX_MODULES; i++) {
if (configs[i].enabled) {
printModule(configs[i].module, output);
}
}
output->print("\n");
}
BrainConfig * Brain::getModuleConfig(AbstractBrain * module)
{
for (int i = 0; i < BRAIN_MAX_MODULES; i++) {
if (configs[i].enabled && configs[i].module == module) {
return &configs[i];
}
}
return nullptr;
}
BrainConfig * Brain::getFreeModuleConfig()
{
for (int i = 0; i < BRAIN_MAX_MODULES; i++) {
if (!configs[i].enabled) {
return &configs[i];
}
}
return nullptr;
}
void Brain::executeModule(BrainConfig * config)
{
actualModule = config;
int retVal = config->module->tick();
config->lastRunTime = millis();
config->timeInterval = retVal;
actualModule = nullptr;
}
#define BRAIN_MAX_MODULES 4
#define BRAIN_OK 0
#define BRAIN_ERROR_NO_MODULES -1
/**
* Define a structure that old information for a given Brain module
*/
typedef struct BrainConfig {
boolean enabled;
AbstractBrain* module;
unsigned long lastRunTime;
int timeInterval;
inline bool isDue() {
return (unsigned long)(millis() - lastRunTime) >= timeInterval;
}
};
/**
* The main Brain class
*/
class Brain {
private:
int nextModule;
int moduleCount;
BrainConfig* actualModule;
BrainConfig configs[BRAIN_MAX_MODULES];
public:
int addModule(AbstractBrain* module);
int removeModule(AbstractBrain* module);
void initialize();
void tick();
void printModule(AbstractBrain* module, Print* output);
void printModules(Print* output);
protected:
BrainConfig* getModuleConfig(AbstractBrain* module);
BrainConfig* getFreeModuleConfig();
void executeModule(BrainConfig * config);
};
/**
* Defines a Brain module
*/
class AbstractBrain {
public:
/* The name of the module */
virtual char* getName() = 0;
/* Initialize the module */
virtual void initialize() = 0;
/* Run the module code */
virtual int tick() = 0;
};
#include "BrainModule.h"
#include "StatusLed.h"
char * StatusLed::getName()
{
return "Status Led";
}
void StatusLed::initialize()
{
blinkFreq = 1000;
pinMode(13, OUTPUT);
}
int StatusLed::tick()
{
isOn = !isOn;
if (isOn) {
digitalWrite(13, HIGH);
}
else {
digitalWrite(13, LOW);
}
return blinkFreq;
}
#include "BrainModules.h"
/**
* Define a module that just blink a led
*/
class StatusLed : public AbstractBrain {
private:
bool isOn;
int blinkFreq;
public:
char* getName();
void initialize();
int tick();
};
#include "Brain.h"
#include "StatusLed.h"
Brain brain; //Create Brain instance
StatusLed status; //Create instance of StatusLed BrainModule
void setup() {
Serial.begin(19200); while (!Serial); //Init serial and wait for it (for leonardo)
Serial.println("Setup: Configuring brain modules");
brain.addModule(&status); //Register the module to the Brain
Serial.println("Setup: Initializing brain modules");
brain.initialize(); //Initialize all registered modules
Serial.println("Setup: starting done");
}
void loop() {
brain.tick(); //Take care of executing all modules
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment