2018-06-10 17:23:11 +00:00
//flash as Wemos D1 R2 & mini
2020-12-12 20:50:20 +00:00
# include <Arduino.h>
2018-04-08 16:20:11 +00:00
# include <Adafruit_NeoPixel.h>
# ifdef __AVR__
# include <avr/power.h>
# endif
2019-04-07 14:07:55 +00:00
# include <EEPROM.h>
# define EEPROMSTARTADDRESS_HEIGHTMAP 8
2018-04-08 16:20:11 +00:00
# include <vector>
# include "wagon.h"
2018-07-15 15:08:34 +00:00
# include "effect.h"
2018-07-10 22:08:14 +00:00
# include "fx_scanner.h"
2018-07-15 15:26:07 +00:00
# include "fx_flash.h"
2020-12-14 22:30:12 +00:00
# include "fx_stars.h"
2018-04-08 16:20:11 +00:00
2019-06-04 23:54:20 +00:00
2020-12-12 20:50:20 +00:00
void resetHeightmap ( ) ;
void printHeightmapRaw ( ) ;
void interpolateHeightValues ( ) ;
void previewHeightmap ( int waittime ) ;
2020-12-13 00:12:37 +00:00
void allBlack ( int waittime ) ;
2020-12-12 20:50:20 +00:00
void spawnWagon ( ) ;
void spawnWagon ( float pos , float wagonlength , float startvel , float startacc , float mass , uint8_t wheelcolor ) ;
void checkSerial ( ) ;
void loop_configmode ( ) ;
void loop_achterbahn ( ) ;
void removeAllWagons ( ) ;
uint32_t Wheel ( byte WheelPos ) ;
void loadHeightmapRaw ( ) ;
void saveHeightmapRaw ( ) ;
2020-12-14 22:30:12 +00:00
# define PIN_LDR A0 //comment if not used
2020-12-12 20:50:20 +00:00
2018-04-08 16:20:11 +00:00
# define PIN D2
2018-05-06 16:14:11 +00:00
# define NUMPIXELS 600
2018-04-08 16:20:11 +00:00
Adafruit_NeoPixel strip = Adafruit_NeoPixel ( NUMPIXELS , PIN , NEO_GRB + NEO_KHZ800 ) ;
long lastPixelUpdate = 0 ;
2018-05-06 16:14:11 +00:00
# define PIXELUPDATETIME 20
2018-04-08 16:20:11 +00:00
long lastRoutineUpdate = 0 ;
2018-05-06 16:14:11 +00:00
# define ROUTINEUPDATETIME 20
2018-05-06 19:41:33 +00:00
long lastCheckspawn = 0 ;
2020-12-14 22:30:12 +00:00
# define CHECKSPAWNDELAY 2000 //delay in ms to check random spawn
# define SPAWNCHANCE 40 //1 out of x times wagon will spawn
2018-05-06 19:41:33 +00:00
# define SPAWNCHANCEDOUBLE 5 //change of spawning a two trains simultaneously
2018-07-15 21:04:20 +00:00
long lastCheckspawnEffect = 0 ;
2018-09-05 16:23:48 +00:00
# define CHECKSPAWNDELAY_EFFECT 10000 //delay in ms to check random effect
# define SPAWNCHANCE_EFFECT_SCANNER 1000 //1 out of x times spawn effect
2020-12-13 11:59:38 +00:00
# define SPAWNCHANCE_EFFECT_FLASH 4000 //1 out of x times spawn effect
2020-12-14 22:30:12 +00:00
# define SPAWNCHANCE_EFFECT_STARS 100 //1 out of x times spawn effect
2018-04-08 16:20:11 +00:00
2020-12-14 22:30:12 +00:00
# define BRIGHTNESS_RUN 200 //max brightness
# define BRIGHTNESS_RUN_MIN 20
2018-05-16 18:48:55 +00:00
# define BRIGHTNESS_DEBUG 150
2020-12-14 22:30:12 +00:00
# define LDR_MIN 700
# define LDR_MAX 150
unsigned long last_ldrread = 0 ;
2018-04-08 16:20:11 +00:00
long loopmillis = 0 ;
uint8_t height [ NUMPIXELS ] ;
2018-05-06 16:14:11 +00:00
uint8_t heightraw [ NUMPIXELS ] ; //uninterpolated values
# define MAXHEIGHT 254
2018-04-08 16:20:11 +00:00
std : : vector < Wagon > wagon_arr ;
uint8_t maxid = 0 ;
2018-05-06 19:41:33 +00:00
bool configmode = false ;
2018-05-06 16:14:11 +00:00
int selectedpixel = - 1 ; //-1 = none
2020-12-13 00:12:37 +00:00
uint8_t selectpixelmode = 0 ;
2018-05-06 16:14:11 +00:00
2018-05-06 19:41:33 +00:00
uint8_t wagoncount = 0 ;
2018-07-15 15:08:34 +00:00
Effect * effect = NULL ;
2018-07-10 22:08:14 +00:00
2019-06-04 23:54:20 +00:00
//Persistance effects
# define PERSMODE_BLACK 0
# define PERSMODE_FADEPERCENT 1
# define NUM_PERSMODE 2 //number of available persistancemodes
uint8_t persistancemode = PERSMODE_BLACK ;
long last_changePersistancemode = 0 ;
# define PERSISTANCEMODECHANGE_DELAY 180000
2018-05-06 19:41:33 +00:00
//define config
//#define RESPAWNWAGON
# define MAXWAGONS 5 //maximum number of wagons
2018-05-06 16:14:11 +00:00
2018-04-08 16:20:11 +00:00
void setup ( ) {
Serial . begin ( 115200 ) ;
2020-12-14 22:30:12 +00:00
# ifdef PIN_LDR
pinMode ( PIN_LDR , INPUT ) ;
# endif
2019-04-07 14:07:55 +00:00
EEPROM . begin ( 4096 ) ; //set eeprom size, between 4 and 4096 bytes.
2018-04-10 19:17:45 +00:00
strip . begin ( ) ;
2018-05-16 18:48:55 +00:00
strip . setBrightness ( BRIGHTNESS_RUN ) ; //150
2020-12-14 22:30:12 +00:00
2018-04-10 19:17:45 +00:00
strip . show ( ) ; // Initialize all pixels to 'off'
Serial . println ( " Started " ) ;
2018-05-06 16:14:11 +00:00
resetHeightmap ( ) ;
2018-05-06 19:41:33 +00:00
//fixed heightmap
2019-04-07 14:07:55 +00:00
loadHeightmapRaw ( ) ;
2018-04-10 19:17:45 +00:00
2018-05-06 16:14:11 +00:00
interpolateHeightValues ( ) ;
/*
Serial . println ( ) ;
for ( int i = 0 ; i < NUMPIXELS ; i + + ) {
Serial . print ( i ) ;
Serial . print ( " : " ) ;
Serial . println ( height [ i ] ) ;
} */
//previewHeightmap(2000);
2018-05-06 19:41:33 +00:00
//spawnWagon();
2018-05-19 18:37:06 +00:00
spawnWagon ( ) ;
2018-05-06 16:14:11 +00:00
}
2020-12-12 20:50:20 +00:00
2018-05-06 16:14:11 +00:00
void resetHeightmap ( ) {
for ( int i = 0 ; i < NUMPIXELS ; i + + ) {
heightraw [ i ] = 255 ; //255 means value need to be interpolated
}
heightraw [ 0 ] = 0 ;
heightraw [ NUMPIXELS - 1 ] = 0 ;
}
2018-04-10 19:17:45 +00:00
2018-05-06 19:41:33 +00:00
void printHeightmapRaw ( ) {
Serial . println ( ) ;
for ( int i = 0 ; i < NUMPIXELS ; i + + ) {
if ( heightraw [ i ] ! = 255 ) {
Serial . print ( " heightraw[ " ) ;
Serial . print ( i ) ;
Serial . print ( " ]= " ) ;
Serial . print ( heightraw [ i ] ) ;
Serial . println ( " ; " ) ;
2018-05-16 18:48:55 +00:00
delay ( 10 ) ;
2018-05-06 19:41:33 +00:00
}
}
}
2018-05-06 16:14:11 +00:00
void interpolateHeightValues ( ) {
for ( int i = 0 ; i < NUMPIXELS ; i + + ) { //copy heightraw to height
height [ i ] = heightraw [ i ] ;
}
2018-04-10 19:17:45 +00:00
//interpolate every part with height value 255
for ( int interpolateStartpos = 0 ; interpolateStartpos < NUMPIXELS - 1 ; interpolateStartpos + + ) {
if ( height [ interpolateStartpos ] = = 255 ) { //interpolation part starts
int interpolateEndpos = interpolateStartpos + 1 ;
while ( interpolateEndpos < NUMPIXELS & & height [ interpolateEndpos ] = = 255 ) {
interpolateEndpos + + ;
}
interpolateEndpos - - ;
//interpolateStartpos index of first 255 value
//interpolateEndpos index of last 255 value
uint8_t interpolateStartvalue = height [ interpolateStartpos - 1 ] ;
uint8_t interpolateEndvalue = height [ interpolateEndpos + 1 ] ;
int interpolateLength = interpolateEndpos - interpolateStartpos + 1 ; //one 255 element -> length 1
float interpolateStep = ( ( int ) ( interpolateEndvalue ) - ( int ) ( interpolateStartvalue ) ) * 1.0 / ( interpolateLength + 1 ) ;
Serial . println ( ) ;
Serial . print ( " interpolateStep= " ) ;
Serial . print ( " ( " ) ;
Serial . print ( interpolateEndvalue ) ;
Serial . print ( " - " ) ;
Serial . print ( interpolateStartvalue ) ;
Serial . print ( " )/ " ) ;
Serial . print ( interpolateLength + 1 ) ;
Serial . print ( " = " ) ;
Serial . println ( interpolateStep ) ;
int interpolateStepCounter = 1 ;
Serial . println ( ) ;
Serial . print ( " interpolateStartpos= " ) ;
Serial . println ( interpolateStartpos ) ;
Serial . print ( " interpolateEndpos= " ) ;
Serial . println ( interpolateEndpos ) ;
Serial . print ( " interpolateStartvalue= " ) ;
Serial . println ( interpolateStartvalue ) ;
Serial . print ( " interpolateEndvalue= " ) ;
Serial . println ( interpolateEndvalue ) ;
Serial . print ( " interpolateLength= " ) ;
Serial . println ( interpolateLength ) ;
Serial . print ( " interpolateStep= " ) ;
Serial . println ( interpolateStep , 6 ) ;
for ( int setinti = interpolateStartpos ; setinti < = interpolateEndpos ; setinti + + ) { //for all coherent elements to interpolate
height [ setinti ] = height [ interpolateStartpos - 1 ] + ( int ) ( interpolateStep * interpolateStepCounter ) ;
/*Serial.print(height[interpolateStartpos-1]);
Serial . print ( " +( " ) ;
Serial . print ( interpolateStep ) ;
Serial . print ( " * " ) ;
Serial . print ( interpolateStepCounter ) ;
Serial . print ( " )= " ) ;
Serial . println ( height [ setinti ] ) ; */
interpolateStepCounter + + ;
}
interpolateStartpos = interpolateEndpos ;
}
2018-04-08 16:20:11 +00:00
}
}
2018-04-10 19:17:45 +00:00
void previewHeightmap ( int waittime ) {
2018-04-08 16:20:11 +00:00
for ( int i = 0 ; i < NUMPIXELS ; i + + ) {
//uint32_t c=Wheel(height[i]*255/45);
2018-04-10 19:17:45 +00:00
uint8_t b = height [ i ] * 255.0 / MAXHEIGHT ;
2018-05-06 16:14:11 +00:00
//uint32_t c=strip.Color(255-b,b,0);
uint32_t c = Wheel ( b / 1.2 ) ;
2018-04-10 19:17:45 +00:00
if ( height [ i ] = = 255 ) {
c = strip . Color ( 0 , 0 , 0 ) ;
}
2018-04-08 16:20:11 +00:00
strip . setPixelColor ( i , c ) ;
}
2018-05-06 16:14:11 +00:00
if ( waittime > 0 ) {
strip . show ( ) ;
delay ( waittime ) ;
}
2018-04-08 16:20:11 +00:00
}
2020-12-13 00:12:37 +00:00
void allBlack ( int waittime ) {
for ( int i = 0 ; i < NUMPIXELS ; i + + ) {
uint32_t c = strip . Color ( 0 , 0 , 0 ) ;
strip . setPixelColor ( i , c ) ;
}
if ( waittime > 0 ) {
strip . show ( ) ;
delay ( waittime ) ;
}
}
2020-12-12 20:50:20 +00:00
2018-04-08 16:20:11 +00:00
void spawnWagon ( ) {
2018-04-08 17:47:34 +00:00
//Wagon tmpr = Wagon(maxid++,NUMPIXELS,&strip, height, 35, 6, 0.5,0); //spawn new wagon
2018-05-16 18:48:55 +00:00
// pos, wagonlength, startvel, startacc, trainmass, wagoncolor
2018-05-06 19:41:33 +00:00
//Wagon tmpr = Wagon(maxid++,NUMPIXELS,&strip, height, random(0, 20), random(3,20), random(0.2, 50)/10.0, 0 , random(5,100) , Wheel(random(0,256))); //spawn new wagon
2018-05-24 23:10:06 +00:00
int _randomlength = random ( 3 , 40 ) ; //Zelt: 3-> minimum vel 10, 40 -> minium vel 30
2018-05-16 18:48:55 +00:00
// pos, wagonlength, startvel , startacc, trainmass, wagoncolor
2018-06-10 17:23:11 +00:00
//Wagon tmpr = Wagon(maxid++,NUMPIXELS,&strip, height, random(0, 20), _randomlength, random(map(_randomlength,3,40,1,1), map(_randomlength,3,40, 13,40))/10.0 , 0 , 5 , Wheel((uint8_t)random(0,255))); //spawn new wagon
2018-09-05 16:49:54 +00:00
int side_startpos = 0 ;
int side_multi = 1 ;
2020-12-13 11:59:38 +00:00
/*
2018-09-05 16:49:54 +00:00
if ( random ( 0 , 2 ) = = 0 ) { //spawn from other side
side_startpos = NUMPIXELS + _randomlength ;
side_multi = - 1 ;
}
2020-12-13 11:59:38 +00:00
*/
//Force start from end of strip
side_startpos = NUMPIXELS + _randomlength ;
side_multi = - 1 ;
2018-09-05 16:49:54 +00:00
Wagon tmpr = Wagon ( maxid + + , NUMPIXELS , & strip , height , side_startpos , _randomlength , side_multi * random ( map ( _randomlength , 3 , 20 , 5 , 10 ) , map ( _randomlength , 3 , 20 , 5 , 40 ) ) / 10.0 , 0 , 5.0 , Wheel ( ( uint8_t ) random ( 0 , 255 ) ) ) ; //spawn new wagon
2018-04-08 17:47:34 +00:00
2018-06-10 17:59:01 +00:00
//special spawns
if ( random ( 0 , 50 ) = = 0 ) {
tmpr . setType ( 1 ) ; //make rainbow
tmpr . setLength ( _randomlength * random ( 1 , 3 ) ) ;
}
2018-04-08 16:20:11 +00:00
wagon_arr . push_back ( tmpr ) ;
Serial . println ( " Spawned Wagon " ) ;
}
2018-05-06 16:14:11 +00:00
void spawnWagon ( float pos , float wagonlength , float startvel , float startacc , float mass , uint8_t wheelcolor ) {
//Wagon tmpr = Wagon(maxid++,NUMPIXELS,&strip, height, 35, 6, 0.5,0); //spawn new wagon
// pos, wagonlength, startvel, startacc, wagonmass, wagoncolor
Wagon tmpr = Wagon ( maxid + + , NUMPIXELS , & strip , height , pos , wagonlength , startvel , startacc , mass , Wheel ( wheelcolor ) ) ; //spawn new wagon
wagon_arr . push_back ( tmpr ) ;
Serial . println ( " Spawned Custom Wagon " ) ;
}
2018-04-08 17:47:34 +00:00
2018-04-08 16:20:11 +00:00
void loop ( ) {
loopmillis = millis ( ) ;
2020-12-14 22:30:12 +00:00
# ifdef PIN_LDR
if ( millis ( ) - last_ldrread > 10000 ) {
int _light = analogRead ( PIN_LDR ) ;
uint8_t _brightness = constrain ( map ( _light , LDR_MIN , LDR_MAX , BRIGHTNESS_RUN_MIN , BRIGHTNESS_RUN ) , BRIGHTNESS_RUN_MIN , BRIGHTNESS_RUN ) ;
Serial . print ( " kilian= " ) ; Serial . println ( _light ) ;
Serial . print ( " ergbebinis= " ) ; Serial . println ( _brightness ) ;
strip . setBrightness ( _brightness ) ;
last_ldrread = millis ( ) ;
}
# endif
2018-05-06 16:14:11 +00:00
checkSerial ( ) ;
if ( configmode ) {
loop_configmode ( ) ;
} else {
loop_achterbahn ( ) ;
}
}
2020-12-12 20:50:20 +00:00
2018-05-06 16:14:11 +00:00
void checkSerial ( ) {
static String serialstring_temp = " " ;
String serialstring = " " ;
while ( Serial . available ( ) ) {
if ( Serial . available ( ) > 0 ) {
char c = Serial . read ( ) ;
if ( c ! = ' \n ' ) {
serialstring_temp + = c ;
Serial . print ( c ) ; //echo
} else {
Serial . println ( " " ) ; //new line
serialstring = serialstring_temp ;
serialstring_temp = " " ;
}
}
}
if ( serialstring . length ( ) > 0 ) {
Serial . println ( " String: " + serialstring ) ;
2018-05-06 19:41:33 +00:00
2018-05-06 16:14:11 +00:00
if ( serialstring . equals ( " run " ) ) {
2018-05-16 18:48:55 +00:00
strip . setBrightness ( BRIGHTNESS_RUN ) ;
2018-05-06 16:14:11 +00:00
configmode = false ;
} else if ( serialstring . equals ( " debug " ) ) {
2018-05-16 18:48:55 +00:00
strip . setBrightness ( BRIGHTNESS_DEBUG ) ;
2018-05-06 16:14:11 +00:00
configmode = true ;
2020-12-13 00:12:37 +00:00
selectpixelmode = 0 ;
} else if ( serialstring . equals ( " debug_dark " ) ) {
strip . setBrightness ( BRIGHTNESS_DEBUG ) ;
configmode = true ;
selectpixelmode = 1 ; //show only selected color, everything else off
2018-05-06 19:41:33 +00:00
} else if ( serialstring . equals ( " print " ) ) {
printHeightmapRaw ( ) ;
2019-04-07 14:07:55 +00:00
} else if ( serialstring . equals ( " save " ) ) {
saveHeightmapRaw ( ) ; //save to eeprom
} else if ( serialstring . equals ( " load " ) ) {
loadHeightmapRaw ( ) ; //load from eeprom
2018-05-06 16:14:11 +00:00
} else if ( serialstring . equals ( " remove " ) ) {
removeAllWagons ( ) ;
} else if ( serialstring . equals ( " clear " ) ) {
resetHeightmap ( ) ;
interpolateHeightValues ( ) ;
previewHeightmap ( 0 ) ; //show heightmap
strip . show ( ) ;
} else if ( serialstring . startsWith ( " spawn= " ) ) {
String rest = serialstring . substring ( serialstring . indexOf ( ' = ' ) + 1 ) ; //part after =
int spawnpos = rest . substring ( 0 , rest . indexOf ( ' , ' ) ) . toInt ( ) ; //part to next ,
rest = rest . substring ( rest . indexOf ( ' , ' ) + 1 ) ; //part after ,
int spawnlength = rest . substring ( 0 , rest . indexOf ( ' , ' ) ) . toInt ( ) ; //part to next ,
rest = rest . substring ( rest . indexOf ( ' , ' ) + 1 ) ; //part after ,
int spawnstartvel = rest . substring ( 0 , rest . indexOf ( ' , ' ) ) . toInt ( ) ; //part to next ,
rest = rest . substring ( rest . indexOf ( ' , ' ) + 1 ) ; //part after ,
int spawnstartacc = rest . substring ( 0 , rest . indexOf ( ' , ' ) ) . toInt ( ) ; //part to next ,
rest = rest . substring ( rest . indexOf ( ' , ' ) + 1 ) ; //part after ,
2018-07-10 21:18:48 +00:00
float spawnmass = rest . substring ( 0 , rest . indexOf ( ' , ' ) ) . toInt ( ) / 1000.0 ; //part to next , //mass in gramm
2018-05-06 16:14:11 +00:00
rest = rest . substring ( rest . indexOf ( ' , ' ) + 1 ) ; //part after ,
int spawncolor = rest . substring ( 0 ) . toInt ( ) ; //part to next ,
Serial . print ( " spawning " ) ;
Serial . print ( spawnpos ) ;
Serial . print ( " , " ) ;
Serial . println ( spawnlength ) ;
Serial . print ( " , " ) ;
Serial . println ( spawnstartvel ) ; //startvel will be /10
Serial . print ( " , " ) ;
Serial . println ( spawnstartacc ) ; //startacc will be /10
Serial . print ( " , " ) ;
Serial . println ( spawnmass ) ;
Serial . print ( " , " ) ;
Serial . println ( spawncolor ) ;
spawnWagon ( spawnpos , spawnlength , spawnstartvel / 10.0 , spawnstartacc / 10.0 , spawnmass , spawncolor ) ;
} else if ( serialstring . equals ( " spawn " ) ) {
spawnWagon ( ) ; //random
} else if ( serialstring . startsWith ( " setpx= " ) ) {
String pixelnumberstring = serialstring . substring ( serialstring . indexOf ( ' = ' ) + 1 , serialstring . indexOf ( ' , ' ) ) ; //part between = and ,
String pixelvaluestring = serialstring . substring ( serialstring . indexOf ( ' , ' ) + 1 ) ; //part after ,
int pixelnumber = pixelnumberstring . toInt ( ) ;
int pixelvalue = pixelvaluestring . toInt ( ) ;
Serial . print ( " set pixel " ) ;
Serial . print ( pixelnumber ) ;
Serial . print ( " = " ) ;
Serial . println ( pixelvalue ) ;
if ( pixelnumber > = 0 & & pixelnumber < NUMPIXELS & & pixelvalue > = 0 & & pixelvalue < = 255 ) {
heightraw [ pixelnumber ] = pixelvalue ;
} else {
Serial . println ( " Error: Value out of range! " ) ;
}
interpolateHeightValues ( ) ;
Serial . println ( ) ;
for ( int i = 0 ; i < NUMPIXELS ; i + + ) {
Serial . print ( i ) ;
Serial . print ( " : " ) ;
Serial . print ( height [ i ] ) ;
Serial . print ( " ( " ) ;
Serial . print ( heightraw [ i ] ) ;
Serial . println ( " ) " ) ;
}
previewHeightmap ( 0 ) ; //show heightmap
strip . show ( ) ;
} else if ( serialstring . startsWith ( " px= " ) ) {
String pixelnumberstring = serialstring . substring ( serialstring . indexOf ( ' = ' ) + 1 ) ; //part between = and ,
int pixelnumber = pixelnumberstring . toInt ( ) ;
Serial . print ( " show pixel " ) ;
Serial . print ( pixelnumber ) ;
2020-12-13 00:12:37 +00:00
selectedpixel = pixelnumber ;
/* //ignore max and min. all black with px=-1
2018-05-06 16:14:11 +00:00
if ( pixelnumber < NUMPIXELS ) {
selectedpixel = pixelnumber ;
} else {
Serial . println ( " Error: Value too high! " ) ;
2020-12-13 00:12:37 +00:00
} */
2018-07-15 15:26:07 +00:00
} else if ( serialstring . startsWith ( " fx_ " ) ) {
2018-07-10 22:08:14 +00:00
Serial . println ( " Effect Scanner " ) ;
2018-07-15 15:08:34 +00:00
if ( effect ! = NULL ) {
delete effect ;
}
2018-07-15 15:26:07 +00:00
if ( serialstring . equals ( " fx_scanner " ) ) {
Serial . println ( " Effect Scanner " ) ;
effect = new FX_Scanner ( NUMPIXELS , & strip , height , 255 , - 200 , strip . Color ( 100 , 0 , 0 ) ) ;
} else if ( serialstring . equals ( " fx_flash " ) ) {
Serial . println ( " Effect Flash " ) ;
2018-07-15 21:04:20 +00:00
effect = new FX_Flash ( NUMPIXELS , & strip , height , strip . Color ( 200 , 200 , 200 ) ) ;
2020-12-14 22:30:12 +00:00
} else if ( serialstring . equals ( " fx_stars " ) ) {
Serial . println ( " Effect Stars " ) ;
effect = new FX_Stars ( NUMPIXELS , & strip , height ) ;
2018-07-15 15:26:07 +00:00
}
2018-05-06 16:14:11 +00:00
}
}
}
void loop_configmode ( ) {
if ( lastPixelUpdate + PIXELUPDATETIME < loopmillis ) {
lastPixelUpdate = loopmillis ;
2020-12-13 00:12:37 +00:00
if ( selectpixelmode = = 0 ) {
//show heightmap as color and selected pixel white
previewHeightmap ( 0 ) ;
if ( selectedpixel > = 0 ) {
uint32_t c = strip . Color ( 255 , 255 , 255 ) ;
strip . setPixelColor ( selectedpixel , c ) ;
if ( selectedpixel > = 1 ) {
uint32_t c = strip . Color ( 0 , 0 , 0 ) ;
strip . setPixelColor ( selectedpixel - 1 , c ) ;
}
if ( selectedpixel < NUMPIXELS - 1 ) {
uint32_t c = strip . Color ( 0 , 0 , 0 ) ;
strip . setPixelColor ( selectedpixel + 1 , c ) ;
}
2018-05-06 16:14:11 +00:00
}
2020-12-13 00:12:37 +00:00
} else if ( selectpixelmode = = 1 ) {
//show only selected pixel as white, everything else off
allBlack ( 0 ) ;
if ( selectedpixel > = 0 & & selectedpixel < NUMPIXELS ) {
uint32_t c = strip . Color ( 255 , 255 , 255 ) ;
strip . setPixelColor ( selectedpixel , c ) ;
2018-05-06 16:14:11 +00:00
}
}
strip . show ( ) ;
}
}
2020-12-12 20:50:20 +00:00
2018-05-06 16:14:11 +00:00
void loop_achterbahn ( ) {
2018-04-08 16:20:11 +00:00
//######################### Update LED Output
if ( lastPixelUpdate + PIXELUPDATETIME < loopmillis ) {
lastPixelUpdate = loopmillis ;
for ( int i = 0 ; i < NUMPIXELS ; i + + ) { //all black
2019-06-04 23:54:20 +00:00
switch ( persistancemode ) {
case PERSMODE_FADEPERCENT :
{
uint32_t _pxcolor = strip . getPixelColor ( i ) ; //get current color of that pixel
uint8_t _pxr = _pxcolor > > 16 ;
uint8_t _pxg = _pxcolor > > 8 ;
uint8_t _pxb = _pxcolor ;
uint32_t c = strip . Color ( _pxr * 0.99 , _pxg * 0.99 , _pxb * 0.99 ) ;
strip . setPixelColor ( i , c ) ;
break ;
}
case PERSMODE_BLACK : default :
{
uint32_t c = strip . Color ( 0 , 0 , 0 ) ;
strip . setPixelColor ( i , c ) ;
break ;
}
}
}
//possible persistancemode change
if ( millis ( ) > last_changePersistancemode + PERSISTANCEMODECHANGE_DELAY ) {
if ( random ( 0 , 10 ) ! = 0 ) {
persistancemode = PERSMODE_BLACK ;
} else {
persistancemode = random ( 1 , NUM_PERSMODE ) ;
}
last_changePersistancemode = millis ( ) ;
2018-04-08 16:20:11 +00:00
}
2018-07-10 22:08:14 +00:00
//Wagons
2018-04-08 16:20:11 +00:00
for ( std : : vector < Wagon > : : iterator it = wagon_arr . begin ( ) ; it ! = wagon_arr . end ( ) ; + + it ) //all wagons
{
Wagon & w = * it ;
w . updateGraphics ( ) ;
}
2018-07-10 22:08:14 +00:00
//Effects
2018-07-15 15:08:34 +00:00
if ( effect ! = NULL ) {
if ( effect - > active ( ) ) {
effect - > updateGraphics ( ) ;
}
2018-07-10 22:08:14 +00:00
}
2018-04-08 16:20:11 +00:00
strip . show ( ) ;
}
if ( lastRoutineUpdate + ROUTINEUPDATETIME < loopmillis - ROUTINEUPDATETIME ) {
2018-05-06 16:14:11 +00:00
Serial . println ( " Behind! " ) ;
2018-04-08 16:20:11 +00:00
}
//######################### Update Physics
if ( lastRoutineUpdate + ROUTINEUPDATETIME < loopmillis ) {
lastRoutineUpdate = loopmillis ;
2018-05-06 19:41:33 +00:00
wagoncount = 0 ;
2018-04-08 16:20:11 +00:00
for ( std : : vector < Wagon > : : iterator it = wagon_arr . begin ( ) ; it ! = wagon_arr . end ( ) ; + + it ) //all wagons
{
2018-05-06 19:41:33 +00:00
2018-04-08 16:20:11 +00:00
Wagon & w = * it ;
w . updatePhysics ( ROUTINEUPDATETIME ) ;
if ( ! w . alive ( ) )
{
it = wagon_arr . erase ( it ) ; // After erasing, it is now pointing the next element.
- - it ;
2018-09-05 16:49:54 +00:00
Serial . println ( " Killed train " ) ;
2018-05-06 19:41:33 +00:00
# ifdef RESPAWNWAGON
spawnWagon ( ) ; //spawn new one
# endif
} else { //wagon is alive
wagoncount + + ;
}
}
2018-07-10 22:08:14 +00:00
//Effects
2018-07-15 15:08:34 +00:00
if ( effect ! = NULL ) {
if ( effect - > active ( ) ) {
effect - > updateRoutine ( ROUTINEUPDATETIME ) ;
} else { //effect not active anymore
delete effect ;
effect = NULL ;
}
2018-07-10 22:08:14 +00:00
}
2018-05-06 19:41:33 +00:00
}
//Check spawning
if ( lastCheckspawn + CHECKSPAWNDELAY < loopmillis ) {
lastCheckspawn = loopmillis ;
Serial . print ( " Checking Spawning, wagons " ) ;
Serial . println ( wagoncount ) ;
if ( random ( 0 , SPAWNCHANCE ) = = 0 & & wagoncount < MAXWAGONS ) { //by chance, exclusive SPAWNCHANCE
spawnWagon ( ) ;
if ( random ( 0 , SPAWNCHANCEDOUBLE ) = = 0 ) {
spawnWagon ( ) ;
2018-04-08 16:20:11 +00:00
}
2018-07-15 21:04:20 +00:00
}
}
//Check Effect Spawning
if ( effect = = NULL & & lastCheckspawnEffect + CHECKSPAWNDELAY_EFFECT < loopmillis ) {
lastCheckspawnEffect = loopmillis ;
if ( random ( 0 , SPAWNCHANCE_EFFECT_SCANNER ) = = 0 ) {
effect = new FX_Scanner ( NUMPIXELS , & strip , height , 255 , - 200 , strip . Color ( 100 , 0 , 0 ) ) ;
} else if ( random ( 0 , SPAWNCHANCE_EFFECT_FLASH ) = = 0 ) {
effect = new FX_Flash ( NUMPIXELS , & strip , height , strip . Color ( 200 , 200 , 200 ) ) ;
2020-12-14 22:30:12 +00:00
} /*else if (random(0,SPAWNCHANCE_EFFECT_STARS)==0){
effect = new FX_Stars ( NUMPIXELS , & strip , height ) ;
} */
2018-04-08 16:20:11 +00:00
}
}
2018-05-06 16:14:11 +00:00
void removeAllWagons ( ) {
for ( std : : vector < Wagon > : : iterator it = wagon_arr . begin ( ) ; it ! = wagon_arr . end ( ) ; + + it ) //all wagons
{
Wagon & w = * it ;
w . updatePhysics ( ROUTINEUPDATETIME ) ;
it = wagon_arr . erase ( it ) ; // After erasing, it is now pointing the next element.
- - it ;
}
}
2018-04-08 16:20:11 +00:00
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel ( byte WheelPos ) {
WheelPos = 255 - WheelPos ;
if ( WheelPos < 85 ) {
return strip . Color ( 255 - WheelPos * 3 , 0 , WheelPos * 3 ) ;
}
if ( WheelPos < 170 ) {
WheelPos - = 85 ;
return strip . Color ( 0 , WheelPos * 3 , 255 - WheelPos * 3 ) ;
}
WheelPos - = 170 ;
return strip . Color ( WheelPos * 3 , 255 - WheelPos * 3 , 0 ) ;
}
2019-04-07 14:07:55 +00:00
2020-12-12 20:50:20 +00:00
2019-04-07 14:07:55 +00:00
void loadHeightmapRaw ( ) {
int c_eepromaddress = EEPROMSTARTADDRESS_HEIGHTMAP ;
uint8_t lastvalue = 0 ;
for ( int i = 0 ; i < NUMPIXELS ; i + + ) {
lastvalue = EEPROM . read ( c_eepromaddress ) ;
heightraw [ i ] = lastvalue ;
c_eepromaddress + + ;
}
interpolateHeightValues ( ) ;
}
void saveHeightmapRaw ( ) {
int c_eepromaddress = EEPROMSTARTADDRESS_HEIGHTMAP ;
for ( int i = 0 ; i < NUMPIXELS ; i + + ) {
EEPROM . write ( c_eepromaddress , heightraw [ i ] ) ; //address, value
c_eepromaddress + + ;
}
EEPROM . commit ( ) ; //write changes to eeprom. EEPROM.end() will also commit and release the ram copy of eeprom contents
}
2020-12-12 20:50:20 +00:00