Evitare if concatenati

Con riferimento al precedente post ( ritardo tra 1 e due microsec) mi trovo a dover fare una serie di if che vado a descrivere :

int F ; //

se F Va da 0 a 125 chiama delay100();
se F Va da 126 a 225 chiama delay200();
se F Va da 226 a 325 chiama delay300();
se F Va da 326 a 425 chiama delay400();
ecc ecc omissis....
se F Va da 9500 a 10500 chiama delay10000();

c'è un modo più veloce che non fare tanti if a cascata?

grazie

No

Ma se li fai a rovescio esce più corto e meglio leggibile

Mi correggo

Naturalmente c'è un modo per evitare la catena di if

Mettere le soglie in un array e ciclarlo

Oppure potresti cercare una relazione tra soglie e ritardo e se la trovi puoi uasrla per calcolare direttamente il ritardo

Al limite puoi usare lo switch case con gli intervalli, ammesso che possa essere più conveniente

case 0 ... 250

Occhio che intervalli nel case è solo una estensione di Gnu C
"Using range in switch case in C/C++ - GeeksforGeeks"

Come detto anche da Standardoil, secondo me c'e' una formula:

delaytime = int( (F+74)/100 )  * 100;
delay(delaytime);

cioè
0..125 + 79 al max a 199, parte intera divisione 100 = 1
126...225 + 79 al max a 299, parte intera divisione 100 = 2 etc.

vediamo se riesco a spiegarmi
perché poi sarò occupato probabilmente, quindi vediamo di farlo adesso

ammesso così:

0-125 ->100
126-225 ->200
226-325 ->300
e via così..

Lo OP i fare:

int calcolaattesa(int F){
   if (F > 9500) return 10000;
   if (F > ....
   ...
   if (F > 325) return 400;
   if (F > 225) return 300;
   if (F > 125) return 200;
   return 100;
   }

come vedi è più snello e corto e semplice da leggere che una catena di if..elseif con doppia condizione: > && <

oppure puoi costruire un array di soglie e valori

int soglie[]={9500,...,325,225,125,0};
int valori[]={10000,...,400,300,200,100};
// con la sua dimensione
#define dimensione sizeof soglie / sizeof sogle[0]
//per poi ciclarlo
for(int i=0; i< dimensione, i++){
   if (F >= soglie[i]) return valori[i];
   }
// che con poche righe te la cavi, comodo per tante differenti soglie

oppure, da ultimo, posto che tutti gli if siano come i primi 4
puoi usare una relazione matematica semplice

delay(int( (F-25) ) / 100 * 100 + 100);

dove ho usato un casting esplicito perchè non so di che tipo sia F

a proposito, solitamente le maiscole sono usate per le costanti

@nid69ita , @Standardoil : forse ad entrambi è sfuggito il riferimento al thread precedente, l'OP non vuole richiamare la funzione delay() con un parametro variabile, ma le varie funzioni delay100(), delay(200) etc che ha creato con asm(nop).

Ciao, Ale.

Ah...

Ok

Nessun problema

L'esempio 1 va bene lo stesso
Invece di un return si mette chiamata alla funzione e return

L'esempio 2 ancora meglio
Array di puntatore a funzione void con argomento void
Si chiama la funzione puntata dell'elemento trovato

L'esempio 3 è forse quello che richiede maggiori modifiche
Serve di usare il 'risultato del calcolo' come indice dell'array di puntatore a funzione, creato apposta

Forse però, considerando che poi i tempi sono critici, contano i microsecondi...

Sarebbe da considerare di spostare il "lavoro di selezione" fuori dal ciclo ed impostare un puntatore valido una volta per tutte

Con tutti quegli if ci vorrebbero anche gli else...

Rispondo alla risposta successiva di Standardoil:
Certo, perché ci sono i return!

No

Mi sembrava di averlo mostrato...

Grazie a tutti,
ho fatto un pezzo di lavoro con un loop di prova che mi chiama le rampe più veloci.

Poi per le rampe più lente ho fatto un paio di funzioni con parametro, e va abbastanza bene.
Ora però sono nei guai, perchè , avendo usato i puntatori a funzioni (non è farina del mio sacco) per chiamare ripetutamente le rampe, non so come aggiungere il parametro a queste funzioni.
In pratica devo puntare
FunctionPointed = Rampa10_1000ms(200); ....dove 200 è il parametro, ma nonlo so proprio fare.
Grazie

//prototipi
void Rampa75usec(void);
void Rampa100usec(void);
void Rampa150usec(void);
void Rampa200usec(void);
void Rampa250usec(void);
void Rampa300usec(void);
void Rampa400usec(void);
void Rampa500usec(void);
void Rampa600usec(void);
void Rampa700usec(void);
void Rampa800usec(void);
void Rampa900usec(void);
void Rampa1msec(void);
void Rampa2msec(void);
void Rampa3msec(void);
void Rampa4msec(void);
void Rampa5msec(void);
void Rampa8msec(void);
void Rampa10_1000ms(int RampaMilliS); 
void Rampa1000_10000ms(int RampaMilliS); 

int cicli;

typedef void (*GeneralFunction) (void);  //puntatore alla funzione


GeneralFunction FunctionPointed = NULL;


//-------------------------------
void setup() {
  //Serial.begin(38400);
  //Serial.begin(115200);
  //while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  //}
  FunctionPointed = Rampa75usec;
  DDRD=B11111111;


}

//-------------------------------

void loop() {


  //testa le rampe da 100usec a 1msec
  FunctionPointed = Rampa100usec;
  for (cicli = 1; cicli<10000; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa150usec;
  for (cicli = 1; cicli<7500; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa200usec;
  for (cicli = 1; cicli<5000; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa250usec;
  for (cicli = 1; cicli<4000; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa300usec;
  for (cicli = 1; cicli<3300; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa400usec;
  for (cicli = 1; cicli<2500; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa500usec;
  for (cicli = 1; cicli<2000; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa600usec;
  for (cicli = 1; cicli<1600; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa700usec;
  for (cicli = 1; cicli<1400; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa800usec;
  for (cicli = 1; cicli<1200; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa900usec;
  for (cicli = 1; cicli<1100; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa1msec;
  for (cicli = 1; cicli<1000; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa2msec;
  for (cicli = 1; cicli<500; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa3msec;
  for (cicli = 1; cicli<333; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa4msec;
  for (cicli = 1; cicli<250; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa5msec;
  for (cicli = 1; cicli<200; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa8msec;
  for (cicli = 1; cicli<125; cicli++){
    (FunctionPointed)(); 
  }


  //qui mi da errore
  FunctionPointed = Rampa10_1000ms(200);
  for (cicli = 1; cicli<50; cicli++){
    (FunctionPointed)(); 
  }
  



  

}

//***********************************************
//***********************************************
//***********************************************



//***********************************************
//***********************************************
//***********************************************


void Rampa75usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;   
  }  
}


void Rampa100usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    asm("nop");   
    asm("nop");      
  }
}


void Rampa150usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop"); 
    asm("nop");   
  }
}

void Rampa200usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   

    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   
  }  
}

void Rampa250usec(void){
  /*
  for(int y=255;y>-1;y--){
    PORTD=y;
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   

    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   

    asm("nop");   
    asm("nop");     
    asm("nop");   
    

  }
  */
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(2);
  }
  
}

void Rampa300usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   

    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   

    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");
       
    asm("nop");   
    asm("nop");   
  

  }
}
//-------------------------------------------------
void Rampa400usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(2);
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   

    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");
       
    asm("nop");   
    asm("nop");   
  }
}




void Rampa500usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(3);
  }
}

void Rampa600usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(3);
    asm("nop");   

    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");
       
  }
}


void Rampa700usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(3);
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");
       
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");

    asm("nop");
       
  }
}


void Rampa800usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(4);
    asm("nop");         
  }
}

void Rampa900usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(4);
    asm("nop");         
    asm("nop");         
    asm("nop");         
    asm("nop");         
    asm("nop");         
    asm("nop");         
  }
}


//-------------------------------------------------
void Rampa1msec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(5);
  }
}


void Rampa2msec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(9);
  }
}

void Rampa3msec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(13);
  }
}

void Rampa4msec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(17);
  }
}

void Rampa5msec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(21);
  }
}

void Rampa8msec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(34);
  }
}


//-------------------------------------------------
// rampa con durata da 10ms a 1000 msec 
//bisogna dividere il parametro per circa 1,3

void Rampa10_1000ms(int RampaMilliS){
  float float2;
  int int2;
  float2 = RampaMilliS * 10;
  float2 = float2 / 13;
  
  int2 = float2;
  int2 = int2 * 5;
  
  for(int y=255;y>-1;y--){
      PORTD=y;
      delayMicroseconds(int2);
  }    
}

//-----------------------------------

void xxRampa1000_10000ms(int RampaMilliS){ 
  for(int y=255;y>-1;y--){
      PORTD=y;
      delay(RampaMilliS * 4);
  }    
}


void Rampa1000_10000ms(int RampaMilliS){ 
  int int3;
  int3 = RampaMilliS * 4; 
  for(int y=255;y>-1;y--){
      PORTD=y;
      delayMicroseconds(int3);
  }    
}





Bravo

Però non puoi usare due differenti "tipi" di funzione

Devi usare sempre lo stesso metodo

Devi usare funzioni void foo (void)

qualche foto...




in alternativa potresti usare due differenti dichiarazioni di tipo puntatore a due differenti tipi di funzione

typedef void (*GeneralFunction) (void);  //puntatore alla funzione argomento void
typedef void (*IntegerFunction) (int);  //puntatore alla funzione argomento int
GeneralFunction FunctionPointed = NULL;
IntegerFunction IntFunPointed = NULL;

e chiamarla con

  IntFunPointed = Rampa10_1000ms;
  for (cicli = 1; cicli<50; cicli++){
    (InfFunPointed)(200); 
  }

non so mica se funziona
non lo ho nemmeno compilato

ma provare non costa nulla

e adesso chiudo, perché vorrei andare in ferie

ho provato, ma dovunque metta il parametro 200 mi da errore
l'unica ch compila è

  IntFunPointed = Rampa10_1000ms;
  for (cicli = 1; cicli<50; cicli++){
    (FunctionPointed)(); 
  }

ma manca il parametro,
:unamused:

Risolto, do priorità a quelle più veloci, e per quelle lente c'è tutto il tempo di fare calcoli ulteriori.

La funzione principale è ArrotondaTempoRampa(); che sistema il puntatore alla funzione che verrà chiamata velocemente fino ad un aggiornamento (ancora da implementare.

Grazie a tutti.

/*
 * Arduino NANO + DAC AD1280 connesso in parallelo sul portD generano una rampa raziometrica
 * Il parametro "unsigned long TempoRampa" decide quanto dura la rampa, da 100usec a 3 sec
 * - 100 = 100usec
 * - 1.000 = 1msec
 * - 1.000.000 = 1 sec
 * - 3.000.000 = 3 sec
 * - se vale 0 il DAC va subito a fondo scala
 * - per altri valori il TempoRampa è espresso in microsecondi
 * ----------------------------------------------------------
 * 
 */

unsigned long TempoRampa = 0;


//prototipi
void ArrotondaTempoRampa(void);
void RampaLenta(void); //rampa se t > 9 msec
void DacFullScale(void); // dac a fondo scala
void DacZero(void); //azzera la tensione
void Rampa75usec(void);
void Rampa100usec(void);
void Rampa150usec(void);
void Rampa200usec(void);
void Rampa250usec(void);
void Rampa300usec(void);
void Rampa400usec(void);
void Rampa500usec(void);
void Rampa600usec(void);
void Rampa700usec(void);
void Rampa800usec(void);
void Rampa900usec(void);
void Rampa1msec(void);
void Rampa2msec(void);
void Rampa3msec(void);
void Rampa4msec(void);
void Rampa5msec(void);
void Rampa8msec(void);
void Rampa10_1000ms(int RampaMilliS); 
void Rampa1000_10000ms(int RampaMilliS); 

int cicli;

typedef void (*GeneralFunction) (void);  //puntatore alla funzione


GeneralFunction FunctionPointed = NULL;


//-------------------------------
void setup() {
  //Serial.begin(38400);
  //Serial.begin(115200);
  //while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  //}
  FunctionPointed = Rampa75usec;
  DDRD=B11111111;


}

//-------------------------------
//-------------------------------
void loop(){
  // testa rampa > 10 msec fino a 2sec
  
    TempoRampa = 2000000;
// valori testati
//    TempoRampa = 20000;
//    TempoRampa = 50000;
//    TempoRampa = 90000;
//    TempoRampa = 150000;
//    TempoRampa = 250000;
//    TempoRampa = 500000;
//    TempoRampa = 1000000;
//    TempoRampa = 2000000;

    ArrotondaTempoRampa();
    for (cicli = 1; cicli<100; cicli++){
      (FunctionPointed)(); 
      delay(TempoRampa/1000);
    }
}

//-------------------------------
void loop5(){
  // testa rampe con chiamata da Arrotondamento da 1usec a 9999usec
  for (unsigned long Testusec = 1000; Testusec<10000; Testusec++){
    TempoRampa = Testusec;
    ArrotondaTempoRampa();
    for (cicli = 1; cicli<100; cicli++){
      (FunctionPointed)(); 
      delay(1);
    }
    delay(10);
    Testusec = Testusec + 499;  // lo facciamo a step di 500, altrimenti è eterno
  }
}

//-------------------------------
void loop4(){
  // testa rampe con chiamata da Arrotondamento da 1usec a 9999usec
  for (unsigned long Testusec = 500; Testusec<1001; Testusec++){
    TempoRampa = Testusec;
    ArrotondaTempoRampa();
    for (cicli = 1; cicli<10; cicli++){
      (FunctionPointed)(); 
      delay(1);
    }
    delay(10);
  }
}

//-------------------------------
void loop3(){
  // testa rampe con chiamata da Arrotondamento da 1usec a 9999usec
  for (unsigned long Testusec = 1; Testusec<501; Testusec++){
    TempoRampa = Testusec;
    ArrotondaTempoRampa();
    for (cicli = 1; cicli<10; cicli++){
      (FunctionPointed)(); 
      delay(1);
    }
    delay(10);
  }
}

//-------------------------------
//-------------------------------

void loop2() {


  //testa le rampe da 100usec a 1msec
  FunctionPointed = Rampa100usec;
  for (cicli = 1; cicli<10000; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa150usec;
  for (cicli = 1; cicli<7500; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa200usec;
  for (cicli = 1; cicli<5000; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa250usec;
  for (cicli = 1; cicli<4000; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa300usec;
  for (cicli = 1; cicli<3300; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa400usec;
  for (cicli = 1; cicli<2500; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa500usec;
  for (cicli = 1; cicli<2000; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa600usec;
  for (cicli = 1; cicli<1600; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa700usec;
  for (cicli = 1; cicli<1400; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa800usec;
  for (cicli = 1; cicli<1200; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa900usec;
  for (cicli = 1; cicli<1100; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa1msec;
  for (cicli = 1; cicli<1000; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa2msec;
  for (cicli = 1; cicli<500; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa3msec;
  for (cicli = 1; cicli<333; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa4msec;
  for (cicli = 1; cicli<250; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa5msec;
  for (cicli = 1; cicli<200; cicli++){
    (FunctionPointed)(); 
  }

  FunctionPointed = Rampa8msec;
  for (cicli = 1; cicli<125; cicli++){
    (FunctionPointed)(); 
  }


  



  

}

//***********************************************
//***********************************************
//***********************************************
/*
  - input Durata in microsecondi (TempoRampa)
  - output punta la funzione giusta
void Rampa75usec(void);
void Rampa100usec(void);
void Rampa150usec(void);
void Rampa200usec(void);
void Rampa250usec(void);
void Rampa300usec(void);
void Rampa400usec(void);
void Rampa500usec(void);
void Rampa600usec(void);
void Rampa700usec(void);
void Rampa800usec(void);
void Rampa900usec(void);
void Rampa1msec(void);
void Rampa2msec(void);
void Rampa3msec(void);
void Rampa4msec(void);
void Rampa5msec(void);
void Rampa8msec(void);
void Rampa10_1000ms(int RampaMilliS); 
void Rampa1000_10000ms(int RampaMilliS); 

La soglia è l'intero tra i due valori limitrofi (ad esempio tra 75 e 100 la soglia è 88)
*/ 
void  ArrotondaTempoRampa(void){
   if (TempoRampa == 0)   { FunctionPointed = DacFullScale; return 0; }

   if (TempoRampa < 88)   { FunctionPointed = Rampa75usec ; return 0; }
   if (TempoRampa < 125)  { FunctionPointed = Rampa100usec; return 0; }
   if (TempoRampa < 175)  { FunctionPointed = Rampa150usec; return 0; }
   if (TempoRampa < 225)  { FunctionPointed = Rampa200usec; return 0; }
   if (TempoRampa < 275)  { FunctionPointed = Rampa250usec; return 0; }
   if (TempoRampa < 350)  { FunctionPointed = Rampa300usec; return 0; }
   if (TempoRampa < 450)  { FunctionPointed = Rampa400usec; return 0; }
   if (TempoRampa < 550)  { FunctionPointed = Rampa500usec; return 0; }
   if (TempoRampa < 650)  { FunctionPointed = Rampa600usec; return 0; }
   if (TempoRampa < 750)  { FunctionPointed = Rampa700usec; return 0; }
   if (TempoRampa < 850)  { FunctionPointed = Rampa800usec; return 0; }
   if (TempoRampa < 950)  { FunctionPointed = Rampa900usec; return 0; }
   if (TempoRampa < 1500) { FunctionPointed = Rampa1msec  ; return 0; }
   if (TempoRampa < 2500) { FunctionPointed = Rampa2msec  ; return 0; }
   if (TempoRampa < 3500) { FunctionPointed = Rampa3msec  ; return 0; }
   if (TempoRampa < 4500) { FunctionPointed = Rampa4msec  ; return 0; }
   if (TempoRampa < 6500) { FunctionPointed = Rampa5msec  ; return 0; }
   if (TempoRampa < 9000) { FunctionPointed = Rampa8msec  ; return 0; }
                                          
   if (TempoRampa > 9000) { FunctionPointed = RampaLenta; return 0; }

   
  
}


//***********************************************
// per rampa di durata da 10msec a 1000msec si usa Rampa10_1000ms(int RampaMilliS); 
// per rampa di durata da 1sec a 10 sec si usa Rampa1000_10000ms(int RampaMilliS);

void RampaLenta(void){
  if (TempoRampa < 1000000){
    Rampa10_1000ms(TempoRampa / 1000); // vuole il parametro in millisecondi
  } else {
    Rampa1000_10000ms(TempoRampa / 1000);
  }
  
}


//***********************************************

void DacFullScale(void){
  PORTD=0;
}

void DacZero(void){
  PORTD=255;
}


//***********************************************


void Rampa75usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;   
  }  
}


void Rampa100usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    asm("nop");   
    asm("nop");      
  }
}


void Rampa150usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop"); 
    asm("nop");   
  }
}

void Rampa200usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   

    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   
  }  
}

void Rampa250usec(void){
  /*
  for(int y=255;y>-1;y--){
    PORTD=y;
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   

    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   

    asm("nop");   
    asm("nop");     
    asm("nop");   
    

  }
  */
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(2);
  }
  
}

void Rampa300usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   

    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   

    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");
       
    asm("nop");   
    asm("nop");   
  

  }
}
//-------------------------------------------------
void Rampa400usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(2);
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   

    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");
       
    asm("nop");   
    asm("nop");   
  }
}




void Rampa500usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(3);
  }
}

void Rampa600usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(3);
    asm("nop");   

    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");
       
  }
}


void Rampa700usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(3);
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");
       
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");   
    asm("nop");

    asm("nop");
       
  }
}


void Rampa800usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(4);
    asm("nop");         
  }
}

void Rampa900usec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(4);
    asm("nop");         
    asm("nop");         
    asm("nop");         
    asm("nop");         
    asm("nop");         
    asm("nop");         
  }
}


//-------------------------------------------------
void Rampa1msec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(5);
  }
}


void Rampa2msec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(9);
  }
}

void Rampa3msec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(13);
  }
}

void Rampa4msec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(17);
  }
}

void Rampa5msec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(21);
  }
}

void Rampa8msec(void){
  for(int y=255;y>-1;y--){
    PORTD=y;
    delayMicroseconds(34);
  }
}


//-------------------------------------------------
// rampa con durata da 10ms a 1000 msec 
//bisogna dividere il parametro per circa 1,3

void Rampa10_1000ms(int RampaMilliS){
  float float2;
  int int2;
  float2 = RampaMilliS * 10;
  float2 = float2 / 13;
  
  int2 = float2;
  int2 = int2 * 5;
  
  for(int y=255;y>-1;y--){
      PORTD=y;
      delayMicroseconds(int2);
  }    
}

//-----------------------------------

void xxRampa1000_10000ms(int RampaMilliS){ 
  for(int y=255;y>-1;y--){
      PORTD=y;
      delay(RampaMilliS * 4);
  }    
}


void Rampa1000_10000ms(int RampaMilliS){ 
  int int3;
  int3 = RampaMilliS * 4; 
  for(int y=255;y>-1;y--){
      PORTD=y;
      delayMicroseconds(int3);
  }    
}

Non è la risposta al topic.
Il core Arduino mantiene abilitati gli interrupt globali, per cui durante un ciclo for o altro tra una istruzione assembly e l'altra può essere sollevato una IRQ e servita la relativa ISR. Questo accade per il contatore restituito da millis(), dove una ISR viene chiamata ogni 1ms. Il for che realizza la rampa non è sincronizzato (mi pare) per cui può verificarsi la chiamata alla ISR per incrementare il contatore di millis. Per aggirare il problema si può rendere atomica una porzione di codice che per natura non lo è, lo puoi fare come ho mostrato.

Qui la doc di ATOMIC_BLOCK.

Ciao.

1000 grazie !!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.