Go Down

Topic: Problemi funzioni Touchscreen e PWM simultaneamente (Read 1 time) previous topic - next topic

vinciolo

Salve a tutti sono un neofita e spero possiate aiutarmi.

Io ho un Arduino Mega 2560 R3, un real time clock,un sensore DS18S20,4-5 sensori LM35Dz,-3 sensori LM35DT,una scheda relè fatta in casa con 20 relè,2.8 "TFT Touch Shield Adafruit per Arduino.

sto realizzando un automazione completa per acquario e sono a buon punto,potrei quasi dire che ho finito, la parte di programma per il controllo del Touch completo di porzione di programma del real time e dei sensori di temperatura.Ora il mio problema è il seguente:

tramite le uscite PWM di arduino vado a controllare dei driver che mi accenderanno o spegneranno dei led di potenza ad un determinato orario o con delle determinate condizioni(se le voglio accendere io).
Per fare l'accensione ad un determinato orario ho usato delle if e poi un ciclo for esempio di programma:
Quote

    //Controllo accensione Led bianchi 1
    if(hour>=oreOnBianchi1 && minute>=minutiOnBianchi1 && b==1){
      for (valoreLed_W1 = W1 ; valoreLed_W1 < VLW1; valoreLed_W1++) {
      analogWrite(LED_White1, valoreLed_W1);  //imposta la luminosità dei LED
      delay(delaytRAMPAW1);
      }
    }



dove VLW1 arriva al max a 255 ed è un valore impostabile tramite touch dall'utente
delaytRAMPAW1 è sempre impostabile dall'utente.

un programma esempio per il controllo del touch è questo:
ho usato sempre delle if

Quote

    //TASTO MENO PER DECREMENTARE IL MESE
    if ( p.x > 5 && p.x < 30 && p.y > 110 && p.y <135 && dc==1 && month>=2) {
      int newmonth;
        mc=1;
        dc=1;
        cc=0;
        tc=0;
        ic=0;
        ac=0;
        fc=0;
        sc=0;
        p.x=0;
        p.y=0;
        delay(500);
        newmonth=month-1;
        month=newmonth;
        tft.fillRect(51, 111, 138, 23, YELLOW);//riempimento rettangolo 
        tft.setCursor(65, 115);
        tft.setTextSize(2);
        tft.println("MESE:");
        tft.setCursor(140, 115);
        tft.println(month);
      setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
    }




logicamente questi sono solo i pezzi del void loop

ora il problema è:

se inizia il ciclo for per il PWM dei LED il touch è fuori uso, ovvero non riesco a fare niente fin quando il PWM dei led non è finito

ora vi chiedo cosa posso fare? posso risolvere la cosa a livello di programma usando altre cose? e quindi poter usare touch mente c'è il pwm
oppure dovrò procurarmi un altro arduino che mi faccia il pwm  e che sia interconnesso serialmente al mio arduino mega?

p.s.
info aggiuntive

la home page del programma(touch) si aggirna ogni secondo per aggiornare l'orario e i valori di temparatura

vi posto anche il link del video del funzionamento del touch:
http://www.youtube.com/watch?v=XJh8zodTlVY

il video è pessimo lo so ma è fatto con il cellulare

spero possiate aiutarmi

uwefed

Quello che aiuterebbe a risponderti sarebbe lo sketch intero.
In generale posso dire di usare un ciclo di incremento / decremento PWM senza for (perché il programma resta nel for finche non é terminato) e determina la velocitá di fade con millis() (vedi esempio blink without delay).

Ciao Uwe

vinciolo

grazie per la risposta

il programma intero non saprei come postarlo è lungo 8000 righe senza il controllo del PWM cioè solo programma per touch e occupa 130 Kb  più o meno su arduino

come si fa un incremento/decremento senza for?

mi spiegheresti meglio come funziona il millis()?

tieni presente che il PWM,in incremento o decremento, dei led non dura qualche secondo ma dura circa 60 minuti per ogni uscita

questi 60 minuti però possono essere sia di meno che di più questo è un tempo impostabile dall'utente

perdona le domande forse anche stupide ma sono alle prime armi :)

uwefed

#3
Jan 13, 2013, 11:26 pm Last Edit: Jan 13, 2013, 11:28 pm by uwefed Reason: 1
millis() ti da il numero di millisecondi trascorsi dall accensione.
http://arduino.cc/en/Reference/Millis

Sketch esempio per incrementio senza for:
Code: [Select]
unsigned long intervallo_PWM = 14000;  //per 255 step in 60 minuti
unsigned long currentMillis;
unsigned long previousMillis = 0;

int i=0 // Variable incremento
int LED_pin = x //piedino PWM dove attacato luce LED.
int statoINC; // variabile se attivo aumento luce.

setup()
{
unsigned long currentMillis = millis();
}
loop()
{
 if (statoINC == 1)               // attivo fade incremento
 {currentMillis = millis();
 if((currentMillis - previousMillis > intervallo_PWM))
 {
 previousMillis = currentMillis;
 i++
 analogWrite(LED_pin,i);
 if (i==255) statoINC =0; // stop al raggiungimento max luminositá LED
 }
 }
}


Stessa cosa si puó fare per la diminuizione di luce.
La variabile statoINC decide se viene fatto il PWM o se la luminositá della luce resta costante. Per fare partire una rampa di aumneto luce si deve mettere a 0 "i" e a 1  "statoINC".
In analogia la diminuizione si pilota con la variabile statoDEC.
Se si ha piú luci indipendenti é da copiare tutto per ogni luce.

Ciao Uwe  

vinciolo

#4
Jan 14, 2013, 10:06 am Last Edit: Jan 14, 2013, 10:12 am by vinciolo Reason: 1
grazie infinite

oggi lo provo e vedo come va:)

il delay influisce sui millis?

perchè ho la home page che si aggiorno ogni secondo circa e non vorrei che bloccasse il millis altrimenti mi tocca fare l'aggiornamento con il millis
il codice è il seguente:

Quote

    if(a==1){//AGGIORNAMENTO IN HOME PAGE PER TEMPERATURE E ORARIO
    if( hour>=oreOnBianchi1 && hour<oreOffBianchi1){
        a=1;//reimposta la variabile di controllo
        cc=1;
        mc=1;
        dc=0;
        tc=0;
        ic=0;
        ac=0;
        fc=0;
        sc=0;
        b=1;
       
        tft.fillRect(20, 35, 200, 45, BLACK);//serve per RIPULIRE la porzione di schermo
        tft.setCursor(25, 40);
        tft.setTextColor(BLUE); tft.setTextSize(2);
        if(dayOfWeek==1){
        tft.print("LUNEDI'");//QUI ANDRà INSERITO IL VALORE DEL REAL TIME
        }
        if(dayOfWeek==2){
          tft.print("MARTEDI'");
        }
        if(dayOfWeek==3){
          tft.print("MERCOLEDI'");
        }
        if(dayOfWeek==4){
        tft.print("GIOVEDI'");//QUI ANDRà INSERITO IL VALORE DEL REAL TIME
        }
        if(dayOfWeek==5){
          tft.print("VENERDI'");
        }
        if(dayOfWeek==6){
          tft.print("SABATO");
        }
        if(dayOfWeek==7){
          tft.print("DOMENICA");
        }
        tft.setCursor(125, 40);
        tft.print(dayOfMonth);
        tft.print("/");
        tft.print(month);
        tft.print("/");
        tft.print(year);
        tft.setCursor(25, 60);
        tft.print("ORA: ");
        tft.setCursor(125, 60);
        tft.print(hour);
        tft.print(":");
        tft.print(minute);
        tft.print(":");
        tft.println(second);
        tft.fillRect(0, 120, 240, 75, BLACK);//serve per RIPULIRE la porzione di schermo
        tft.setCursor(15, 125);
        if(Tplafo<=TnomPlafo){
        tft.setTextColor(BLUE);
        }
        if(Tplafo>TnomPlafo && Tplafo<TmaxPlafo){
        tft.setTextColor(GREEN);
        }
        if(Tplafo>=TmaxPlafo){
        tft.setTextColor(RED);
        }
        tft.print("PLAFONIERA: ");
        tft.setCursor(150, 125);
        tft.print(Tplafo);
        tft.println("C");
        tft.setCursor(15, 150);
        if(Tsistema<=TnomSistema){
        tft.setTextColor(BLUE);
        }
        if(Tsistema>TnomSistema && Tsistema<TmaxSistema){
        tft.setTextColor(GREEN);
        }
        if(Tsistema>=TmaxSistema){
        tft.setTextColor(RED);
        }
        tft.print("SISTEMA: ");
        tft.setCursor(150, 150);
        tft.print(Tsistema);
        tft.println("C");
        tft.setCursor(15, 175);
        if(Tvasca<=TminVasca){
        tft.setTextColor(BLUE);
        }
        if(Tvasca>TminVasca && Tvasca<TmaxVasca){
        tft.setTextColor(GREEN);
        }
        if(Tvasca>=TmaxVasca){
        tft.setTextColor(RED);
        }
        tft.setTextSize(2);
        tft.print("VASCA: ");
        if(Tvasca>=1){
        tft.setCursor(150, 175);
        }
        else{
          tft.setCursor(110, 175);
        }
        tft.print(Tvasca);
        tft.println("C");
       if( (p.x > 30 && p.y > 200 && p.x < 210 && p.y < 250 && (cc==1 || cc==3))||(p.x > 40 && p.y > 255 && p.x < 200 && p.y < 285 && cc==1)||(p.y < 320 && p.y > 290 && p.x > 0 && p.x < 83 && mc==1)){
       
         /*
         Se si preme sui tasti MENU',MANUTENZIONE O INFORMAZIONI
         si imposta la variabile di controllo per l'aggiornamento schermo a zero 
         in modo tale da uscire dal ciclo di aggiornamento e usufruire del touch
         */
         a=0;
       }         
       delay(750);
     }
}


uwefed

#5
Jan 14, 2013, 01:38 pm Last Edit: Jan 14, 2013, 02:52 pm by uwefed Reason: 1
Il delay non influisce sui millis ma il problema á che durante il delay() non puoi leggere i pulsanti e 0,75 secondi sono tanti. Rischi di perdere dei azionamenti del pulsanti.
Ciao Uwe

vinciolo

#6
Jan 14, 2013, 01:46 pm Last Edit: Jan 27, 2013, 10:32 am by vinciolo Reason: 1
a ok capito

allora l'aggiornamento lo faccio con i millis

il codice sopra che hai postato l'ho provato(leggermente modificato) e funziona benissimo:)

vinciolo

ragazzi nel fare un semplice ritardo
es: dopo aver premuto un pulsante(sul touch) mi deve cambiare schermata come posso cambiare il delay con i millis?

if(p.x>=40 && p.x<=200 && p.y>=230 && p.y<=280 && cc==3){
        a=0;
        delay(300);
       
        p.x=0;
        p.y=0;
        cc=4;//reimposta la variabile di controllo
        mc=1;
        dc=0;
        tc=0;
        ic=0;
        ac=0;
        fc=0;
        pc=0;
        sc=0;
        info=0;
               
        tft.fillRect(41, 231, 158, 48, RED);//RIEMPIMENTO rettangolo INFORMAZIONI
        tft.setTextColor(BLACK); tft.setTextSize(2);
        tft.setCursor(55, 238);
        tft.print("SPEGNIMENTO");
        tft.setCursor(97, 258);
        tft.print("LUCI");
     
    //inserire anche il controllo per dare alimentazione a plafoniera tramite relè
   }


devo mettere un'altra if come per il PWM dei led? quindi con tutte le variabili che servono?

PaoloP

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

vinciolo


PaoloP

Dipende da come hai strutturato il programma.
Potresti usare i timer (tramite millis) per aggiornare il display e con la pressione dei pulsanti aggiornare le variabili che verranno mostrate al successivo aggiornamento.
Oppure potresti mettere un filtro sulla pressione del touchscreen in modo che rilevi solo una pressione ogni tot di tempo anche tenendo premuto il dito sul display. quindi non avresti il problema del ritardo perché anche se dovesse cambiare la schermata non verrebbe letto l'eventuale pulsante sulla nuova. Però devi vedere come è strutturata la libreria per vedere se è fattibile.

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

vinciolo

l'aggiornamento del display lo faccio gia con i millis

il ritardo della pagine è solo per una questione di "scena" per non renderla troppo veloce e fastidiosa alla vista e anche perchè ci sono molte pag. che hanno pulsanti nello stesso posto con funzioni differenti es se vedi nel video dal minuto 4,26 in 2 pagine differente c'è un pulsante nello stesso identico posto e se non ci fosse il ritardo rischierei di premere i due pulsanti(nelle due pagine) contemporaneamente

io i millis fin ora li ho usati come
if(succede qualcosa)
{currentMillis_aggiorna=millis();
    if(currentMillis_aggiorna-previousMillis_aggiorna>1000 ){//serve per aggiornare la HOME PAGE ogni 1000 millisicondi
      previousMillis_aggiorna=currentMillis_aggiorna;
}

però fare una cosa del genere per ogni pagina oppure per un incremento o decremento di un numero(tramite touch)
rende il programma troppo pesante(credo) e dovrei usare almeno altre 30 variabili per currentMillis eccecc

p.s. la memoria occupata è gia circa 185K e manca ancora un pò di codice, penso che arriverà a 210-220k quindi deve essere una soluzione che occupa poco spazio di memoria altrimenti terrò il delay:(

vinciolo

ragazzi continuo qui con un altra domanda per il PWM senza che apro un altra discussione tanto il programma è lo stesso

allora io il PWM per i led l'ho fatto come consigliatomi sopra e nello specifico così:

Quote

  //CONTROLLO INCREMENTO FADE LED BIANCHI 1
  if(hour>=oreOnBianchi1 && minute>=minutiOnBianchi1 && hour<oreOffBianchi1 && valoreLed_W1<VLW1)
  {
    statoINC_W1 = 1;//fa partire l'incremento
  }
  else
  {
    statoINC_W1 = 0;// stop al raggiungimento max luminositá LED
  }
  //ciclo di incremento del led bianchi 1
  if (statoINC_W1 == 1)
  {
    currentMillis_W1 = millis();
    if(currentMillis_W1 - previousMillis_W1 > delaytRAMPAW1)
    { 
      previousMillis_W1 = currentMillis_W1;
      valoreLed_W1++;
      analogWrite(LED_White1,valoreLed_W1);
      //Serial.print("valoreLed_W1: ");
      // Serial.println(valoreLed_W1);
    }
  }



vale anche per il decremento

come vedere parte ad un determinato orario, impostato tramite TFT, e aumenta la luminosità di 1 ogni tot secondi (delaytRAMPAW1) sempre impostato da TFT e anche la massima luminosità (VLW1) è impostata da TFT

il problema che mi pongo è il seguente: si può fare un controllo PWM tramite funzione map che tenga conto dell'ora di accensione e del tempo di rampa?

leo72

La map altro non fa che una proporzione matematica trasformando un valore da una scala all'altra.

Go Up