Home Forum MICROCONTROLLORI >Problema con programma pic

Questo argomento contiene 13 risposte, ha 7 partecipanti, ed è stato aggiornato da  ferfabry76 2 mesi, 3 settimane fa.

Stai vedendo 14 articoli - dal 1 a 14 (di 14 totali)
  • Autore
    Articoli
  • #60780

    trabo
    Membro

    Salve a tutti.
    Sono qui per chiedervi una mano se possibile.
    Ho realizzato un programma in MikroBasic, utilizzando il pic 12f629.
    E sono giorni che sto provando ad ultimarlo

    E’ un piccolo progetto, ovvero una schedina , con il pic centrale, dove c’è collegato un pulsante e 8 led.
    Praticamente ho bisogno che questo sistema,quando si preme il pulsante, cambia effetto ai led.
    Appena acceso luce fissa, pulsante premuto metà potenza, pulsante premuto strobo, pulsante premuto 4 led accesi e 4 no (si alternano) premo il pulsante deve tornare su fissa.
    Il mio problema è che quando premo il pulsante, mi cambia gli effetti, ma non in modo ordinato, ma casuale.
    Magari fa 3 volte un effetto poi passa all’altro.

    Spero nel vostro aiuto.

    Grazie
    Ecco il programma

    program MyProject

    main:
    TRISIO.1=0
    TRISIO.2=0
    TRISIO.0=1
    cmcon=7
    IF gpio.0=0 THEN
    GOTO fissa
    end if

    fissa:
    TRISIO.1=0
    TRISIO.2=0
    TRISIO.0=1
    cmcon=7
    while true
    gpio.1=1
    gpio.2=1
    if gpio.0=1 then
    goto inizio
    end if
    wend

    inizio:
    delay_ms(100)
    TRISIO.1=0
    TRISIO.2=0
    TRISIO.0=1
    cmcon=7

    while true
    if gpio.0=1 then
    goto mezzo
    end if
    GPIO.1=1
    gpio.2=1
    delay_us(50)
    GPIO.2=0
    gpio.1=0
    delay_us(50)
    IF GPIO.0=1 THEN
    GOTO mezzo
    end if
    wend

    mezzo:
    delay_ms(100)
    TRISIO.1=0
    TRISIO.2=0
    TRISIO.0=1
    cmcon=7

    while true
    if gpio.0=1 then
    goto strobo
    end if
    gpio.2=1
    delay_ms(500)
    gpio.2=0
    delay_ms(500)
    gpio.1=1
    delay_ms(500)
    gpio.1=0
    delay_ms(500)
    if gpio.0=1 then
    goto strobo
    end if
    wend

    strobo:
    delay_ms(100)
    TRISIO.1=0
    TRISIO.2=0
    TRISIO.0=1
    cmcon=7
    while true
    if gpio.0=1 then
    goto fissa
    end if
    gpio.1=1
    gpio.2=1
    delay_ms(50)
    gpio.1=0
    gpio.2=0
    delay_ms(50)
    if gpio.0=1 then
    goto fissa
    end if
    wend
    end.

    #75758

    maxvarese
    Membro

    Ciao,
    mi sembra che sia un problema di gestione del pulsante, ovvero devi gestire l’antirimbalzo o utilizzare un cond. 100 nF.

    Se possibile commenta il sw in modo che sia + leggibile.

    #75759

    IvanScordato
    Membro

    un buon consiglio, prova e facci sapere

    #75760

    Ciao!

    Si molto probabilmente è la mancanza di debounce sul tasto ma sarebbe meglio se ci descrivi un po’ il codice per capire se effettivamente il problema è quello del debounce.
    Ad esempio “gpio.0″ è il tasto?

    Facci sapere.

    Ps: un consiglio, usa l’assembrer, scoprirai che è più semplice poi sia per implementare il firmware sia per capire e risolvere i problemi.

    #75761

    ferfabry76
    Membro

    Ciao

    in effetti manca proprio l’antirimbalzo che ti consiglio di realizzare via software. Puoi realizzarlo in diversi modi: o accettando la pressione del tasto se questo viene premuto per almeno un determinato tempo. L’importante è che appena accettata la pressione del tasto tu setta un flag che inibisca il tasto stesso. Questo flag viene resettato quando il tasto cambia di stato.

    Per quanto riguarda il codice è scritto in maniera confusa, sequenziale, senza indentazione e senza commenti.

    In merito a chi consiglia invece l’assembler non sono d’accordo. I moderni compilatori C e basic per questi micro permettono di realizzare codice altamente scalabile e riutilizzabile su innumerevoli dispositivi senza cambiare una riga di codice, con le dovute limitazioni tra le famiglie ovviamente. L’assembler lo utilizzo solamente per le routine di interrupt riguardanti timer e ricezioni seriali dove ho necessitò di un codice ottimizzato e pulito. Ovviamente ti consiglio di utilizzare i compilatori C messi gratuitamente a disposizione dalla Microchip sicuramente più professionali, anche se per anni ho usato ed utilizzo ancora il compilatore PicBasic PRO.

    #75766

    gio22
    Membro

    Ciao.
    Sto cercando di aiutarti…. dove sono collegati gli 8 led e il pulsante?
    Il PIC di cui parli ha poche porte di I/O.
    Il listato era indentato oppure il copia e incolla e’ imperfetto?
    Se mi alleghi uno schema posso aiutarti.
    CIao
    Giovanni

    #75768

    Forse scrivendo sono stato un po’ frettoloso e ho omesso alcune cose.

    Visto il progetto e le problematiche ho dato per scontato che il nostro amico “trabo” fosse alle prime armi (chiedo preventivamente scusa se non è così) ed è per questo ho consigliato l’assembler.
    Iniziare a programmare i micontrollori con il cosiddetto “linguaggio macchina” (assembler per intenderci) ti permette di conoscerli più a fondo e averne più padronanza, cosa che nel mondo dell’embedded spesso è necessaria.

    Non conosco molto bene il MikroBasi ma non mi trovi molto d’accordo sul suo utilizzo: nell’embedded un linguaggio troppo astratto rischia di far perdere di vista delle cose che sono necessarie. Una tipica situazione è quando devi realizzare un sistema che risponda in real-time a degli eventi esterni: in questo caso se l’astrazione è troppo elevata non riesci a controllarlo.
    Mi trovi d’accordo invece sul C, non a caso è stato sviluppato proprio per velocizzare gli sviluppi che venivano fatti in assembler ed è un linguaggio in cui i puntatori fanno da padroni (in assembler quando si usano le variabili in realtà si usano i puntatori).
    Tutto questo è un discorso che è indipendente dal tipo di compilatore usato.

    Ovviamente tutto questo discorso riguarda il mondo dell’embedded (termine relativo tra l’altro), se ci si spinge verso sistemi più complessi come un PC o uno smartphone, un linguaggio di programmazione più di alto livello è necessario (quasi indispensabile) a discapito ovviamente del pieno controllo dell’hardware.

    Tornando alla questione principale: abbiamo bisogno di spiegazione per il codice :D

    #75770

    Ciao trabo, Il tuo programma è un esempio classico di macchina a stati. Quello che hai fatto è un classico errore in cui si cade quando si scrivono macchine a stati. Tu hai un programma che può assumere diversi stati (configurazioni dell’uscita); poi hai una condizione (pulsante premuto) che fa passare da uno stato all’altro. Il problema è che la stessa condizione determina il passaggio di tutti gli stati, per cui una volta che premi il pulsante il programma comincia a passare da uno stato all’altro senza fermarsi finché non lasci il pulsante. E’ necessario quindi porre una condizione che impedisca il cambiamento di stato finché non si verifica: tale condizione è ovviamente quella di aspettare che il rilascio del pulsante prima di accettare il prossimo passaggio. Basta un:
    while gpio.0=0
    wend
    e stai li dentro finche il pulsante non è stato rilasciato.
    Il debounce è un’altra cosa, non è questo il caso.
    Saluti

    #75771

    Ha ragione Stefano Panichi, il problema non sta sul debounce. Per motivi di lavoro ieri ero in viaggio e potendo usare solo il cellulare, non ero in grado di prendere il tuo codice e analizzarlo con più attenzione.

    Effettivamente il tuo problema è sul fatto che il codice così come è fatto scorre i vari effetti fintantoché tieni premuto il tasto, al rilascio si ferma sull'ultimo effetto su cui è passato e il tutto lo fa alla velocità del microcontrollore.

    Per risolvere il problema in modo facile, io metterei il seguente codice subito dopo ogni "label:":

     

    label:
          while gpio.0=1
          goto label

     

    in questo caso avresti l'inconveniente che il dispositivo non cambia gioco finchè non rilasci il tasto, ma come modifica è molto semplice; potresti anche mettere questo ciclo di attesa dopo l'inizializzazione dei TRIS.

    Per evitare questo dovresti fare il codice un po' più complesso.

     

    Facci sapere.

    Ciao!

    #75772

    ferfabry76
    Membro

    Per esperienza il solo controllo sul cambio di stato del pulsante non sempre è sufficiente, sopratutto a seconda della qualità e del tipo di pulsante utilizzato. Non è sempre detto che il contatto sia “perfetto” e generi un cambio si stato singolo. Per questo motivo preferisco sempre accettare la pressione di un tasto se premuto per almeno un determinato tempo. In alternativa la pressione del tasto può incrementare un contatore che raggiunto un determinato valore accetta la pressione del tasto stesso, cosa semplicissima da realizzare. Il rilascio anzitempo provoca il reset del contatore.

    #75780

    trabo
    Membro

    Per prima cosa mi scuso per aver risposto cosi’ tardi.
    Ho avuto problemi di connessione.
    Come qualcuno hanno già intuito, sono quasi alle prime armi.
    Sto utilizzando il Mikrobasic perchè a scuola l’ho ”studiato”, e quindi non sono completamente a 0.
    Vorrei scusarmi anche per la poca comprensione del programma scritto.

    E quindi vorrei ringraziarvi per le soluzioni che mi state proponendo.
    Ora cerchero’ di dare qualche chiarimento.
    Volevo rispolverare la programmazione con i PIC, dato che con loro si posso fare molte cose, e quindi partire con un piccolo progettino fatto in casa, molto banale , ma che sta sembrando difficile ;-).

    Ora passiamo al progetto, ho realizzato su millefori, un circuito
    ecco il link dello schema:

    http://i58.tinypic.com/2lt65v4.jpg.

    Non so se ho errato qualcosa.

    Ho provato anche ad inserire il While gpio.0=0

    program prova

    main:
    while true

    trisio.0=1
    trisio.1=0
    trisio.2=0
    gpio.0=0
    gpio.1=0
    gpio.2=0
    cmcon=7

    while gpio.0=0
    gpio.1=0 primi 4 led spenti
    gpio.2=1 secondi 4 led accesi
    wend

    delay_ms(1000)

    while gpio.0=0
    gpio.1=0 spegne i 4 led di gpio.1
    gpio.2=1 accende i 4 led di gpio.2
    delay_ms(1000)
    gpio.1=1 accende i 4 led di gpio.1
    gpio.2=0 spegne i 4 led di gpio.2
    delay_ms(1000)
    wend

    delay_ms(1000)

    wend

    end.

    Ma in questo modo, dal primo effetto passa al secondo…
    E dal secondo si blocca, o meglio premo il pulsante e riparte dal secondo invece di tornare al prima, sembra quasi un reset.
    Vi ringrazio ancora, aspetto i vostri commenti..
    GRAZIE

    #75781

    trabo
    Membro

    Vorrei aggiungre che, seavete skyipe potete aggiungermi, in modo da poter parlare meglio.

    nick: trabbone

    #75784

    Ciao!

    Non conosco molto bene il MikroBasic ma da come mi dici potrebbe essere che il micro esegue il reset proprio perchè rimane dentro questo ciclo di attesa: solitamente all’interno dei micro c’è una periferica chiamata watchdog timer; questo “cane da guardia” non fa altro che resettare il micro allo scadere di un timer, a meno che l’utente tramite il software non lo resetta periodicamente.
    E’ utile per sbloccare il micro in caso di blocco del software. Si può disabilitare ma è utile tenerlo attivo e eseguire periodicamente il reset.
    In MikroBasic non so quale sia l’istruzione per il reset, in assembler è clrwdt (prova a cercare il suo equivalente con google).

    Nel tuo caso prova mettere il reset su ogni ciclo e quindi all’interno del ciclo principale; prova perchè se così ti funziona allora il problema è quello.

    Riguardando il tuo progetto noto che sul pulsante ci hai messo una sorta di anti rimbalzo via hardware e quindi probabilmente non necessita di quello software, anche se solitamente viene fatto via software.

    Prova a vedere se ti funziona resettando il watchdog, in caso poi vediamo il discorso dell’anti rimbalzo.

    Facci sapere.
    Ciao

    #75785

    ferfabry76
    Membro

    Il watchdog sui microchip va sempre abilitato settando gli opportuni registri e non si attiva mai da solo.
    Tenderei ad escludere quindi questa motivazione.
    L’antirimbalzo hardware per essere realizzato in maniera efficacie deve essere modificato.
    Il classico circuito prevede il condensatore verso massa ma la resistenza in pull-up ed il pulsante che chiude verso massa. Basterà poi invertire nel micro la logica.

    Ovviamente è conveniente realizzare il tutto via software come indicato in precedenti commenti.

    saluti

Stai vedendo 14 articoli - dal 1 a 14 (di 14 totali)

Devi aver eseguito l’accesso per poter rispondere a questa discussione.