add nuevos cfgparam (battery, etc), modifica protocol, bajado uso dynamic memory

This commit is contained in:
Luca Borsari 2021-07-19 19:42:10 +02:00
parent 8592a958a4
commit 08e73f894e
9 changed files with 247 additions and 145 deletions

View file

@ -9,8 +9,7 @@ Revisions history
- Quit tail lap efect - Quit tail lap efect
- Add coin to main track for BATTERY_MODE=1 - Add coin to main track for BATTERY_MODE=1
* 2020-07-09: Ver 0.9.6 - Luca * 2020-12-17: Ver 0.9.6- Luca // Gitlab Commit = 0.9.6a
...............................
- Removed dependency from "AsyncSerialLib" - Removed dependency from "AsyncSerialLib"
- new class SerialCommand() - new class SerialCommand()
- Remove delay() (blocking) in Countdown phase - Remove delay() (blocking) in Countdown phase

View file

@ -62,8 +62,7 @@ int SerialCommand::checkSerial() {
void SerialCommand::sendCommand(char* str) { void SerialCommand::sendCommand(char* str) {
// get command length // get command length
int dlen=0; int dlen=0;
// for(; dlen<_bufLen; dlen++ ) { // limit transmitted command length to received command buffer for(; dlen<80; dlen++ ) { // "dlen<80" to avoid infinite loop on malformed str without EOC
for(; dlen<80; dlen++ ) { // limit transmitted command length to received command buffer
if(*(str+dlen) == _eoc ){ if(*(str+dlen) == _eoc ){
dlen++; // send EOC dlen++; // send EOC
break; break;

View file

@ -67,8 +67,6 @@ float controller_getSpeed( controller_t* ct) {
} }
float controller_getAccel ( void ) { float controller_getAccel ( void ) {
return ACEL; return ACEL;
} }

View file

@ -19,8 +19,6 @@ extern "C"{
#define PIN_VCC_ADC1 6 #define PIN_VCC_ADC1 6
#define PIN_VCC_ADC2 7 #define PIN_VCC_ADC2 7
enum ctr_type{ enum ctr_type{
NOT_DEFINED = 0, NOT_DEFINED = 0,
DIGITAL_MODE, DIGITAL_MODE,

View file

@ -48,10 +48,12 @@ void update_track( track_t* tck, car_t* car ) {
void process_aux_track( track_t* tck, car_t* car ){ void process_aux_track( track_t* tck, car_t* car ){
struct cfgtrack const* cfg = &tck->cfg.track; struct cfgtrack const* cfg = &tck->cfg.track;
struct cfgbattery const* battery = &tck->cfg.battery;
if ( (int)car->dist_aux == tck->ledcoin if ( (int)car->dist_aux == tck->ledcoin
&& car->speed <= controller_getAccel() ) { && car->speed <= controller_getAccel() ) {
car->speed = controller_getAccel ()*SPEED_BOOST_SCALER; car->speed = controller_getAccel() * (1.0 * battery->speed_boost_scaler);
tck->ledcoin = COIN_RESET; tck->ledcoin = COIN_RESET;
car->battery=100; car->battery=100;
}; };
@ -76,7 +78,8 @@ void process_main_track( track_t* tck, car_t* car ) {
car->speed += cfg->kg * r->high ; car->speed += cfg->kg * r->high ;
} }
if (BATTERY_MODE==1) { if(param_option_is_active(&tck->cfg, BATTERY_MODE_OPTION)){ // Battery Mode ON
struct cfgbattery const* battery = &tck->cfg.battery;
if ( cfg->nled_main-(int)(car->dist) % cfg->nled_main == tck->ledcoin if ( cfg->nled_main-(int)(car->dist) % cfg->nled_main == tck->ledcoin
&& controller_getStatus( car->ct ) == 0 //charge battery by push switch over coin && controller_getStatus( car->ct ) == 0 //charge battery by push switch over coin
//&& car->speed <= controller_getAccel() //&& car->speed <= controller_getAccel()
@ -84,22 +87,24 @@ void process_main_track( track_t* tck, car_t* car ) {
{car->charging=1;}; {car->charging=1;};
if (car->charging==1){ if (car->charging==1){
car->battery+=BATTERY_DELTA*2; car->battery+= battery->delta / 100.0 * 2;
car->speed =0; car->speed =0;
if (car->battery >100){tck->ledcoin = COIN_RESET; if (car->battery >100){tck->ledcoin = COIN_RESET;
car->battery=100; car->battery=100;
car->charging=0; car->charging=0;
//car->speed = controller_getAccel()*SPEED_BOOST_SCALER; //car->speed = controller_getAccel()*SPEED_BOOST_SCALER;
car->speed = 0.1*SPEED_BOOST_SCALER; car->speed = 0.1 * battery->speed_boost_scaler;
}; };
}; };
if (car->ct->flag_sw==0) { if (car->ct->flag_sw==0) {
if ((car->battery)>=BATTERY_MIN ) {car->battery-=BATTERY_DELTA;}; if ((car->battery)>=battery->min ) {car->battery-= battery->delta/100.0;};
}; };
if (car->ct->flag_sw==1) { if (car->ct->flag_sw==1) {
if (car->charging==1) {car->charging=0; if (car->charging==1) {car->charging=0;
car->speed = 0.1*SPEED_BOOST_SCALER/2; car->speed = (0.1*battery->speed_boost_scaler)/2;
}; };
}; };
}; };
@ -147,16 +152,22 @@ int tracklen_configure( track_t* tck, int nled ) {
return 0; return 0;
} }
int autostart_configure( track_t* tck, int autostart ) {
param_option_set(&tck->cfg, AUTOSTART_MODE_OPTION, (boolean) autostart);
return 0;
}
int boxlen_configure( track_t* tck, int box_len, int boxalwaysOn ) { int boxlen_configure( track_t* tck, int box_len, int boxalwaysOn ) {
struct cfgtrack* cfg = &tck->cfg.track; struct cfgtrack* cfg = &tck->cfg.track;
if ( boxalwaysOn != 0 && boxalwaysOn != 1 ) return -1; if ( boxalwaysOn != 0 && boxalwaysOn != 1 ) return -1;
if( box_len <= 0 || box_len >= cfg->nled_total ) return -1; if( box_len <= 0 || box_len >= cfg->nled_total ) return -1;
cfg->box_len = box_len; cfg->box_len = box_len;
cfg->box_alwaysOn = boxalwaysOn; //cfg->box_alwaysOn = boxalwaysOn;
param_option_set(&tck->cfg, BOX_MODE_OPTION, (boolean) boxalwaysOn);
// Update track->boxactive // Update track->boxactive
tck->boxactive = boxalwaysOn; tck->boxactive = boxalwaysOn;
return 0; return 0;
} }
@ -183,7 +194,7 @@ int track_configure( track_t* tck, int init_box ) {
} }
int ramp_configure( track_t* tck, int init, int center, int end, int high, int alwaysOn ) { int ramp_configure( track_t* tck, int init, int center, int end, uint8_t high, int alwaysOn ) {
struct cfgramp* ramp = &tck->cfg.ramp; struct cfgramp* ramp = &tck->cfg.ramp;
if ( init >= tck->cfg.track.nled_main || init <= 0 ) return -1; if ( init >= tck->cfg.track.nled_main || init <= 0 ) return -1;
@ -196,18 +207,27 @@ int ramp_configure( track_t* tck, int init, int center, int end, int high, int a
ramp->center = center; ramp->center = center;
ramp->end = end; ramp->end = end;
ramp->high = high; ramp->high = high;
ramp->alwaysOn = alwaysOn;
param_option_set(&tck->cfg, SLOPE_MODE_OPTION, (boolean) alwaysOn);
// Update track->rampactive // Update track->rampactive
/**
boolean rampactive = &tck->rampactive;
rampactive = alwaysOn;
**/
tck->rampactive = alwaysOn; tck->rampactive = alwaysOn;
return 0; return 0;
} }
int battery_configure( track_t* tck, int delta, int min, int boost, int active ){
struct cfgbattery* battery = &tck->cfg.battery;
battery->delta = delta;
battery->min = min;
battery->speed_boost_scaler = boost;
param_option_set(&tck->cfg, BATTERY_MODE_OPTION, (boolean) active);
return 0;
}
int race_configure( track_t* tck, int startline, int nlap, int nrepeat, int finishline ) { int race_configure( track_t* tck, int startline, int nlap, int nrepeat, int finishline ) {
struct cfgrace* race = &tck->cfg.race; struct cfgrace* race = &tck->cfg.race;

View file

@ -13,10 +13,12 @@ extern "C"{
#include "olr-controller.h" #include "olr-controller.h"
#include "olr-param.h" #include "olr-param.h"
#define SPD_MIN_TRACK_AUX 0.8
#define BATTERY_DELTA 0.03 #define SPD_MIN_TRACK_AUX 0.8 // change track by low speed
#define BATTERY_MIN 60 //#define BATTERY_DELTA 0.03 // Decrease BATTERY_DELTA on each controller activation - used in charge rate too
#define SPEED_BOOST_SCALER 10 //#define BATTERY_DELTA 3 // unsigned char value [1-254] / will be divided by 100 [0.01-2.54]
//#define BATTERY_MIN 60 // Battery does not descharge below BATTERY_MIN
//#define SPEED_BOOST_SCALER 10
enum stcoin{ enum stcoin{
COIN_RESET = -2, COIN_RESET = -2,
@ -51,11 +53,11 @@ typedef struct{
byte nlap; byte nlap;
byte repeats; byte repeats;
uint32_t color; uint32_t color;
int trackID; uint8_t trackID;
enum status st; enum status st;
bool leaving; bool leaving;
float battery; float battery;
int charging; bool charging;
}car_t; }car_t;
@ -87,6 +89,8 @@ bool box_isactive( track_t* tck );
int tracklen_configure( track_t* tck, int nled ); int tracklen_configure( track_t* tck, int nled );
int autostart_configure( track_t* tck, int autostart );
int boxlen_configure( track_t* tck, int box_len, int boxalwaysOn ); int boxlen_configure( track_t* tck, int box_len, int boxalwaysOn );
int physic_configure( track_t* tck, float kgp, float kfp ); int physic_configure( track_t* tck, float kgp, float kfp );
@ -97,7 +101,9 @@ void ramp_init( track_t* tck );
bool ramp_isactive( track_t* tck ); bool ramp_isactive( track_t* tck );
int ramp_configure( track_t* tck, int init, int center, int end, int high, int alwaysOn ); int ramp_configure( track_t* tck, int init, int center, int end, uint8_t high, int alwaysOn );
int battery_configure( track_t* tck, int delta, int min, int boost, int active );
int race_configure( track_t* tck, int startline, int nlap, int nrepeat, int finishline ); int race_configure( track_t* tck, int startline, int nlap, int nrepeat, int finishline );

View file

@ -1,27 +1,41 @@
#include "olr-param.h" #include "olr-param.h"
void param_setdefault( struct cfgparam* cfg ) { void param_setdefault( struct cfgparam* cfg ) {
cfg->setted = true; cfg->ver = CFGPARAM_VER;
cfg->race.startline = true; cfg->race.startline = true;
cfg->race.nlap = NUMLAP; cfg->race.nlap = NUMLAP;
cfg->race.nrepeat = 1; cfg->race.nrepeat = 1;
cfg->race.finishline = true; cfg->race.finishline = true;
param_option_set(cfg, BATTERY_MODE_OPTION, BATTERY_MODE);
cfg->battery.delta = 3;
cfg->battery.min = 60;
cfg->battery.speed_boost_scaler = 10;
param_option_set(cfg, AUTOSTART_MODE_OPTION, AUTOSTART_MODE);
cfg->ramp.init = 80; cfg->ramp.init = 80;
cfg->ramp.center = 90; cfg->ramp.center = 90;
cfg->ramp.end = 100; cfg->ramp.end = 100;
cfg->ramp.high = 6; cfg->ramp.high = 6;
cfg->ramp.alwaysOn = false; param_option_set(cfg, SLOPE_MODE_OPTION, SLOPE_ALWAYS_ON);
cfg->track.nled_total = MAXLED; cfg->track.nled_total = MAXLED; // MAXLED: Total LED number in the racetrack (default:300 -> 5mt, 60LED/mt Strip)
cfg->track.nled_main = MAXLED; // 240 when boxes length = 60 cfg->track.nled_main = MAXLED; // 240 when boxes length = 60
cfg->track.nled_aux = 0; // 60 cfg->track.nled_aux = 0; // 60
cfg->track.init_aux = -1; // 239 cfg->track.init_aux = -1; // 239
cfg->track.box_len = BOXLEN; cfg->track.box_len = BOXLEN;
cfg->track.box_alwaysOn = false; param_option_set(cfg, BOX_MODE_OPTION, BOX_ALWAYS_ON);
cfg->track.kf = 0.015; // friction constant cfg->track.kf = 0.015; // friction constant
cfg->track.kg = 0.006; // gravity constant - Used in Slope cfg->track.kg = 0.006; // gravity constant - Used in Slope
} }
void param_option_set( struct cfgparam* cfg, uint8_t option, boolean value ) {
bitWrite(cfg->option, option, value);
}
boolean param_option_is_active( struct cfgparam* cfg, uint8_t option) {
return(bitRead(cfg->option, option));
}

View file

@ -10,37 +10,60 @@ extern "C"{
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
// Default values loaded on "D" command received (Serial Protocol)
//////////////////////////////////////////////////////////////////
#define MAXLED 300 #define MAXLED 300
#define BOXLEN 60 #define BOXLEN 60
#define NUMLAP 5 #define NUMLAP 5
#define BATTERY_MODE false
#define AUTOSTART_MODE true
#define BOX_ALWAYS_ON false
#define SLOPE_ALWAYS_ON false
//////////////////////////////////////////////////////////////////
#define BATTERY_MODE 1
enum{ // Position (bit) into the cfgparam.option byte for On|Off settings
// Used in param_option_set()/param_option_is_active() calls
enum cfgparam_option_bit {
BATTERY_MODE_OPTION = 0,
AUTOSTART_MODE_OPTION = 1,
BOX_MODE_OPTION = 2,
SLOPE_MODE_OPTION = 3,
NOT_USED_1_OPTION = 4,
NOT_USED_2_OPTION = 5,
NOT_USED_3_OPTION = 6,
NOT_USED_4_OPTION = 7,
};
enum cfgpar {
CFGPARAM_VER = 6, // Change this value (+=1) every time the [cfgparam] struct is modified
// This will force an update with the new [struct] to the settings
// stored in EEPROM with an old (invalid) struct
LEN_UID = 16, LEN_UID = 16,
CFG_VER = 5, // "5" in V0.9.6 (manage "permanent" param for Box and Slope)
}; };
struct cfgrace{ struct cfgrace{
bool startline; // Used only in OLRNetwork bool startline; // Used only in OLRNetwork
int nlap; uint8_t nlap;
int nrepeat; // Used only in OLRNetwork uint8_t nrepeat; // Used only in OLRNetwork
bool finishline; // Used only in OLRNetwork bool finishline; // Used only in OLRNetwork
}; };
// struct cfgbattery{ // added in ver 0.9.7
uint8_t delta; // unsigned char value [1-254] / will be divided by 100 [0.01-2.54]
uint8_t min; // Battery does not descharge below this "min" percentage
uint8_t speed_boost_scaler;
} ;
struct cfgtrack { struct cfgtrack {
int nled_total; int nled_total;
int nled_main; int nled_main;
int nled_aux; int nled_aux;
int init_aux; int init_aux;
int box_len; // used to hold the Box Length if the default get changed. int box_len; // used to hold the Box Length if the default is changed.
// it's not possible to implicitly store it in nled_main,nled_aux // it's not possible to implicitly store it in nled_main,nled_aux
// because, if these are different to the default, box gets always activated // because, if these are different to the default, box gets always activated
// (the software does not chek "box_isactive" to draw car position) // (the software does not chek "box_isactive" to draw car position)
bool box_alwaysOn; // added in ver 0.9.6
float kf; float kf;
float kg; float kg;
@ -51,8 +74,7 @@ struct cfgramp {
int init; int init;
int center; int center;
int end; int end;
int high; uint8_t high;
bool alwaysOn; // added in ver 0.9.6
}; };
struct brdinfo { struct brdinfo {
@ -60,8 +82,10 @@ struct brdinfo {
}; };
struct cfgparam { struct cfgparam {
bool setted; uint8_t ver; // Version of this [cfgparam] struct
uint8_t option; // Bit-mapped byte to store 'active' on|off for options (Battery, AutoStart, BoxalwaysOn, etc)
struct cfgrace race; // added in ver 0.9.d struct cfgrace race; // added in ver 0.9.d
struct cfgbattery battery;
struct cfgtrack track; struct cfgtrack track;
struct cfgramp ramp; struct cfgramp ramp;
struct brdinfo info; struct brdinfo info;
@ -69,6 +93,8 @@ struct cfgparam {
void param_setdefault( struct cfgparam* cfg ); void param_setdefault( struct cfgparam* cfg );
void param_option_set( struct cfgparam* cfg, uint8_t option, boolean value );
boolean param_option_is_active( struct cfgparam* cfg, uint8_t option);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"

View file

@ -31,11 +31,11 @@
*/ */
// 2021/07/14 - Ver 0.9.6b // 2021/07/14 - Ver 0.9.6 - lab branch
// --see changelog.txt // --see changelog.txt
char const softwareId[] = "A4P0"; // A4P -> A = Open LED Race, 4P0 = Game ID (4P = 4 Players, 0=Type 0) char const softwareId[] = "A4P0"; // A4P -> A = Open LED Race, 4P0 = Game ID (4P = 4 Players, 0=Type 0)
char const version[] = "0.9.6b"; char const version[] = "0.9.6";
@ -49,7 +49,15 @@ char const version[] = "0.9.6b";
#define PIN_LED 2 // R 500 ohms to DI pin for WS2812 and WS2813, for WS2813 BI pin of first LED to GND , CAP 1000 uF to VCC 5v/GND,power supplie 5V 2A #define PIN_LED 2 // R 500 ohms to DI pin for WS2812 and WS2813, for WS2813 BI pin of first LED to GND , CAP 1000 uF to VCC 5v/GND,power supplie 5V 2A
#define PIN_AUDIO 3 // through CAP 2uf to speaker 8 ohms #define PIN_AUDIO 3 // through CAP 2uf to speaker 8 ohms
#define REC_COMMAND_BUFLEN 32 #define REC_COMMAND_BUFLEN 32 // received command buffer size
// At the moment, the largest received command is RAMP CONFIGURATION (A)
// ex: A1400,1430,1460,12,0[EOC] (for a 1500 LED strip)
// 21 CHAR
#define TX_COMMAND_BUFLEN 48 // send command buffer size
// At the moment, the largest send command is Q
// ex: QTK:1500,1500,0,-1,60,0,0.006,0.015,1[EOC] (for a 1500 LED strip)
// 37 CHAR
#define EOL '\n' // End of Command char used in Protocol #define EOL '\n' // End of Command char used in Protocol
#define COLOR1 track.Color(255,0,0) #define COLOR1 track.Color(255,0,0)
@ -69,8 +77,6 @@ char const version[] = "0.9.6b";
#define NEWRACE_DELAY 5000 #define NEWRACE_DELAY 5000
#define AUTO_START 0
enum{ enum{
MAX_CARS = 4, MAX_CARS = 4,
}; };
@ -140,11 +146,6 @@ static track_t tck;
static int const eeadrInfo = 0; static int const eeadrInfo = 0;
char txbuff[64];
static unsigned long lastmillis = 0; static unsigned long lastmillis = 0;
SoftTimer customDelay = SoftTimer(); // non blocking delay() SoftTimer customDelay = SoftTimer(); // non blocking delay()
@ -160,8 +161,6 @@ int win_music[] = {
3136 3136
}; };
//int TBEEP=3;
char tracksID[ NUM_TRACKS ][2] ={"U","M","B","I","O"}; char tracksID[ NUM_TRACKS ][2] ={"U","M","B","I","O"};
/* ----------- Function prototypes ------------------- */ /* ----------- Function prototypes ------------------- */
@ -175,10 +174,11 @@ void print_cars_positions( car_t* cars);
void run_racecycle( void ); void run_racecycle( void );
void draw_winner( track_t* tck, uint32_t color); void draw_winner( track_t* tck, uint32_t color);
char cmd[REC_COMMAND_BUFLEN]; // Stores command received by ReadSerialComand() char cmd[REC_COMMAND_BUFLEN]; // Stores command received by ReadSerialComand()
SerialCommand serialCommand = SerialCommand(cmd, REC_COMMAND_BUFLEN, EOL, &Serial); // get complete command from serial SerialCommand serialCommand = SerialCommand(cmd, REC_COMMAND_BUFLEN, EOL, &Serial); // get complete command from serial
char txbuff[TX_COMMAND_BUFLEN];
Adafruit_NeoPixel track; Adafruit_NeoPixel track;
@ -218,7 +218,7 @@ void setup() {
// Check Box before Physic/Sound to allow user to have Box and Physics with no sound // Check Box before Physic/Sound to allow user to have Box and Physics with no sound
if(digitalRead(DIG_CONTROL_2)==0 || tck.cfg.track.box_alwaysOn ) { //push switch 2 on reset for activate boxes (pit lane) if(digitalRead(DIG_CONTROL_2)==0 || param_option_is_active(&tck.cfg, BOX_MODE_OPTION) ) { //push switch 2 on reset for activate boxes (pit lane)
box_init( &tck ); box_init( &tck );
track_configure( &tck, tck.cfg.track.nled_total - tck.cfg.track.box_len ); track_configure( &tck, tck.cfg.track.nled_total - tck.cfg.track.box_len );
draw_box_entrypoint( &tck ); draw_box_entrypoint( &tck );
@ -226,7 +226,7 @@ void setup() {
track_configure( &tck, 0 ); track_configure( &tck, 0 );
} }
if( digitalRead(DIG_CONTROL_1)==0 || tck.cfg.ramp.alwaysOn ) { //push switch 1 on reset for activate physics if( digitalRead(DIG_CONTROL_1)==0 || param_option_is_active(&tck.cfg, SLOPE_MODE_OPTION) ) { // push switch 1 on reset for activate physics
ramp_init( &tck ); ramp_init( &tck );
draw_ramp( &tck ); draw_ramp( &tck );
track.show(); track.show();
@ -278,7 +278,8 @@ void loop() {
break; break;
case READY: case READY:
{if (AUTO_START==1){ { if(param_option_is_active(&tck.cfg, AUTOSTART_MODE_OPTION)){ // Auto-Start Mode ON
if(customDelay.elapsed()) { if(customDelay.elapsed()) {
for( int i = 0; i < race.numcars; ++i) { for( int i = 0; i < race.numcars; ++i) {
car_resetPosition( &cars[i] ); car_resetPosition( &cars[i] );
@ -348,8 +349,9 @@ void loop() {
draw_coin( &tck ); draw_coin( &tck );
else if( millis() > tck.ledtime ) else if( millis() > tck.ledtime )
tck.ledcoin = random( 20, tck.cfg.track.nled_aux - 20 ); tck.ledcoin = random( 20, tck.cfg.track.nled_aux - 20 );
}
else if (BATTERY_MODE==1){ } else {
if ( param_option_is_active(&tck.cfg, BATTERY_MODE_OPTION) ) { // Battery Mode ON
if( tck.ledcoin == COIN_RESET ) { if( tck.ledcoin == COIN_RESET ) {
tck.ledcoin = COIN_WAIT; tck.ledcoin = COIN_WAIT;
tck.ledtime = millis() + random(3000,8000); tck.ledtime = millis() + random(3000,8000);
@ -359,8 +361,7 @@ void loop() {
else if( millis() > tck.ledtime ) else if( millis() > tck.ledtime )
tck.ledcoin = random( LED_SEMAPHORE+4, tck.cfg.track.nled_main - 60); //valid zone from random charge (semaphore to 1 meter before to start-finish position tck.ledcoin = random( LED_SEMAPHORE+4, tck.cfg.track.nled_main - 60); //valid zone from random charge (semaphore to 1 meter before to start-finish position
} }
}
for( int i = 0; i < race.numcars; ++i ) { for( int i = 0; i < race.numcars; ++i ) {
run_racecycle( &cars[i], i ); run_racecycle( &cars[i], i );
@ -378,7 +379,7 @@ void loop() {
// Print p command!!! // Print p command!!!
unsigned long nowmillis = millis(); unsigned long nowmillis = millis();
if( abs( nowmillis - lastmillis ) > 100 ){ if( abs( nowmillis - lastmillis ) > 500 ){
lastmillis = nowmillis; lastmillis = nowmillis;
print_cars_positions( cars ); print_cars_positions( cars );
} }
@ -403,12 +404,12 @@ void loop() {
default: default:
{ {
sprintf( txbuff, "Software Error in main loop switch()"); sprintf( txbuff, "SwErr-01");
printdebug( txbuff, WARNING ); printdebug( txbuff, WARNING );
break; break;
} }
} // switch } // switch race.phase
} }
@ -496,23 +497,19 @@ void print_cars_positions( car_t* cars ) {
for( int i = 0; i < race.numcars; ++i ) { for( int i = 0; i < race.numcars; ++i ) {
int const rpos = get_relative_position( &cars[i] ); int const rpos = get_relative_position( &cars[i] );
if (BATTERY_MODE==1) {sprintf( txbuff, "p%d%s%d,%d,%d%c", i + 1, tracksID[cars[i].trackID], cars[i].nlap, rpos,(int)cars[i].battery, EOL );} sprintf( txbuff, "p%d%s%d,%d,%d%c", i + 1, tracksID[cars[i].trackID], cars[i].nlap, rpos,(int)cars[i].battery, EOL );
else {sprintf( txbuff, "p%d%s%d,%d%c", i + 1, tracksID[cars[i].trackID], cars[i].nlap, rpos, EOL );};
serialCommand.sendCommand(txbuff); serialCommand.sendCommand(txbuff);
//sendCommand(txbuff);
} }
} }
/* /*
* non-blocking version * non-blocking version
*/ */
boolean start_race_done( ) { boolean start_race_done( ) {
if(countdown_new_phase){ if(countdown_new_phase){
countdown_new_phase=false; countdown_new_phase=false;
//customDelay.start(CONTDOWN_PHASE_DURATION);
customDelay.start(CONTDOWN_PHASE_DURATION); customDelay.start(CONTDOWN_PHASE_DURATION);
strip_clear( &tck ); strip_clear( &tck );
if(ramp_isactive( &tck )) draw_ramp( &tck ); if(ramp_isactive( &tck )) draw_ramp( &tck );
@ -533,7 +530,6 @@ boolean start_race_done( ) {
track.setPixelColor(LED_SEMAPHORE-2, track.Color(0,255,0)); track.setPixelColor(LED_SEMAPHORE-2, track.Color(0,255,0));
break; break;
case 4: case 4:
//customDelay.start(CONTDOWN_STARTSOUND_DURATION);
customDelay.start(CONTDOWN_STARTSOUND_DURATION); customDelay.start(CONTDOWN_STARTSOUND_DURATION);
tone(PIN_AUDIO,880); tone(PIN_AUDIO,880);
track.setPixelColor(LED_SEMAPHORE-2, track.Color(0,0,0)); track.setPixelColor(LED_SEMAPHORE-2, track.Color(0,0,0));
@ -614,23 +610,29 @@ void draw_car_tail( track_t* tck, car_t* car ) {
void draw_car( track_t* tck, car_t* car ) { void draw_car( track_t* tck, car_t* car ) {
struct cfgtrack const* cfg = &tck->cfg.track; struct cfgtrack const* cfg = &tck->cfg.track;
struct cfgbattery const* battery = &tck->cfg.battery;
switch ( car->trackID ){ switch ( car->trackID ){
case TRACK_MAIN: case TRACK_MAIN:
for(int i=0; i<=1; ++i ) for(int i=0; i<=1; ++i )
track.setPixelColor( ((word)car->dist % cfg->nled_main) - i, car->color ); track.setPixelColor( ((word)car->dist % cfg->nled_main) - i, car->color );
if (BATTERY_MODE==1) {if ( car->charging==1 ) {track.setPixelColor( ((word)car->dist % cfg->nled_main) - 2, 0x010100 * 50*(millis()/(201-2*(byte)car->battery)%2));} if(param_option_is_active(&tck->cfg, BATTERY_MODE_OPTION)){ // Battery Mode ON
else if (car->battery<=BATTERY_MIN) if ( car->charging==1 ) {
track.setPixelColor( ((word)car->dist % cfg->nled_main) - 2, 0x010100 * 50*(millis()/(201-2*(byte)car->battery)%2));
} else if (car->battery <= battery->min)
if ((millis()%100)>50) track.setPixelColor( ((word)car->dist % cfg->nled_main) - 2, WARNING_BLINK_COLOR ); if ((millis()%100)>50) track.setPixelColor( ((word)car->dist % cfg->nled_main) - 2, WARNING_BLINK_COLOR );
} }
break; break;
case TRACK_AUX: case TRACK_AUX:
for(int i=0; i<=1; ++i ) for(int i=0; i<=1; ++i )
track.setPixelColor( (word)(cfg->nled_main + cfg->nled_aux - car->dist_aux) + i, car->color); track.setPixelColor( (word)(cfg->nled_main + cfg->nled_aux - car->dist_aux) + i, car->color);
if (BATTERY_MODE==1) {if ( car->charging==1 ) {track.setPixelColor( (word)(cfg->nled_main + cfg->nled_aux - car->dist_aux) + 2, 0x010100 * 50*(millis()/(201-2*(byte)car->battery)%2));} if(param_option_is_active(&tck->cfg, BATTERY_MODE_OPTION)){ // Battery Mode ON
else if (car->battery<=BATTERY_MIN)
if ((millis()%100)>50) track.setPixelColor( (word)(cfg->nled_main + cfg->nled_aux - car->dist_aux) + 2, WARNING_BLINK_COLOR);
if ( car->charging==1 ) {
track.setPixelColor( (word)(cfg->nled_main + cfg->nled_aux - car->dist_aux) + 2, 0x010100 * 50*(millis()/(201-2*(byte)car->battery)%2));
} else if (car->battery <= battery->min)
if ((millis()%100)>50)
track.setPixelColor( (word)(cfg->nled_main + cfg->nled_aux - car->dist_aux) + 2, WARNING_BLINK_COLOR);
} }
break; break;
} }
@ -865,6 +867,52 @@ ack_t manageSerialCommand() {
} }
break; break;
case 'E' : // Parse Battery configuration -> Edelta,min,boost,active
{
ack.type = cmd[0];
char * pch = strtok (cmd,"E");
if( !pch ) return ack;
pch = strtok (pch, "," );
if( !pch ) return ack;
int delta = atoi( pch );
pch = strtok (NULL, "," );
if( !pch ) return ack;
int min = atoi( pch );
pch = strtok (NULL, "," );
if( !pch ) return ack;
int boost = atoi( pch );
pch = strtok (NULL, ",");
if( !pch ) return ack;
int active = atoi( pch );
int err = battery_configure( &tck, delta, min, boost, active );
if( err ) return ack;
ack.rp = OK;
}
break;
case 'G' : //Parse Autostart configuration -> Gautostart
{
ack.type = cmd[0];
char * pch = strtok (cmd,"G");
if( !pch ) return ack;
int autostart = atoi( cmd + 1 );
int err = autostart_configure( &tck, autostart);
if( err ) return ack;
ack.rp = OK;
}
break;
case 'K': // Parse Physic simulation parameters case 'K': // Parse Physic simulation parameters
{ {
ack.type = cmd[0]; ack.type = cmd[0];
@ -899,8 +947,8 @@ ack_t manageSerialCommand() {
// Update box/slope active in current Track Struct with values // Update box/slope active in current Track Struct with values
// just loaded (for show_cfgpars_onstrip()) // just loaded (for show_cfgpars_onstrip())
struct cfgparam const* cfg = &tck.cfg; struct cfgparam const* cfg = &tck.cfg;
tck.boxactive = cfg->track.box_alwaysOn; tck.boxactive = param_option_is_active(&tck.cfg, BOX_MODE_OPTION);
tck.rampactive = cfg->ramp.alwaysOn; tck.rampactive = param_option_is_active(&tck.cfg, SLOPE_MODE_OPTION);
show_cfgpars_onstrip(); show_cfgpars_onstrip();
} }
@ -944,28 +992,39 @@ ack_t manageSerialCommand() {
case 'Q': // Get current configuration Info case 'Q': // Get current configuration Info
{ {
struct cfgparam const* cfg = &tck.cfg; struct cfgparam const* cfg = &tck.cfg;
sprintf( txbuff, "%s:%d,%d,%d,%d,%d,%d,%d.%03d,%d.%03d%c", "QTRACK", sprintf( txbuff, "%s:%d,%d,%d,%d,%d,%d,%d.%03d,%d.%03d,%d%c", "QTK",
cfg->track.nled_total, cfg->track.nled_total,
cfg->track.nled_main, cfg->track.nled_main,
cfg->track.nled_aux, cfg->track.nled_aux,
cfg->track.init_aux, cfg->track.init_aux,
cfg->track.box_len, cfg->track.box_len,
cfg->track.box_alwaysOn, //cfg->track.box_alwaysOn,
param_option_is_active(&tck.cfg, BOX_MODE_OPTION),
(int)cfg->track.kg, (int)(cfg->track.kg*1000)%1000, // std arduino sprintf() missing %f (int)cfg->track.kg, (int)(cfg->track.kg*1000)%1000, // std arduino sprintf() missing %f
(int)cfg->track.kf, (int)(cfg->track.kf*1000)%1000, // std arduino sprintf() missing %f (int)cfg->track.kf, (int)(cfg->track.kf*1000)%1000, // std arduino sprintf() missing %f
param_option_is_active(&tck.cfg, AUTOSTART_MODE_OPTION),
EOL ); EOL );
serialCommand.sendCommand(txbuff); serialCommand.sendCommand(txbuff);
sprintf( txbuff, "%s:%d,%d,%d,%d,%d%c", "QRAMP", sprintf( txbuff, "%s:%d,%d,%d,%d,%d%c", "QRP",
cfg->ramp.init, cfg->ramp.init,
cfg->ramp.center, cfg->ramp.center,
cfg->ramp.end, cfg->ramp.end,
cfg->ramp.high, cfg->ramp.high,
cfg->ramp.alwaysOn, //cfg->ramp.alwaysOn,
param_option_is_active(&tck.cfg, SLOPE_MODE_OPTION),
EOL ); EOL );
serialCommand.sendCommand(txbuff); serialCommand.sendCommand(txbuff);
sprintf( txbuff, "%s:%d,%d,%d,%d%c", "QRACE", sprintf( txbuff, "%s:%d,%d,%d,%d%c", "QBT",
cfg->battery.delta,
cfg->battery.min,
cfg->battery.speed_boost_scaler,
param_option_is_active(&tck.cfg, BATTERY_MODE_OPTION),
EOL );
serialCommand.sendCommand(txbuff);
sprintf( txbuff, "%s:%d,%d,%d,%d%c", "QRC",
cfg->race.startline, cfg->race.startline,
cfg->race.nlap, cfg->race.nlap,
cfg->race.nrepeat, cfg->race.nrepeat,
@ -1028,46 +1087,29 @@ void enter_configuration_mode(){
void param_load( struct cfgparam* cfg ) { void param_load( struct cfgparam* cfg ) {
int cfgversion;
int eeAdress = eeadrInfo;
EEPROM.get( eeAdress, tck.cfg );
eeAdress += sizeof( cfgparam );
EEPROM.get( eeAdress, cfgversion );
sprintf( txbuff, "%s:%d%c", "Parameters Loaded from EEPROM - Cfg ver", cfgversion, EOL ); /**
serialCommand.sendCommand(txbuff); // Ignore EEPROM params during development of a new version of the [cfgparam]
if ( cfgversion != CFG_VER ) {
param_setdefault( &tck.cfg ); param_setdefault( &tck.cfg );
eeAdress = 0; sprintf( txbuff, "%s%c", "Temporary....DEFAULT PAREMETRS LOADED ", EOL );
EEPROM.put( eeAdress, tck.cfg ); serialCommand.sendCommand(txbuff);
eeAdress += sizeof( cfgparam ); return;
EEPROM.put( eeAdress, CFG_VER ); **/
sprintf( txbuff, "%s%c", "DEFAULT PAREMETRS LOADED (and Stored in EEPROM)", EOL );
EEPROM.get( eeadrInfo, tck.cfg );
sprintf( txbuff, "%s:%d%c", "EEPROM-v", tck.cfg.ver, EOL );
serialCommand.sendCommand(txbuff); serialCommand.sendCommand(txbuff);
if ( tck.cfg.ver != CFGPARAM_VER ) { // [cfgparam.ver] read form EEPROM != [#define CFGPARAM_VER] in the code
// Each time a new version of the code modify the [cfgparam] struct, [#define CFGPARAM_VER] is also
// changed to force the code enter here.
// The previous values stored in EEPROM are invalid and need to be reset-to-default and
// stored in the EEPROM again with the new "structure"
param_setdefault( &tck.cfg );
EEPROM.put( eeadrInfo, tck.cfg );
sprintf( txbuff, "%s:%d%c", "DEFAULT->EEPROM-v)", tck.cfg.ver, EOL );
serialCommand.sendCommand(txbuff);
} }
} }
/*
* Custon Non-Blocking Delay() functions
* customDelayStart(unsigned long timeout)
* customDelayElapsed
*/
/**
unsigned long customDelay_startTime=0;
unsigned long customDelay_timeout=0;
void customDelayStart(unsigned long tout) {
customDelay_timeout=tout;
customDelay_startTime=millis();
}
boolean customDelayElapsed(){
if((millis() - customDelay_startTime) > customDelay_timeout) {
return(true);
}
return(false);
}
**/