Skip to content
Snippets Groups Projects
Select Git revision
  • 254eb3bbc4c7b519c489f36069e2c91a0fd8a3f3
  • master default protected
  • patch-1
  • PRETASKSCHED
4 results

FanLoop.ino

Blame
  • Forked from SistemiEmbedded / 2019-2020
    Source project has a limited visibility.
    FanLoop.ino 4.33 KiB
    //#define SENSORE 4  // sulla board Arduino UNO solo 2,3
    #define SENSORE 2
    #define ATTUATORE 3
    
    #define RUMORE 50  // soglia minima interrupt
    
    // TODO 'volatile' (vedere se si può creare un esperimento ad-hoc, non banale)
    
    volatile long timestamp=0;
    volatile long durata=0;
    volatile long durataMedia=0; // media mobile (molto corta, a 2 elementi)
    volatile boolean updated=false;
    
    long durataDesiderata=100; // inverso velocità
    float duty=.7; // %
    int periodpwm=2000; //millis
    
    //boolean fai=true; // per il "monitor"
    
    
    // TaskScheduler
    #include <TaskScheduler.h>
    Scheduler runner;
    
    ///////////////////////////////////////////////////////
    // I soluzione
    void onLED(){
     digitalWrite(LED_BUILTIN,HIGH);
    }
    
    void offLED(){
     digitalWrite(LED_BUILTIN,LOW);
    }
    
    Task accendiLEDTask(TASK_SECOND, TASK_FOREVER, onLED);
    Task spegniLEDTask(TASK_SECOND, TASK_FOREVER, offLED);
    ///////////////////////////////////////////////////////
    
    ///////////////////////////////////////////////////////
    // II soluzione
    boolean acceso=false;
    void blink(){
    	Serial.println("blink");
    	Serial.println(acceso);
    	if(acceso) digitalWrite(LED_BUILTIN,LOW);
    	else digitalWrite(LED_BUILTIN,HIGH);
    	acceso=!acceso;
    	
    	//delay(20000); // BLOCCA TASK SCHEDULER!!!
    }
    
    Task blinkTask(2*TASK_SECOND, TASK_FOREVER, blink);
    ///////////////////////////////////////////////////////
    
    boolean dutyOn=false;
    Task pwmDeiPoveryTask(periodpwm*(1-duty), TASK_FOREVER, pwmDeiPovery);
    void pwmDeiPovery(){
    //Task pwmDeiPoveryTask(periodpwm*(1-duty), TASK_FOREVER, [](){
    	Serial.println("pwm");
    	Serial.println(dutyOn);
    
    	noInterrupts(); // non compila in fn anonima
        if(dutyOn){
         digitalWrite(ATTUATORE,HIGH);
         pwmDeiPoveryTask.setInterval(periodpwm*duty);
        }
        else{
         digitalWrite(ATTUATORE,LOW);
         pwmDeiPoveryTask.setInterval(periodpwm*(1-duty));
        }
    	interrupts(); // non compila in fn anonima
        
        //delay(periodpwm*(duty));
        //delay(periodpwm*(1.0-duty));
    	 dutyOn=!dutyOn;
    	 
    	 
    	 duty+=(durataMedia-durataDesiderata)*.001;
    	 if(duty>=1) duty=1.0;
    //});
    }
    
    
    
    
    
    
    void setup() {
        Serial.begin(115200);
    
        pinMode(SENSORE,INPUT_PULLUP);
        pinMode(ATTUATORE,OUTPUT);
        pinMode(LED_BUILTIN,OUTPUT);
    
        // CONFIGURAZIONE
        attachInterrupt(
            digitalPinToInterrupt(SENSORE),
            lap,
            RISING);
            
            
        // Tasks
        runner.init();
        
        runner.addTask(blinkTask); // qui usare il task non la callback!
        blinkTask.enable();
    
        runner.addTask(pwmDeiPoveryTask); // qui usare il task non la callback!
        pwmDeiPoveryTask.enable();
    }
    
    void loop() {
    
        runner.execute(); // TaskScheduler
    
        //boolean scattato=digitalRead(SENSORE); // non serve più
        if(updated) {
            //Serial.print(timestamp);
            //Serial.print(F("durata:"));
            //Serial.print(durata);
            Serial.print(F("media:"));
            Serial.print(durataMedia);
            Serial.print(F(",desiderata:"));
            Serial.print(durataDesiderata);
            Serial.print(F(",duty:"));
            Serial.println(duty*100);
            //Serial.print(",");
            //Serial.println(scattato);
            updated=false;
        }
    
        // a questo punto posso permettermi tranquillamente di "dormire" anche a lungo... o no?
        /*  TRASFORMARE IN TASK
        digitalWrite(ATTUATORE,HIGH);
        delay(periodpwm*(duty));
        digitalWrite(ATTUATORE,LOW);
        delay(periodpwm*(1.0-duty));
        */
    
        /* versione "grande"
        	LOW  800
        	HIGH 250 non meno, se no non fa nemmeno in tempo a partire
        	minima durata circa 20ms, max circa 60
    
           versione "piccola", ad esempio
            LOW  500
            HIGH 500
        */
    
    }
    
    void lap() {
        //noInterrupts(); // non si può invocare da dentro, non ha effetto, va usata fuori per marcare sezioni critiche, qui dentro parte già a interrupt disabilitati
    
        /* versione "monitor" (dei poveri)
        if (fai) {
        	fai=false;
        	durata=millis()-timestamp;
        	timestamp=millis();
        	//scattato=true;
        	fai=true;
        }
        */
    
        //Serial.println("int!"); //da non fare...
    
        long m=millis();
        if((m-timestamp)>RUMORE) { // per eliminare gli interrupt spuri
            durata=m-timestamp;
            durataMedia=(durataMedia+durata)/2;
            timestamp=m;
            updated=true;
        }
    
        //interrupts(); // questa invece si può invocare (e in automatico vengono cmq riabilitati all'uscita), potrebbe avere senso riabilitarli anche prima di uscire se si deve solo fare qualcosa di non critico
    }