Oscillazioni funzione map()

Salve, si tale approccio effettivamente non è molto efficiente perché limita moltissimo il tempo di ogni ciclo del mio controllore, ma in ogni caso non è una caratteristica fondamentale che deve soddisfare il mio sistema.

Comunque venendo al dunque, in questi giorni ho cercato, come suggerito da te @cotestatnt, di “accelerare” le letture e di non farle diventare bloccanti tramite l’uso di millis().

La soluzione a cui sono venuto a capo è la seguente, infatti ora la funzione getTEMP() è governata da una media mobile, che sequenzialmente:

  • fa la differenza del valore più vecchio dalla somma dei valori del buffer;
  • legge un nuovo valore;
  • lo aggiunge al buffer secondo la posizione definita dall’indice;
  • fa una somma il valore rilevato;
  • incrementa l’indice;
  • divide la somma per la dimensione della “finestra” per ottenere il valore filtrato;

Per correttezza, cito la fonte di tale codice.

Quello che ho fatto è stato adattare i vari parametri per rendere compatibile la media con il mio codice senza per il momento modificare molto la sintassi, una volta che avrò compreso meglio l’argomento (e risolto i problemi) potrò pensare di rendere più efficiente questa funzione.

Detto ciò ho fatto la medesima cosa per quanto riguarda a funzione getVCC() per eliminare l’altro tempo morto del mio codice.
Fatto tutto ciò, non riesco a capire il problema per cui non ottengo output nel monitor seriale e il sistema non cambia il Duty cycle rimanendo constante al minimo anche quando la temperatura cresce.
Ed è stato qusto il problema che ho cercato di risolvere in questi giorni.

Come potrei risolvere tale problema?
Mi sembra di aver svolto quasi tutto in maniera corretta, se provo ad eseguire il codice della media mobile separatamente questo funziona senza problemi filtrando i valori correttamente.

Ringrazio per l’aiuto e per le risposte fornite in anticipo.

Saluti


#include <SoftwareSerial.h>

//DEBUG ONLY
SoftwareSerial SWSERIAL(8, 0);  // RX, TX

const byte tempC_PIN = A2;
const byte vcc_PIN  = A3;
const byte pwmCTL_PIN = 1;
const byte pgs_PIN    = 2;


float tempC;
float tempC_sum;
float vcc;
float vcc_sum;

byte pwm_val;

boolean ST_temp;
boolean ST_vcc;



const byte WINDOW_SIZE = 20;

float buffer_tempC [WINDOW_SIZE];
byte index_tempC = 0;
float read_tempC = 0;

float buffer_vcc [WINDOW_SIZE];
byte index_vcc = 0;
float read_vcc = 0;


//CONSTANTS
const byte T_MIN    = 35;
const byte T_MAX    = 45;

const byte PWM_MIN  = 114;
const byte PWM_MAX  = 255;
const byte V_LOW    = 11;

const byte HIST    = 1;


//TIME INTERVAL CONSTANTS
//TEMPC TIME INTERVAL
unsigned long MILLISPREV1 = 0;
unsigned long INTERVAL1 = 100; 

//VCC TIME INTERVAL
unsigned long MILLISPREV2 = 0;
unsigned long INTERVAL2 = 100; 


//---------------------------------------
// --MAIN SETUP--
//---------------------------------------

void setup() {
  
  //PWM freq. 
  TCCR1 = (TCCR1 & (0b11110000 | 0b0001));

  pinMode(pwmCTL_PIN,OUTPUT);
  pinMode(pgs_PIN,OUTPUT);

  //SERIAL BEGIN (DEBUG ONLY)
  SWSERIAL.begin(4800);
}


//---------------------------------------
// --MAIN LOOP--
//---------------------------------------

void loop() {
  
  //TEMPERATURE SENS.
  getTEMP();

  //FAN PWM / SPEED SET
  setPWM();

  //VCC SENS.
  getVCC();

  //POWER GOOD SIGNAL SET (P.G.S)
  setPGS();

  //ALARM SET
  setALM();

  //DEBUG
  DATAMONITOR();

}


//---------------------------------------
//FUNCTIONS DEFINITION
//---------------------------------------

//TEMPERATURE SENS.
void getTEMP() {
  
  if ((millis() - MILLISPREV1) > INTERVAL1){
    
    tempC_sum = tempC_sum - buffer_tempC[index_tempC];
    read_tempC = ((analogRead(tempC_PIN)/1023.00) * 498.10);
    buffer_tempC[index_tempC] = read_tempC;
    tempC_sum = tempC_sum + read_tempC;
    index_tempC = (index_tempC + 1) % WINDOW_SIZE;

    tempC = tempC_sum / WINDOW_SIZE;
	
	MILLISPREV1 = millis();
  }
}


//FAN PWM / SET SPEED
void setPWM() {

  //AVVIO CON VENTOLA A VELOCITA' MIN. 
  if((tempC > 0) && (tempC <= T_MIN)){  
    pwm_val = PWM_MIN;                                                   
  }

  //VENTOLA MODULATA
  if((tempC >= T_MIN) && (tempC <= T_MAX)){   
		pwm_val = map(tempC, T_MIN, T_MAX, PWM_MIN, PWM_MAX);
    pwm_val = constrain(pwm_val, 0, 255);
	}



  // TEMP ALARM
  //nessuna anomalia
  if(tempC < T_MAX){ 
    ST_temp = false;
  }

  // TEMP ALARM
  //allarme temperatura
  if((tempC > T_MAX) && (tempC > T_MAX + HIST)){ 
    pwm_val = 255; 
    ST_temp = true;
	}

  analogWrite(pwmCTL_PIN,pwm_val);
}


//VCC SENS.
void getVCC() {
  //MEDIA MOBILE
  
  if ((millis() - MILLISPREV2) > INTERVAL2){
    
    vcc_sum = vcc_sum - buffer_vcc[index_vcc];
    read_vcc = (((analogRead(vcc_PIN)/1023.00) * 4.98) * 13.70);
    buffer_vcc[index_vcc] = read_vcc;
    vcc_sum = vcc_sum + read_vcc;
    index_vcc = (index_vcc + 1) % WINDOW_SIZE;

    vcc = vcc_sum / WINDOW_SIZE;
	
	MILLISPREV2 = millis();
  }
}


//POWER GOOD SIGNAL SET (P.G.S)
void setPGS(){
  
  // STATO NORMALE , nessuna anomalia
  if(vcc >= V_LOW){ 
    ST_vcc = false;
    digitalWrite(pgs_PIN,HIGH);
  }

  //ALLARME TENSIONE BASSA
  if((vcc <= V_LOW) && (vcc < V_LOW - HIST)){  
    ST_vcc = true;
    digitalWrite(pgs_PIN,LOW);
  }
}


//ALARM SET
void setALM(){

  //STATO DI ALLARME
  if ((ST_vcc == true) || (ST_temp == true)){
    SWSERIAL.println("ALLARME TEMP.! / ALLARME TENSIONE BASSA!");   //DEBUG
  }

  //STATO NORMALE , nessuna allarme
  if ((ST_vcc == false) && (ST_temp == false)){
    //
	
  }
}


//DATA MONITOR, SERIAL DEBUG 
void DATAMONITOR(){
	
    //plot 
    SWSERIAL.print(tempC);
    SWSERIAL.print(";");
    SWSERIAL.println(pwm_val);
}