Attiny85-Risolto

ciao a tutti, mi sto imbattendo in un problema non da poco...
Ho scoperto questo processore e vorrei creare dei giochi con i led, ma ho dei problemi...
Qualcuno mi può chiarire se posso usare tre uscite PWM?
Con due uscite funziona tutto bene, ma quando voglio usare la terza mi va in crisi.....
Forse sbaglio io....

byte isin_val[]={
127,129,131,134,136,138,140,143,145,147,149,151,154,156,158,160,162,164,
166,169,171,173,175,177,179,181,183,185,187,189,191,193,195,196,198,200,
202,204,205,207,209,211,212,214,216,217,219,220,222,223,225,226,227,229,
230,231,233,234,235,236,237,239,240,241,242,243,243,244,245,246,247,248,
248,249,250,250,251,251,252,252,253,253,253,254,254,254,254,254,254,254,
255};


int passo_tempo_1 = 3000; // passo tempo in ms - periodo intero del fading 15ms*360 = 5,4 s
int passo_tempo_2 = 3000; // passo tempo in ms - periodo intero del fading 10ms*360 = 3,6 s
int passo_tempo_3 = 10000; // passo tempo in ms - periodo intero del fading 10ms*360 = 3,6 s

byte incremento = 1; // rappresenta l'incremento o decremento dei gradi sessagesimali

int luce_1 = 0; // luminosità del led
int luce_2 = 0;
int luce_3 = 0;


int grado_1 = 0; // inizializzo la variabile che rappresenta i gradi sessagesimali
int grado_2 = 45;  //sfasamento di 90 gradi tra i due fade
int grado_3 = 0; 

unsigned long tempo_corrente; 
unsigned long tempo_corrente2;
unsigned long tempo_rif_1;
unsigned long tempo_rif_2;
unsigned long tempo_rif_3;
unsigned long tempo_acceso;
unsigned long tempo_spento;
unsigned long ritardo;
 boolean fade_up=true;
 boolean fade_dw=false;
#define tempo_ON 10000                //tempo che il led 3 deve restare acceso
#define tempo_OFF 3000                //tempo che il led 3 deve stare spento
#define led_1 0  // numero del pin 
#define led_2 1  // numero del pin 
#define led_3 4  // numero del pin 

// dichiaro la funzione isin calcolo seno con numeri interi
int isin(int x)
{
 boolean pos = true;  // tengo conto del segno del seno.

 if (x >= 360) x %= 360;  
 if (x > 180){
   x -= 180;
   pos = !pos;
 }
 if (x > 90) x = 180 - x;
  if (pos){ 
    return isin_val[x];
  }
  else{
  return (isin_val[x]);//255 -
  }
 }


void setup() {
// Serial.begin(9600);
 tempo_corrente = micros();
 tempo_corrente2= micros();
 tempo_rif_1 = tempo_corrente; // tempo_rif tempo di riferimento
 tempo_rif_2 = tempo_corrente; // tempo_rif tempo di riferimento
pinMode(led_1,OUTPUT);
pinMode(led_2,OUTPUT);
pinMode(led_3,OUTPUT);
 analogWrite(led_1,127); // inizializzo la luminosità del led a 127
 analogWrite(led_2,127); // inizializzo la luminosità del led a 127
 analogWrite(led_3,0);

}

void loop() {


tempo_corrente = micros();  // assegno alla variabile tempo_corrente il valore attuale di millis()
tempo_corrente2= micros();
// blocco per led_1
  if(tempo_corrente - tempo_rif_1 >= passo_tempo_1) {
    grado_1 = grado_1 + incremento;
      if (grado_1 >= 360) {
        grado_1 = 0;
        }
    tempo_rif_1 = tempo_corrente;
    luce_1 = isin(grado_1);
    analogWrite(led_1,luce_1);

  }

// blocco per led_2
if(tempo_corrente - tempo_rif_2 >= passo_tempo_2) {
   grado_2 = grado_2 + incremento;
      if (grado_2 >= 360) {
        grado_2 = 0;
        }
     tempo_rif_2 = tempo_corrente;
     luce_2 = isin(grado_2);
     analogWrite(led_2,luce_2);

  }
// blocco led_4 intermittenza

if (fade_up==true && millis()-tempo_spento>=tempo_OFF){ 
if(tempo_corrente2 - tempo_rif_3 >= passo_tempo_3) {
   grado_3 = grado_3 + incremento;
      if (grado_3 >= 90) {
        grado_3 = 90; fade_up=false;tempo_acceso=millis();
        }
     tempo_rif_3 = tempo_corrente2;
     luce_3 = isin(grado_3);
     int parziale1=(luce_3-127)*2;
     if (parziale1>255){parziale1=255;}
     analogWrite(led_3,parziale1);
 //    Serial.print("parziale1=");Serial.println(parziale1);

  }
  }
if(fade_up==false && millis()-tempo_acceso>=tempo_ON){fade_dw=true;}
if (fade_dw==true){
  if(tempo_corrente2 - tempo_rif_3 >= passo_tempo_3) {
   grado_3 = grado_3 - incremento;
      if (grado_3 <= 0) {
        grado_3 = 0; fade_dw=false;tempo_spento=millis();fade_up=true;
        }
     tempo_rif_3 = tempo_corrente2;
     luce_3 = isin(grado_3);
     analogWrite(led_3,luce_3-127);
 //    Serial.print("parziale2=");Serial.println(luce_3-127);
  }
}



}

Praticamente due LED (led_1 e led_2) fanno una specie di breath rapido, mentre il terzo (led_3) fa un fade in-out temporizzato....
Ma si impalla

manolomao:
... Qualcuno mi può chiarire se posso usare tre uscite PWM? ...

SI, puoi usare le tre uscite PWM ... e ne sono certo perché con degli ATtiny85 controllo delle strisce RGB, pilotando il PWM di ogni singolo colore, quindi ... il problema è sicuramente nel codice.

Guglielmo

attinypdfv3_0.pdf (360 KB)

Dove sbaglio?

Ho replicato lo stesso codice su arduino nano, qui non si imballa ma fa una cosa strana...
Quando fa il fade in/out di led_3, si blocca led_1 e led_2....
Non ho messo nessun delay....creo dei caini con i timer??

Allora, chido scusa...abilitando la seriale sul nano led_1 e led_2 si bloccano; tolto questo funziona bene....
Mi rimane "solo" il problemadi replicarlo su Attiny85....

manolomao:
Allora, chido scusa...abilitando la seriale sul nano led_1 e led_2 si bloccano; tolto questo funziona bene....

SU ATtiny85 NON hai la seriale quindi il problema non si pone ...
... i timers NON mi sembra che li manipoli direttamente (non ho visto modifiche hai registri dei timers), quindi non puoi creare problemi ai timers ... resta solo qualche errore di programmazione da verificare ... ::slight_smile:

Guglielmo

Vedo che hai accuratamente evitato l'uso ripetuto della funzione seno che, usata continuamente, è pesante. Anche il "%" è un operatore un po' pesante. Prova a sostituirlo con qualcosa tipo if(x>360) x-=360; ammesso che tra una chiamata e l'altra x non possa raggiungere 720. Altrimenti dovresti scriverewhile(x>360){x-=360;}Non so, però, se ancora è più leggero di un %...

Ma... Non sarà troppo bassa la frequenza di clock? A quanto l'hai impostata?

Ho trovato la soluzione, devo dire in maniera abbastanza casuale...
Le uscite dell'Attiny85 sono collegate a dei mosfet, a cui poi sono collegati tanti led; molto probabilmente durante le commutazioni dei tre mosfet, si creano dei problemi sull'alimentazione.
Ho aggiunto un condensatore da 100micF (quello che avevo a mano in quel momento) e tutto funziona correttamente!!!
Forse un condensatore da 100nF di disaccoppiamento può bastare....
Grazie a tutti per i consigli...

Eh, certo. Se non hai messo 100 Ohm in serie ai gate, a ogni commutazione è come collegare un condensatore scarico a un'uscita alta. Un condensatore scarico per un attimo è come un corto circuito, perciò sporca l'alimentazione (e non è cosa buona per il microcontrollore). I condensatori sull'alimentazione vanno SEMPRE messi!

Grazie Datman, in realtà la figura che ho usato è come quella che allego, per tutti i MOS...
Come vedi c'è sia la resistenza di gate che quella verso massa...
Un po' di elettronica la mastico, e secondo me quel condensatore fa esattamente quello che dici tu...
anche se con l'osilloscopio non vedevo nulla di anomalo....
Forse l'Attiny è molto sensibile... :grin: