Skip to content

Commit f72ea35

Browse files
authored
Actuator API, Braking Solenoid Class (#20)
1 parent 6dda164 commit f72ea35

File tree

9 files changed

+198
-43
lines changed

9 files changed

+198
-43
lines changed

Actuator.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include "Arduino.h"
2+
#include "Actuator.h"
3+
4+
Actuator::Actuator(actuators_t actuator, arduino_t arduino, float failtarget){
5+
this->actuator = actuator;
6+
this->arduino = arduino;
7+
state.error = ERR_NONE;
8+
state.debug = DS_DISABLED;
9+
state.target = this->failtarget = failtarget; // Default start target
10+
}
11+
12+
ActuatorState* Actuator::update(){
13+
if(state.error < ERR_FAIL && state.debug >= DS_INIT){
14+
state.error = set(state.target);
15+
16+
switch(state.error){
17+
case ERR_NONE: //Success!
18+
state.debug = DS_SUCCESS;
19+
break;
20+
case ERR_WARN: //Set didn't go as planned, non-fatal
21+
// DO NOT UPDATE STATE VALUES
22+
break;
23+
case ERR_FAIL: //Set failed catastrophically
24+
state.debug = DS_DISABLED;
25+
set(failtarget);
26+
break;
27+
}
28+
}
29+
return &state;
30+
}
31+
32+
ActuatorState* Actuator::begin(){
33+
state.error = init();
34+
if(state.error > ERR_NONE){
35+
state.debug = DS_DISABLED;
36+
} else {
37+
state.debug = DS_INIT;
38+
}
39+
return &state;
40+
}

Actuator.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#ifndef Actuator_H
2+
#define Actuator_H
3+
4+
#include "Base.h"
5+
6+
// Actuator identifiers
7+
typedef enum actuators_t {
8+
A_BRAKES,
9+
A_INVERTER
10+
} actuators_t;
11+
12+
typedef struct ActuatorState {
13+
errorlevel_t error;
14+
debuglevel_t debug;
15+
float target;
16+
} ActuatorState;
17+
18+
class Actuator{
19+
protected:
20+
virtual errorlevel_t set(float target) = 0;
21+
virtual errorlevel_t init() = 0;
22+
ActuatorState state;
23+
public:
24+
arduino_t arduino;
25+
actuators_t actuator;
26+
float failtarget; // what should we default to in case of failure?
27+
Actuator(actuators_t actuator, arduino_t arduino, float failtarget);
28+
ActuatorState* update();
29+
ActuatorState* begin();
30+
};
31+
32+
#endif

Base.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#ifndef BASE_H
2+
#define BASE_H
3+
4+
#include "Arduino.h"
5+
#include "stdlib.h"
6+
7+
// Arduino identifiers
8+
typedef enum arduino_t {
9+
ARDUINO_ONE,
10+
ARDUINO_TWO,
11+
ARDUINO_THREE
12+
} arduino_t;
13+
14+
// Degree of error occurred
15+
// TODO: Maybe add more specific codes? (i.e. hardware/wiring fail, comms/protocol fail, etc.)
16+
typedef enum errorlevel_t {
17+
ERR_NONE,
18+
ERR_WARN,
19+
ERR_FAIL //NOTE: Implies debug level 'DISABLED'
20+
} errorlevel_t;
21+
22+
// General state - On fail != 0, what state did it last complete successfully?
23+
typedef enum debuglevel_t {
24+
//NOTE: The various debug states imply the value of cache.state.data as follows:
25+
DS_DISABLED, //NULL
26+
DS_INIT, //NULL
27+
// DS_CALIBRATING, //NULL if first time, otherwise unknown
28+
DS_WAITING, //NOT NULL, age > 0
29+
DS_SUCCESS //NOT NULL, age == 0
30+
} debuglevel_t;
31+
32+
#endif

Brakes/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Brakes
2+
3+
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.

Brakes/src/Brakes.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "Brakes.h"
2+
#include "Actuator.h"
3+
4+
Brakes::Brakes(uint8_t pin, arduino_t arduino) : Actuator(A_BRAKES, arduino, 1.0) {
5+
this->pin = pin;
6+
this->engaged = false;
7+
}
8+
9+
errorlevel_t Brakes::init() {
10+
pinMode(pin, OUTPUT);
11+
}
12+
13+
errorlevel_t Brakes::set(float target) {
14+
engaged |= (target != 0); //If engaged is true already, target doesn't matter (stay engaged)
15+
digitalWrite(pin, !engaged); // Engaged = digital low
16+
}

Brakes/src/Brakes.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef BRAKES_H
2+
#define BRAKES_H
3+
4+
#include "Actuator.h"
5+
class Brakes : public Actuator {
6+
public:
7+
Brakes(uint8_t pin, arduino_t arduino);
8+
private:
9+
errorlevel_t set(float target) override;
10+
errorlevel_t init() override;
11+
uint8_t pin;
12+
bool engaged = false; //Toggle-ON latch boolean (can only be turned ON)
13+
};
14+
15+
#endif

Sensor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ SensorState* Sensor::update(){
5959

6060
switch(state.error){
6161
case ERR_NONE: //Success!
62-
state.debug = DS_NEWREAD;
62+
state.debug = DS_SUCCESS;
6363
state.timestamp = lastread;
6464
free(state.data);
6565
state.data = buffer;

Sensor.h

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
#ifndef Sensor_H
22
#define Sensor_H
33

4-
#include "Arduino.h"
5-
#include "stdlib.h"
4+
#include "Base.h"
65

76
// Sensor identifiers
87
typedef enum sensors_t {
@@ -17,43 +16,6 @@ typedef enum sensors_t {
1716
S_CANBUS
1817
} sensors_t;
1918

20-
// Arduino identifiers
21-
typedef enum arduino_t {
22-
ARDUINO_ONE,
23-
ARDUINO_TWO,
24-
ARDUINO_THREE
25-
} arduino_t;
26-
27-
// Degree of error occurred
28-
// TODO: Maybe add more specific codes? (i.e. hardware/wiring fail, comms/protocol fail, etc.)
29-
typedef enum errorlevel_t {
30-
ERR_NONE,
31-
ERR_WARN,
32-
ERR_FAIL //NOTE: Implies debug level 'DISABLED'
33-
} errorlevel_t;
34-
35-
// General state - On fail != 0, what state did it last complete successfully?
36-
typedef enum debuglevel_t {
37-
//NOTE: The various debug states imply the value of cache.state.data as follows:
38-
DS_DISABLED, //NULL
39-
DS_INIT, //NULL
40-
// DS_CALIBRATING, //NULL if first time, otherwise unknown
41-
DS_WAITING, //NOT NULL, age > 0
42-
DS_NEWREAD //NOT NULL, age == 0
43-
} debuglevel_t;
44-
45-
// Unimplemented for now...
46-
// typedef struct SensorError {
47-
// errorlevel_t error,
48-
// char* msg,
49-
// uint8_t msglen
50-
// } SensorError;
51-
// typedef struct SensorDebug {
52-
// debuglevel_t debug,
53-
// char* msg,
54-
// uint8_t msglen
55-
// } SensorError;
56-
5719
// Single datapoint
5820
typedef struct t_datum {
5921
float data;

Template.ino

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
// Headers for each sensor type
22
#include "YourSensorClass.h"
33
//...
4+
#include "YourActuatorClass.h"
45

6+
#include "Base.h"
57
#include "Sensor.h"
8+
#include "Actuator.h"
69
#define NUMSENSORS 1 //Or however many
10+
#define NUMACTUATORS 1 //Or however many
711
#define BAUDRATE 115200
12+
#define THISARDUINO ARDUINO_ONE
813

914
// Objects for each sensor
10-
SensorClass sensor(/*Arguments, arduino enum*/);
15+
SensorClass sensor(/*Arguments, ...*/, THISARDUINO);
16+
//...
17+
ActuatorClass actuator(/*Arguments, arduino enum*/, THISARDUINO);
1118
//...
1219

1320
Sensor* sensors[NUMSENSORS] = {
@@ -16,6 +23,12 @@ Sensor* sensors[NUMSENSORS] = {
1623
//...
1724
};
1825

26+
Actuator* actuators[NUMACTUATORS] = {
27+
// Entry for each sensor object
28+
&actuator,
29+
//...
30+
};
31+
1932
// !#!#!#!--- EVERYTHING AFTER HERE DOES NOT NEED TO BE CHANGED FOR SENSOR IMPLEMENTATION ---!#!#!#!
2033

2134
void setup(){
@@ -37,8 +50,34 @@ void setup(){
3750
}
3851
success &= _success;
3952
}
53+
for(int i = 0; i < NUMACTUATORS; i++){
54+
ActuatorState* state = actuators[i]->begin();
55+
// Print/send sensor post-setup state data here. For example:
56+
bool _success = (state->error == ERR_NONE);
57+
if(_success){
58+
Serial.print("Actuator ");
59+
Serial.print(actuators[i]->actuator);
60+
Serial.print(" initialized. ");
61+
62+
state = actuators[i]->update(); // Initial set to default target
63+
_success = (state->error == ERR_NONE);
64+
if(_success){
65+
Serial.print("Set to ");
66+
Serial.println(state->target);
67+
} else {
68+
Serial.print("\nActuator ");
69+
Serial.print(sensors[i]->sensor);
70+
Serial.println(" failed to set!");
71+
}
72+
} else {
73+
Serial.print("Actuator ");
74+
Serial.print(sensors[i]->sensor);
75+
Serial.println(" failed to initialize!");
76+
}
77+
success &= _success;
78+
}
4079
if(!success){
41-
Serial.println("POST failed on one or more sensors, freezing...");
80+
Serial.println("POST failed on one or more devices, freezing...");
4281
while(1){delay(1000);}
4382
}
4483
}
@@ -48,7 +87,7 @@ void loop(){
4887
SensorState* state = sensors[i]->update();
4988
// Print/send sensor post-setup state data here. For example:
5089
bool _success = (state->error == ERR_NONE);
51-
bool _new = (state->debug == DS_NEWREAD);
90+
bool _new = (state->debug == DS_SUCCESS);
5291
if(_success && _new){
5392
Serial.print("Sensor ");
5493
Serial.print(sensors[i]->sensor);
@@ -66,4 +105,20 @@ void loop(){
66105
// TODO: Recover failed sensor?
67106
}
68107
}
108+
for(int i = 0; i < NUMACTUATORS; i++){
109+
ActuatorState* state = actuators[i]->update();
110+
111+
bool _success = (state->error == ERR_NONE) && (state->debug == DS_SUCCESS);
112+
if(_success){
113+
Serial.print("Actuator ");
114+
Serial.print(actuators[i]->actuator);
115+
Serial.print(" set success: ");
116+
Serial.println(state->target);
117+
} else {
118+
Serial.print("Actuator ");
119+
Serial.print(actuators[i]->actuator);
120+
Serial.println(" failed to set!");
121+
// TODO: Recover failed sensor?
122+
}
123+
}
69124
}

0 commit comments

Comments
 (0)