Skip to content
Merged
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
40 changes: 40 additions & 0 deletions Actuator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "Arduino.h"
#include "Actuator.h"

Actuator::Actuator(actuators_t actuator, arduino_t arduino, float failtarget){
this->actuator = actuator;
this->arduino = arduino;
state.error = ERR_NONE;
state.debug = DS_DISABLED;
state.target = this->failtarget = failtarget; // Default start target
}

ActuatorState* Actuator::update(){
if(state.error < ERR_FAIL && state.debug >= DS_INIT){
state.error = set(state.target);

switch(state.error){
case ERR_NONE: //Success!
state.debug = DS_SUCCESS;
break;
case ERR_WARN: //Set didn't go as planned, non-fatal
// DO NOT UPDATE STATE VALUES
break;
case ERR_FAIL: //Set failed catastrophically
state.debug = DS_DISABLED;
set(failtarget);
break;
}
}
return &state;
}

ActuatorState* Actuator::begin(){
state.error = init();
if(state.error > ERR_NONE){
state.debug = DS_DISABLED;
} else {
state.debug = DS_INIT;
}
return &state;
}
32 changes: 32 additions & 0 deletions Actuator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef Actuator_H
#define Actuator_H

#include "Base.h"

// Actuator identifiers
typedef enum actuators_t {
A_BRAKES,
A_INVERTER
} actuators_t;

typedef struct ActuatorState {
errorlevel_t error;
debuglevel_t debug;
float target;
} ActuatorState;

class Actuator{
protected:
virtual errorlevel_t set(float target) = 0;
virtual errorlevel_t init() = 0;
ActuatorState state;
public:
arduino_t arduino;
actuators_t actuator;
float failtarget; // what should we default to in case of failure?
Actuator(actuators_t actuator, arduino_t arduino, float failtarget);
ActuatorState* update();
ActuatorState* begin();
};

#endif
32 changes: 32 additions & 0 deletions Base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef BASE_H
#define BASE_H

#include "Arduino.h"
#include "stdlib.h"

// Arduino identifiers
typedef enum arduino_t {
ARDUINO_ONE,
ARDUINO_TWO,
ARDUINO_THREE
} arduino_t;

// Degree of error occurred
// TODO: Maybe add more specific codes? (i.e. hardware/wiring fail, comms/protocol fail, etc.)
typedef enum errorlevel_t {
ERR_NONE,
ERR_WARN,
ERR_FAIL //NOTE: Implies debug level 'DISABLED'
} errorlevel_t;

// General state - On fail != 0, what state did it last complete successfully?
typedef enum debuglevel_t {
//NOTE: The various debug states imply the value of cache.state.data as follows:
DS_DISABLED, //NULL
DS_INIT, //NULL
// DS_CALIBRATING, //NULL if first time, otherwise unknown
DS_WAITING, //NOT NULL, age > 0
DS_SUCCESS //NOT NULL, age == 0
} debuglevel_t;

#endif
3 changes: 3 additions & 0 deletions Brakes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Brakes

Engages brakes via digital output control of a MOSFET driving a solenoid (NORMALLY OPEN, i.e. engaged = digital low). Once engaged, brakes do not disengage. Fails to engaged.
16 changes: 16 additions & 0 deletions Brakes/src/Brakes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "Brakes.h"
#include "Actuator.h"

Brakes::Brakes(uint8_t pin, arduino_t arduino) : Actuator(A_BRAKES, arduino, 1.0) {
this->pin = pin;
this->engaged = false;
}

errorlevel_t Brakes::init() {
pinMode(pin, OUTPUT);
}

errorlevel_t Brakes::set(float target) {
engaged |= (target != 0); //If engaged is true already, target doesn't matter (stay engaged)
digitalWrite(pin, !engaged); // Engaged = digital low
}
15 changes: 15 additions & 0 deletions Brakes/src/Brakes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef BRAKES_H
#define BRAKES_H

#include "Actuator.h"
class Brakes : public Actuator {
public:
Brakes(uint8_t pin, arduino_t arduino);
private:
errorlevel_t set(float target) override;
errorlevel_t init() override;
uint8_t pin;
bool engaged = false; //Toggle-ON latch boolean (can only be turned ON)
};

#endif
2 changes: 1 addition & 1 deletion Sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ SensorState* Sensor::update(){

switch(state.error){
case ERR_NONE: //Success!
state.debug = DS_NEWREAD;
state.debug = DS_SUCCESS;
state.timestamp = lastread;
free(state.data);
state.data = buffer;
Expand Down
40 changes: 1 addition & 39 deletions Sensor.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#ifndef Sensor_H
#define Sensor_H

#include "Arduino.h"
#include "stdlib.h"
#include "Base.h"

// Sensor identifiers
typedef enum sensors_t {
Expand All @@ -17,43 +16,6 @@ typedef enum sensors_t {
S_CANBUS
} sensors_t;

// Arduino identifiers
typedef enum arduino_t {
ARDUINO_ONE,
ARDUINO_TWO,
ARDUINO_THREE
} arduino_t;

// Degree of error occurred
// TODO: Maybe add more specific codes? (i.e. hardware/wiring fail, comms/protocol fail, etc.)
typedef enum errorlevel_t {
ERR_NONE,
ERR_WARN,
ERR_FAIL //NOTE: Implies debug level 'DISABLED'
} errorlevel_t;

// General state - On fail != 0, what state did it last complete successfully?
typedef enum debuglevel_t {
//NOTE: The various debug states imply the value of cache.state.data as follows:
DS_DISABLED, //NULL
DS_INIT, //NULL
// DS_CALIBRATING, //NULL if first time, otherwise unknown
DS_WAITING, //NOT NULL, age > 0
DS_NEWREAD //NOT NULL, age == 0
} debuglevel_t;

// Unimplemented for now...
// typedef struct SensorError {
// errorlevel_t error,
// char* msg,
// uint8_t msglen
// } SensorError;
// typedef struct SensorDebug {
// debuglevel_t debug,
// char* msg,
// uint8_t msglen
// } SensorError;

// Single datapoint
typedef struct t_datum {
float data;
Expand Down
61 changes: 58 additions & 3 deletions Template.ino
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
// Headers for each sensor type
#include "YourSensorClass.h"
//...
#include "YourActuatorClass.h"

#include "Base.h"
#include "Sensor.h"
#include "Actuator.h"
#define NUMSENSORS 1 //Or however many
#define NUMACTUATORS 1 //Or however many
#define BAUDRATE 115200
#define THISARDUINO ARDUINO_ONE

// Objects for each sensor
SensorClass sensor(/*Arguments, arduino enum*/);
SensorClass sensor(/*Arguments, ...*/, THISARDUINO);
//...
ActuatorClass actuator(/*Arguments, arduino enum*/, THISARDUINO);
//...

Sensor* sensors[NUMSENSORS] = {
Expand All @@ -16,6 +23,12 @@ Sensor* sensors[NUMSENSORS] = {
//...
};

Actuator* actuators[NUMACTUATORS] = {
// Entry for each sensor object
&actuator,
//...
};

// !#!#!#!--- EVERYTHING AFTER HERE DOES NOT NEED TO BE CHANGED FOR SENSOR IMPLEMENTATION ---!#!#!#!

void setup(){
Expand All @@ -37,8 +50,34 @@ void setup(){
}
success &= _success;
}
for(int i = 0; i < NUMACTUATORS; i++){
ActuatorState* state = actuators[i]->begin();
// Print/send sensor post-setup state data here. For example:
bool _success = (state->error == ERR_NONE);
if(_success){
Serial.print("Actuator ");
Serial.print(actuators[i]->actuator);
Serial.print(" initialized. ");

state = actuators[i]->update(); // Initial set to default target
_success = (state->error == ERR_NONE);
if(_success){
Serial.print("Set to ");
Serial.println(state->target);
} else {
Serial.print("\nActuator ");
Serial.print(sensors[i]->sensor);
Serial.println(" failed to set!");
}
} else {
Serial.print("Actuator ");
Serial.print(sensors[i]->sensor);
Serial.println(" failed to initialize!");
}
success &= _success;
}
if(!success){
Serial.println("POST failed on one or more sensors, freezing...");
Serial.println("POST failed on one or more devices, freezing...");
while(1){delay(1000);}
}
}
Expand All @@ -48,7 +87,7 @@ void loop(){
SensorState* state = sensors[i]->update();
// Print/send sensor post-setup state data here. For example:
bool _success = (state->error == ERR_NONE);
bool _new = (state->debug == DS_NEWREAD);
bool _new = (state->debug == DS_SUCCESS);
if(_success && _new){
Serial.print("Sensor ");
Serial.print(sensors[i]->sensor);
Expand All @@ -66,4 +105,20 @@ void loop(){
// TODO: Recover failed sensor?
}
}
for(int i = 0; i < NUMACTUATORS; i++){
ActuatorState* state = actuators[i]->update();

bool _success = (state->error == ERR_NONE) && (state->debug == DS_SUCCESS);
if(_success){
Serial.print("Actuator ");
Serial.print(actuators[i]->actuator);
Serial.print(" set success: ");
Serial.println(state->target);
} else {
Serial.print("Actuator ");
Serial.print(actuators[i]->actuator);
Serial.println(" failed to set!");
// TODO: Recover failed sensor?
}
}
}