Merge branch 'lab'
This commit is contained in:
commit
01cce75963
9 changed files with 415 additions and 133 deletions
|
@ -1,8 +1,30 @@
|
||||||
Revisions history
|
Revisions history
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
* 2021-11-20: Ver 0.9.7 - Luca - Branch: "lab"
|
||||||
|
...............................................
|
||||||
|
- Changed Version Number to 0.9.7
|
||||||
|
- ready to merge with master branch
|
||||||
|
- ver 0.9.7 managed by companion desktopApp
|
||||||
|
|
||||||
|
* 2021-07-20: Ver 0.9.6 - Luca - Branch: "lab"
|
||||||
|
- Manage config parameters (load/save/protocol) for:
|
||||||
|
- NEW: Autostart ("G")
|
||||||
|
- NEW: Battery ("E")
|
||||||
|
- NEW: Players number ("P")
|
||||||
|
- UPD: "Q" ("Get configuration" output changed)
|
||||||
|
-- Not compatible with previous versions
|
||||||
|
- UPD: "~" ---> "*" (Commmand ID for "Leave configuration mode" changed)
|
||||||
|
|
||||||
|
* 2021-07-13: Ver 0.9.6 - Gerardo - Branch: "lab"
|
||||||
|
- Charge battery function and telemetry test code (add BATTERY ( ",<0-100 value> to end of "p" serial status ))
|
||||||
|
- Add BATTERY_DELTA variable for decremet battery on push buton flag change
|
||||||
|
- Add BATTERY_MIN for user warning on low battery status
|
||||||
|
- Add blink efect on min battery condition
|
||||||
|
- Quit tail lap efect
|
||||||
|
- Add coin to main track for BATTERY_MODE=1
|
||||||
|
|
||||||
* 2020-12-17: Ver 0.9.6- Luca // Gitlab Commit = 0.9.6a
|
* 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
|
||||||
|
|
Binary file not shown.
|
@ -66,6 +66,7 @@ float controller_getSpeed( controller_t* ct) {
|
||||||
return speed;
|
return speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float controller_getAccel ( void ) {
|
float controller_getAccel ( void ) {
|
||||||
return ACEL;
|
return ACEL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -10,10 +10,12 @@ void car_init( car_t* car, controller_t* ct, uint32_t color ) {
|
||||||
car->speed=0;
|
car->speed=0;
|
||||||
car->dist=0;
|
car->dist=0;
|
||||||
car->dist_aux=0;
|
car->dist_aux=0;
|
||||||
|
car->battery=100;
|
||||||
|
car->charging=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void car_updateController( car_t* car ) {
|
void car_updateController( car_t* car ) {
|
||||||
car->speed += controller_getSpeed( car->ct );
|
car->speed += controller_getSpeed( car->ct )*car->battery/100;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_track( track_t* tck, car_t* car ) {
|
void update_track( track_t* tck, car_t* car ) {
|
||||||
|
@ -23,8 +25,8 @@ void update_track( track_t* tck, car_t* car ) {
|
||||||
|
|
||||||
if ( car->trackID == TRACK_MAIN
|
if ( car->trackID == TRACK_MAIN
|
||||||
&& (int)car->dist % cfg->nled_main == (cfg->init_aux-(cfg->nled_aux))
|
&& (int)car->dist % cfg->nled_main == (cfg->init_aux-(cfg->nled_aux))
|
||||||
// && controller_getStatus( ct ) == 0 ) { //change track by switch
|
&& controller_getStatus( ct ) == 0 ) { //change track by switch
|
||||||
&& (car->speed <= SPD_MIN_TRACK_AUX )) { //change track by low speed
|
// && (car->speed <= SPD_MIN_TRACK_AUX )) { //change track by low speed
|
||||||
|
|
||||||
car->trackID = TRACK_AUX;
|
car->trackID = TRACK_AUX;
|
||||||
car->dist_aux = 0;
|
car->dist_aux = 0;
|
||||||
|
@ -46,11 +48,14 @@ 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 ()*50;
|
car->speed = controller_getAccel() * (1.0 * battery->speed_boost_scaler);
|
||||||
|
|
||||||
tck->ledcoin = COIN_RESET;
|
tck->ledcoin = COIN_RESET;
|
||||||
|
car->battery=100;
|
||||||
};
|
};
|
||||||
|
|
||||||
car->speed -= car->speed * cfg->kf;
|
car->speed -= car->speed * cfg->kf;
|
||||||
|
@ -73,6 +78,37 @@ void process_main_track( track_t* tck, car_t* car ) {
|
||||||
car->speed += cfg->kg * r->high ;
|
car->speed += cfg->kg * r->high ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
&& controller_getStatus( car->ct ) == 0 //charge battery by push switch over coin
|
||||||
|
//&& car->speed <= controller_getAccel()
|
||||||
|
)
|
||||||
|
{car->charging=1;};
|
||||||
|
|
||||||
|
if (car->charging==1){
|
||||||
|
car->battery+= battery->delta / 100.0 * 2;
|
||||||
|
|
||||||
|
car->speed =0;
|
||||||
|
if (car->battery >100){tck->ledcoin = COIN_RESET;
|
||||||
|
car->battery=100;
|
||||||
|
car->charging=0;
|
||||||
|
//car->speed = controller_getAccel()*SPEED_BOOST_SCALER;
|
||||||
|
car->speed = 0.1 * battery->speed_boost_scaler;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if (car->ct->flag_sw==0) {
|
||||||
|
if ((car->battery)>=battery->min ) {car->battery-= battery->delta/100.0;};
|
||||||
|
|
||||||
|
};
|
||||||
|
if (car->ct->flag_sw==1) {
|
||||||
|
if (car->charging==1) {car->charging=0;
|
||||||
|
car->speed = (0.1*battery->speed_boost_scaler)/2;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
car->speed -= car->speed * cfg->kf;
|
car->speed -= car->speed * cfg->kf;
|
||||||
car->dist += car->speed;
|
car->dist += car->speed;
|
||||||
|
|
||||||
|
@ -96,6 +132,7 @@ void car_resetPosition( car_t* car) {
|
||||||
car->dist_aux = 0;
|
car->dist_aux = 0;
|
||||||
car->nlap = 1;
|
car->nlap = 1;
|
||||||
car->leaving = false;
|
car->leaving = false;
|
||||||
|
car->battery = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
void box_init( track_t* tck ) {
|
void box_init( track_t* tck ) {
|
||||||
|
@ -115,16 +152,48 @@ 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 players_n_configure( track_t* tck, int val ) {
|
||||||
|
switch(val){
|
||||||
|
case 2 :
|
||||||
|
param_option_set(&tck->cfg, PLAYER_3_OPTION, false);
|
||||||
|
param_option_set(&tck->cfg, PLAYER_4_OPTION, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3 :
|
||||||
|
param_option_set(&tck->cfg, PLAYER_3_OPTION, true);
|
||||||
|
param_option_set(&tck->cfg, PLAYER_4_OPTION, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4 :
|
||||||
|
param_option_set(&tck->cfg, PLAYER_3_OPTION, true);
|
||||||
|
param_option_set(&tck->cfg, PLAYER_4_OPTION, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +220,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;
|
||||||
|
@ -164,18 +233,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;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +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 SPD_MIN_TRACK_AUX 0.8 // change track by low speed
|
||||||
|
//#define BATTERY_DELTA 0.03 // Decrease BATTERY_DELTA on each controller activation - used in charge rate too
|
||||||
|
//#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,
|
||||||
|
@ -48,9 +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;
|
||||||
|
bool charging;
|
||||||
}car_t;
|
}car_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,6 +89,10 @@ 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 players_n_configure( track_t* tck, int val );
|
||||||
|
|
||||||
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 );
|
||||||
|
@ -92,7 +103,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 );
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,44 @@
|
||||||
#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
|
||||||
|
|
||||||
|
param_option_set(cfg, PLAYER_3_OPTION, PLAYER_3);
|
||||||
|
param_option_set(cfg, PLAYER_4_OPTION, PLAYER_4);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,39 +10,65 @@ 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 false
|
||||||
|
#define BOX_ALWAYS_ON false
|
||||||
|
#define SLOPE_ALWAYS_ON false
|
||||||
|
#define PLAYER_3 false
|
||||||
|
#define PLAYER_4 false
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
PLAYER_3_OPTION = 4,
|
||||||
|
PLAYER_4_OPTION = 5,
|
||||||
|
NOT_USED_3_OPTION = 6,
|
||||||
|
NOT_USED_4_OPTION = 7,
|
||||||
|
};
|
||||||
|
|
||||||
enum{
|
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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ramp centred in LED 100 with 10 led fordward and 10 backguard
|
// ramp centred in LED 100 with 10 led fordward and 10 backguard
|
||||||
|
@ -50,8 +76,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 {
|
||||||
|
@ -59,8 +84,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;
|
||||||
|
@ -68,6 +95,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"
|
||||||
|
|
|
@ -29,12 +29,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// 2020/12/10 - Ver 0.9.6
|
// 2021/07/20 - 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.6";
|
char const version[] = "0.9.7";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <Adafruit_NeoPixel.h>
|
#include <Adafruit_NeoPixel.h>
|
||||||
|
@ -48,7 +47,14 @@ char const version[] = "0.9.6";
|
||||||
#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 // received command buffer size
|
#define REC_COMMAND_BUFLEN 32 // received command buffer size
|
||||||
#define TX_COMMAND_BUFLEN 80 // send 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)
|
||||||
|
@ -57,9 +63,11 @@ char const version[] = "0.9.6";
|
||||||
#define COLOR4 track.Color(255,255,255)
|
#define COLOR4 track.Color(255,255,255)
|
||||||
|
|
||||||
#define COLOR_RAMP track.Color(64,0,64)
|
#define COLOR_RAMP track.Color(64,0,64)
|
||||||
#define COLOR_COIN track.Color(0,255,255)
|
#define COLOR_COIN track.Color(40,34,0)
|
||||||
#define COLOR_BOXMARKS track.Color(64,64,0)
|
#define COLOR_BOXMARKS track.Color(64,64,0)
|
||||||
#define LED_SEMAPHORE 12
|
#define LED_SEMAPHORE 12
|
||||||
|
#define WARNING_BLINK_COLOR track.Color(32,20,0)
|
||||||
|
|
||||||
|
|
||||||
#define CONTDOWN_PHASE_DURATION 2000
|
#define CONTDOWN_PHASE_DURATION 2000
|
||||||
#define CONTDOWN_STARTSOUND_DURATION 40
|
#define CONTDOWN_STARTSOUND_DURATION 40
|
||||||
|
@ -124,6 +132,7 @@ byte SMOTOR=0;
|
||||||
int TBEEP=0;
|
int TBEEP=0;
|
||||||
int FBEEP=0;
|
int FBEEP=0;
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------*/
|
/*------------------------------------------------------*/
|
||||||
enum loglevel verbose = DISABLE;
|
enum loglevel verbose = DISABLE;
|
||||||
|
|
||||||
|
@ -134,11 +143,6 @@ static track_t tck;
|
||||||
|
|
||||||
static int const eeadrInfo = 0;
|
static int const eeadrInfo = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned long lastmillis = 0;
|
static unsigned long lastmillis = 0;
|
||||||
|
|
||||||
SoftTimer customDelay = SoftTimer(); // non blocking delay()
|
SoftTimer customDelay = SoftTimer(); // non blocking delay()
|
||||||
|
@ -154,8 +158,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 ------------------- */
|
||||||
|
@ -169,7 +171,6 @@ 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
|
||||||
|
|
||||||
|
@ -197,13 +198,13 @@ void setup() {
|
||||||
|
|
||||||
race.numcars = 2;
|
race.numcars = 2;
|
||||||
|
|
||||||
if( controller_isActive( DIG_CONTROL_3 )) {
|
if( controller_isActive( DIG_CONTROL_3 ) || param_option_is_active(&tck.cfg, PLAYER_3_OPTION) || param_option_is_active(&tck.cfg, PLAYER_4_OPTION) ) {
|
||||||
controller_init( &switchs[2], DIGITAL_MODE, DIG_CONTROL_3 );
|
controller_init( &switchs[2], DIGITAL_MODE, DIG_CONTROL_3 );
|
||||||
car_init( &cars[2], &switchs[2], COLOR3 );
|
car_init( &cars[2], &switchs[2], COLOR3 );
|
||||||
++race.numcars;
|
++race.numcars;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( controller_isActive( DIG_CONTROL_4 )) {
|
if( controller_isActive( DIG_CONTROL_4 ) || param_option_is_active(&tck.cfg, PLAYER_4_OPTION)) {
|
||||||
controller_init( &switchs[3], DIGITAL_MODE, DIG_CONTROL_4 );
|
controller_init( &switchs[3], DIGITAL_MODE, DIG_CONTROL_4 );
|
||||||
car_init( &cars[3], &switchs[3], COLOR4 );
|
car_init( &cars[3], &switchs[3], COLOR4 );
|
||||||
++race.numcars;
|
++race.numcars;
|
||||||
|
@ -214,7 +215,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 );
|
||||||
|
@ -222,7 +223,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();
|
||||||
|
@ -275,6 +276,7 @@ void loop() {
|
||||||
|
|
||||||
case READY:
|
case READY:
|
||||||
{
|
{
|
||||||
|
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] );
|
||||||
|
@ -284,6 +286,30 @@ void loop() {
|
||||||
race.phase = COUNTDOWN;
|
race.phase = COUNTDOWN;
|
||||||
send_phase( race.phase );
|
send_phase( race.phase );
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
int pstart=0;
|
||||||
|
strip_clear( &tck );
|
||||||
|
if( ramp_isactive( &tck ) )
|
||||||
|
draw_ramp( &tck );
|
||||||
|
if( box_isactive( &tck ) )
|
||||||
|
draw_box_entrypoint( &tck );
|
||||||
|
for( int i = 0; i < race.numcars; ++i) {
|
||||||
|
if (controller_getStatus(cars[i].ct)==false){
|
||||||
|
car_resetPosition( &cars[i] );
|
||||||
|
//Serial.println(i);
|
||||||
|
track.setPixelColor(i,cars[i].color);
|
||||||
|
cars[i].repeats = 0;
|
||||||
|
pstart++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
track.setPixelColor(LED_SEMAPHORE , ((millis()/5)%64)*0x010100 );
|
||||||
|
track.show();
|
||||||
|
if (pstart==race.numcars){tck.ledcoin = COIN_RESET;
|
||||||
|
race.phase = COUNTDOWN;
|
||||||
|
send_phase( race.phase );}
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -307,6 +333,11 @@ void loop() {
|
||||||
{
|
{
|
||||||
strip_clear( &tck );
|
strip_clear( &tck );
|
||||||
|
|
||||||
|
if( ramp_isactive( &tck ) )
|
||||||
|
draw_ramp( &tck );
|
||||||
|
if( box_isactive( &tck ) )
|
||||||
|
draw_box_entrypoint( &tck );
|
||||||
|
|
||||||
if( box_isactive( &tck ) ) {
|
if( box_isactive( &tck ) ) {
|
||||||
if( tck.ledcoin == COIN_RESET ) {
|
if( tck.ledcoin == COIN_RESET ) {
|
||||||
tck.ledcoin = COIN_WAIT;
|
tck.ledcoin = COIN_WAIT;
|
||||||
|
@ -316,12 +347,19 @@ 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 );
|
||||||
}
|
|
||||||
|
|
||||||
if( ramp_isactive( &tck ) )
|
} else {
|
||||||
draw_ramp( &tck );
|
if ( param_option_is_active(&tck.cfg, BATTERY_MODE_OPTION) ) { // Battery Mode ON
|
||||||
if( box_isactive( &tck ) )
|
if( tck.ledcoin == COIN_RESET ) {
|
||||||
draw_box_entrypoint( &tck );
|
tck.ledcoin = COIN_WAIT;
|
||||||
|
tck.ledtime = millis() + random(3000,8000);
|
||||||
|
}
|
||||||
|
if( tck.ledcoin > 0 )
|
||||||
|
draw_coin( &tck );
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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 );
|
||||||
|
@ -339,7 +377,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 ) > 250 ){
|
||||||
lastmillis = nowmillis;
|
lastmillis = nowmillis;
|
||||||
print_cars_positions( cars );
|
print_cars_positions( cars );
|
||||||
}
|
}
|
||||||
|
@ -364,12 +402,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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,22 +495,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] );
|
||||||
sprintf( txbuff, "p%d%s%d,%d%c", i + 1, tracksID[cars[i].trackID], cars[i].nlap, rpos, 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 );
|
||||||
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 );
|
||||||
|
@ -493,7 +528,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));
|
||||||
|
@ -557,7 +591,7 @@ void draw_winner( track_t* tck, uint32_t color) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_car( track_t* tck, car_t* car ) {
|
void draw_car_tail( track_t* tck, car_t* car ) {
|
||||||
struct cfgtrack const* cfg = &tck->cfg.track;
|
struct cfgtrack const* cfg = &tck->cfg.track;
|
||||||
|
|
||||||
switch ( car->trackID ){
|
switch ( car->trackID ){
|
||||||
|
@ -572,6 +606,36 @@ 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 cfgbattery const* battery = &tck->cfg.battery;
|
||||||
|
|
||||||
|
switch ( car->trackID ){
|
||||||
|
case TRACK_MAIN:
|
||||||
|
for(int i=0; i<=1; ++i )
|
||||||
|
track.setPixelColor( ((word)car->dist % cfg->nled_main) - i, car->color );
|
||||||
|
if(param_option_is_active(&tck->cfg, BATTERY_MODE_OPTION)){ // Battery Mode ON
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TRACK_AUX:
|
||||||
|
for(int i=0; i<=1; ++i )
|
||||||
|
track.setPixelColor( (word)(cfg->nled_main + cfg->nled_aux - car->dist_aux) + i, car->color);
|
||||||
|
if(param_option_is_active(&tck->cfg, BATTERY_MODE_OPTION)){ // Battery Mode ON
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display on LED Strip current values for Slope and Pitlane
|
* Display on LED Strip current values for Slope and Pitlane
|
||||||
|
@ -659,7 +723,7 @@ ack_t manageSerialCommand() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '~' : // Exit "Configure Mode"
|
case '*' : // Exit "Configure Mode"
|
||||||
{
|
{
|
||||||
ack.type = cmd[0];
|
ack.type = cmd[0];
|
||||||
if(race.phase == CONFIG) { // Ignore command if Board is not in "Configure Mode"
|
if(race.phase == CONFIG) { // Ignore command if Board is not in "Configure Mode"
|
||||||
|
@ -801,6 +865,69 @@ 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 'P' : //Parse Player 3/4 configuration -> P[2|3|4]
|
||||||
|
{
|
||||||
|
ack.type = cmd[0];
|
||||||
|
|
||||||
|
char * pch = strtok (cmd,"P");
|
||||||
|
if( !pch ) return ack;
|
||||||
|
|
||||||
|
int autostart = atoi( cmd + 1 );
|
||||||
|
int err = players_n_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];
|
||||||
|
@ -835,8 +962,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();
|
||||||
}
|
}
|
||||||
|
@ -880,32 +1007,45 @@ 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,%d,%d%c", "QRC",
|
||||||
cfg->race.startline,
|
cfg->race.startline,
|
||||||
cfg->race.nlap,
|
cfg->race.nlap,
|
||||||
cfg->race.nrepeat,
|
cfg->race.nrepeat,
|
||||||
cfg->race.finishline,
|
cfg->race.finishline,
|
||||||
|
param_option_is_active(&tck.cfg, PLAYER_3_OPTION),
|
||||||
|
param_option_is_active(&tck.cfg, PLAYER_4_OPTION),
|
||||||
EOL );
|
EOL );
|
||||||
serialCommand.sendCommand(txbuff);
|
serialCommand.sendCommand(txbuff);
|
||||||
|
|
||||||
|
@ -964,46 +1104,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);
|
|
||||||
}
|
|
||||||
**/
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue