#include #include // nombre de LEDs #define NUM_LEDS 144 // pin sur lequel est connecté le fil data #define DATA_PIN 3 // intensité des LEDs #define BRIGHTNESS 20 #define MAX_RAND 1000 // densités initiales, > 1 pour l'initialisation double rhom = 1.1 ; double rhop = 1.1 ; // probabilité pour la particule centrale (rouge) de sauter à droite double pr = 0.5 ; // pin pour la densité à gauche (potentiomètre gauche) const int PinRhoL = A0; int potPinRhoL ; // pin pour la densité à droite (potentiomètre droit) const int PinRhoR = A4; int potPinRhoR ; // pin pour le biais = proba d'aller à droite (potentiomètre central) const int PinBias = A2; int potPinBias ; // tableau des couleurs de chaque LED CRGB leds[NUM_LEDS]; // occupation numbers of each site // the tracer does not occupy a site int occup[NUM_LEDS]; int pos_tracer = NUM_LEDS/2; // nb of particles int npart = 0 ; int pospart[NUM_LEDS] ; // generate random numbers with exponential law // this uses the cumulative double RandExp(double lambda){ double t = random(MAX_RAND)/(MAX_RAND+1.); return -log(1.-t)/lambda; } double Unif(){ return random(MAX_RAND)/(MAX_RAND+1.); } void initAll() { npart = 0 ; pos_tracer = NUM_LEDS/2; // initialise the system with density rhom on the left for(int i=0; i(leds, NUM_LEDS); // limit power usage FastLED.setMaxPowerInVoltsAndMilliamps(5,1000); // set brightness FastLED.setBrightness(BRIGHTNESS); // initialise random number generator with the noise of pin 0 randomSeed(analogRead(0)); // initAll() ; } void loop() { potPinRhoL = analogRead(PinRhoL) ; double RhoL = map(potPinRhoL, 0, 1023, 0, 10)/10. ; potPinRhoR = analogRead(PinRhoR) ; double RhoR = map(potPinRhoR, 0, 1023, 0, 10)/10. ; potPinBias = analogRead(PinBias) ; double Bias = map(potPinBias, 0, 1023, 0, 5)/10. ; pr = 0.5 + Bias ; if( abs(RhoL - rhom) > 0.01 || abs(RhoR - rhop) > 0.01 ){ rhom = RhoL ; rhop = RhoR ; initAll() ; } // pick the time to wait, in seconds // for the test, it is deterministic double dt = RandExp(npart/0.1) ; // convert to milliseconds int dT = (int) (1000*dt) ; delay(dT) ; // pick the particle to affect int part = random(npart); int pos = pospart[part] ; int new_pos ; // tracer or not ? if(pos == pos_tracer) { // compute the new position // initially, go to the left new_pos = (pos_tracer - 1 + NUM_LEDS) % NUM_LEDS ; // unless go to the right if(Unif() < pr){ new_pos = (pos_tracer + 1) % NUM_LEDS ; } // check if new site is empty if(occup[new_pos] == 0) { leds[pos_tracer] = CRGB::Black; leds[new_pos] = CHSV(0, 255, 127); pos_tracer = new_pos ; pospart[part] = new_pos ; } } else { // new site to move, with periodic boundaries new_pos = (pos + (2*random(2) - 1) + NUM_LEDS) % NUM_LEDS ; // check if new site is empty if(occup[new_pos] == 0 && pos_tracer != new_pos) { leds[pos] = CRGB::Black; leds[new_pos] = CHSV(117, 255, 127); occup[pos] = 0 ; occup[new_pos] = 1 ; pospart[part] = new_pos ; } } // light up the series of LEDs FastLED.show(); }