I was drawn into another discussion -- Use another function during the running of Millis -- and wrote some code, but my disparate set of global configuration variables seems sloppy. I think it would be better to use a configuration structure instead, along with an array of different configurations.
#include <limits.h>
typedef struct config_t {
int id;
char * name;
int delay_interval;
int angle;
int wait_interval;
};
config_t configurations[] = {
{0, "near", 3000, 45, 3000},
{1, "far", 10000, 90, 3000},
{2, "zero",0,0,0},
{3, "ULONG_MAX",ULONG_MAX,0,0}
//...
};
config_t configuration;
//...
void setup(){
Serial.begin(115200);
configuration = configurations[0];
Serial.println(configuration.name);
//...
}
void loop(){;}
Would you have advice or a reference on how to save, update, and use structured configurations like this? Or a better pattern to learn?
My full code with the sloppy global config variables:
// DaveX 2022-02-16 CC BY-SA
// For https://forum.arduino.cc/t/use-another-function-during-the-running-of-millis/959087/17
//
#include<Servo.h>
#define maxdistance 100
unsigned long currentMillis = 0;
Servo srv;
int i;
const int ledPin = LED_BUILTIN;
int ledState = LOW;
void setup()
{
Serial.begin(9600);
pinMode(6, OUTPUT);
pinMode(5, INPUT);
srv.attach(7);
}
// daveX:
enum states {IDLE, DELAY, TURN, STAY, RETURN} sanitizer_state = IDLE;
enum configs {NEAR, FAR} config = NEAR;
unsigned long delay_interval, stay_interval;
int turn_angle, distance;
int read_distance() {
distance = pulseIn(5, HIGH) / 29 / 2;
distance = 4;
return distance;
}
void setNearConfig() {
config = NEAR;
delay_interval = 2000;
turn_angle = 45;
stay_interval = 3000;
}
void setFarConfig() {
config = FAR;
delay_interval = 10000;
turn_angle = 90;
stay_interval = 3000;
}
void processSanitizer() {
unsigned long currentMillis = millis();
static unsigned long previousMillis = 0;
switch (sanitizer_state) {
case IDLE:
if ( read_distance() <= 5 ) {
setNearConfig();
} else {
setFarConfig();
}
srv.write(0);
sanitizer_state = DELAY;
previousMillis = currentMillis;
break;
case DELAY:
if ( currentMillis - previousMillis > delay_interval) {
sanitizer_state = TURN;
}
// Serial.println(currentMillis - previousMillis);
break;
case TURN:
srv.write(turn_angle);
previousMillis = currentMillis;
sanitizer_state = STAY;
break;
case STAY:
if (currentMillis - previousMillis > stay_interval) {
sanitizer_state = IDLE;
}
break;
default:
Serial.println("Default case");
;
}
}
void report() {
const long interval = 1000;
static unsigned long prev = - interval;
if (millis() - prev < interval )
return;
prev += interval;
Serial.print(sanitizer_state);
Serial.print(config);
Serial.print(distance);
Serial.print(srv.read());
Serial.println();
}
void loop() {
processSanitizer();
report();
// check for special handling override
if (config == FAR && sanitizer_state == DELAY) {
if (read_distance() < 5) { // special handling
setNearConfig();
srv.write(turn_angle);
}
}
}
Continuing the discussion from Use another function during the running of Millis: