Page 1 of 1

dilemma sulla programmazione GOSUB e RETURN

PostPosted: 07 Jun 2014, 20:21
by mario59
Salve a tutti! ;)
eccomi qui con il nuovo problema: lo STACK harware e software.
Come funzionano e come si usano le variabili $HWSTACK e $SWSTACK e $FRAMESIZE??
Non ci ho mai dato molto peso, perchè con tutti i programmi visibili in giro, i numeri associati a queste variabili generalmente non cambiano molto.
Però vorrei sapere esattamente a cosa servono e come vanno usate correttamente.... :?:
Infatti se pongo dei numeri non adatti, che effetto ne risulta?
Come e da cosa mi accorgo che dovrei aumentare ad es. il framesize?
oppure cambiare il SWSTACK???
Questo mio domandone è dovuto al fatto che il programmino che ho fatto, sia in simulazione che sul micro reale dopo un pò non segue più la seguenza programmata e comincia a saltare (apparentemente ) all'impazzata all'interno del codice... :?
Da che può essere dovuto?
8-) :D
M

Re: dilemma sulla programmazione GOSUB e RETURN

PostPosted: 07 Jun 2014, 20:41
by deluca
@Mario,
se posti il tuo codice possiamo valutarne insieme il funzionamento e provare ad ottimizzarlo modificando opportunamente questi parametri. Non è detto che i sintomi del tuo codice siano legati allo stack configurato male,
ma se sono presenti moltissimi gosub e call a sub, allora potrebbe anche essere.

Re: dilemma sulla programmazione GOSUB e RETURN

PostPosted: 08 Jun 2014, 22:17
by mario59
Allora, eccomi qui.
Qui sotto trovi riportato il codice.
Se tu vai in simulazione, al primo ciclo, non aspetta la pressione di un tasto, ma va direttamente al ciclo principale (test #1, #2, etc.)
chiaramente alla porta IC0...IC3 devono stare tutti a "1".
Ci sono molte linee di codice che ho apostrofato xchè non mi servono ora, perchè sono ancora ad abbozzare il ciclo principale.

Code: Select all
$sim
$regfile = "m328pdef.dat"
$crystal = 16000000
$hwstack = 50
$swstack = 32
$framesize = 40

'
'
'                                11  21
'                    MAXLOAD     31  41      Load MAX
'                       ./         ====     +-----+
'   144v ------------  --------    -----|     |--------/
'                                           +-----+        |
'                                13  23                    |
'                                34  43      Load MIN      |
'                     ./         ====     +-----+        |
'   150v ------------  --------    -----|     |--------
'   30v              MINLOAD                +-----+        |
'                                                          |
'                                                        -----
'
'                    COIL_N
'                     ./                    +-----+
'             /------  -------------------|  N  |--------/
'             |                             +-----+        |
'    24v -----                                            |
'             |       ./                    +-----+        |
'             \------  -------------------|  R  |--------
'                    COIL_R                 +-----+        |
'                                                          |
'                                                        -----
'
'                                19  29      10 kO
'                                ====     +-----+
'                + 5V    --------    ----|     |--------
'                                        |  +-----+        |
'                                        |                 |
'                       Ok_N ------------/               -----

'                                39  49      10 kO
'                                ====     +-----+
'                + 5V    --------    ----|     |--------
'                                        |  +-----+        |
'                                        |                 |
'                       Ok_R ------------/               -----




'***verificare direzioni !!!
Ddrb = &B00110111                                 'definizione direzione pins porta B: 0=IN, 1=OUT
Ddrc = &B11110000                                 'definizione direzione pins porta C: 0=IN, 1=OUT
Portc = &B00001111                                'attiva pullup PORTC
Ddrd = &B11110011                                 'Definizione Direzione Pins Porta D: 0=IN, 1=OUT
Portd = &B11111100                                'attiva pullup PORTD

Config Lcd = 16 * 2                               'configure lcd screen
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portb.1 , Rs = Portb.0

Displ_on Alias Portb.2                            'DEFINISCE IL PIN CONTR. il led display 0=Off, 1=On
Set Displ_on                                      ' accende il display

'definizione tastiera
Star_t Alias Pinc.0
Paus_e Alias Pinc.1
Sto_p Alias Pinc.2
Bypass Alias Pinc.3

'definizione pins I/O !!!

Maxload Alias Portc.4                             'relè abilitazione carico 5A 0=Aperto, 1=Chiuso
Minload Alias Portc.5                             'relè abilitazione carico 200 mA 0=Aperto, 1=Chiuso

Coil_r Alias Portd.0                              'eccitazione bobina R; 0-1-0 tempo di accitazione 500 ms
Coil_n Alias Portd.1                              'eccitazione bobina N; 0-1-0 tempo di accitazione 500 ms

' definizione pins test x verifica avvenuto scambio
Ok_r Alias Pind.2                                 'check stato rele' R
Ok_n Alias Pind.3                                 'check stato relè' N

'pins riservati contatore esterno
Cnt Alias Portb.4                                 'conta impulsi esterno
Res_cnt Alias Portb.5                             'reset conta impulsi
Reset Cnt
Reset Res_cnt

Dim Count As Long                                 'definizioni variabili
Dim I As Double
Dim Key As Byte

Cursor Off
Set Displ_on                                      ' accende il display

Cls                                               ' SPLASH SCREEN
Lcd "* RELAIS FS-58 *"
Locate 2 , 1
Lcd "*FUNCTION TEST *"
Wait 2
Locate 2 , 1
Lcd "* INITIALIZING *"
Wait 2
Cls
Lcd "*INSERT RELAIS *"
Locate 2 , 1
Lcd " & PRESS START "

Comincia:                                         'inizializzazione

Reset Res_cnt                                     'azzero il contatore esterno
Waitms 10
Set Res_cnt
Waitms 10
Reset Res_cnt

Gosub Apertura3141                                'relè in posizione di inizio test

Count = 0                                         'azzero il contatore

Inizio:                                           'inizio programma
Key = 0                                           'routine di controllo tastiera
If Star_t = 0 Then Waitms 20                      'debounce
If Star_t = 0 Then Key = 1 : Goto Continue        'key=1 inizio/continua test
If Paus_e = 0 Then Waitms 20                      'debounce
If Paus_e = 0 Then Key = 2 : Goto Pausa           'key=2 pausa test
If Sto_p = 0 Then Waitms 20                       'debounce
If Sto_p = 0 Then Key = 3 : Goto Continue         'key=3 fine test test
If Bypass = 0 Then Waitms 20                      'debounce
If Bypass = 0 Then Key = 4                        'key=4 al galoppo e poi torna qui
If Key = 1 Then Goto Continue                     'loop dopo il primo start
Goto Inizio                                       'nessun tasto premuto: aspetta ancora


Continue:
'Lcd "KEY pressed=" ; Key

Ciclo:                                            'inizio ciclo di test
'Locate 1 , 1
'step 1
Cls
Lcd "test #1"
'Gosub Apertura3141                                          'apre3141
'gosub check_key                                 'check tastiera
'if key=2 then locate 2,1: lcd "pausa          ": gosub pausa
'if key=3 then locate 2,1: lcd "stop           ": goto fine_test
'if key=4 then gosub galoppo
Wait 1
'step 2
Cls
Lcd "test #2"
'Waitms 3000                                                 'aspetta 3 sec.
'Gosub N_on                                                  'attiva il carico N
'Gosub Chiusura3141                                          'chiude3141
'gosub check_key                                 'check tastiera
'if key=2 then locate 2,1: lcd "pausa          ": gosub pausa
'if key=3 then locate 2,1: lcd "stop           ": goto fine_test
'if key=4 then gosub galoppo
Wait 1
'step 3
Cls
Lcd "test #3"
'Waitms 1500                                                 'aspetta 1,5 sec.
'Gosub Apertura3141                                          'apre3141
'gosub check_key                                 'check tastiera
'if key=2 then locate 2,1: lcd "pausa          ": gosub pausa
'if key=3 then locate 2,1: lcd "stop           ": goto fine_test
'if key=4 then gosub galoppo
Wait 1
'step 4
Cls
Lcd "test #4"
'Waitms 10500                                                'aspetta 10,5 sec.
'Gosub N_off                                                 'disattiva carico N
'Gosub Chiusura3141                                          'apertura1112
'gosub check_key                                 'check tastiera
'if key=2 then locate 2,1: lcd "pausa          ": gosub pausa
'if key=3 then locate 2,1: lcd "stop           ": goto fine_test
'if key=4 then gosub galoppo
Wait 1
'step 5
Cls
Lcd "test #5"
'Waitms 3000
'Gosub R_on                                                  'atttiva il carico R
'Gosub Apertura3141                                          'chiude 1121
'gosub check_key                                 'check tastiera
'if key=2 then locate 2,1: lcd "pausa          ": gosub pausa
'if key=3 then locate 2,1: lcd "stop           ": goto fine_test
'if key=4 then gosub galoppo
Wait 1
'step 6
Cls
Lcd "test #6"
'Waitms 1500                                                 'aspetta 1,5 sec
'Gosub Chiusura3141                                          'apre 1121
'if key=2 then locate 2,1: lcd "pausa          ": gosub pausa
'if key=3 then locate 2,1: lcd "stop           ": goto fine_test
'if key=4 then gosub galoppo
Wait 1
' step 7
Cls
Lcd "test #7"
'Waitms 10500                                                'aspetta 10,5 sec
'Gosub R_off                                                 'disattiva il carico R
'gosub check_key                                 'check tastiera
'if key=2 then locate 2,1: lcd "pausa          ": gosub pausa
'if key=3 then locate 2,1: lcd "stop           ": goto fine_test
'if key=4 then gosub galoppo
Wait 1
Count = Count + 1                                 'incrementa contatore

Toggle Cnt                                        'aggiorna contatore esterno
Waitms 45                                         'aspetta un pò
Toggle Cnt

Locate 2 , 1
Lcd "ciclo n." ; Count;
'If Key = 2 Then Cls : Lcd "pausa          " : Gosub Pausa
'If Key = 3 Then Cls : Lcd "stop           " : Goto Fine_test
'If Key = 4 Then Gosub Galoppo
'If Count >= 75000 Then Goto Fine_test                       'finito il test
Goto Inizio

End                                               'end program

Apertura3141:                                     'con conseguente CHIUSURA 1121
Set Coil_r                                        'eccita la bobina "R"
Waitms 500                                        'alimenta la bobina er 500 ms
'If Ok_r = 0 Then Goto Fine_loop                             'test se scambio avvenuto: 0=non avvenuto ->ALARM!!
'If Ok_n = 1 Then Goto Fine_loop                             'test se scambio avvenuto: 1=non avvenuto ->ALARM!!
Reset Coil_r                                      'spegne la bobina "R"
Return

Chiusura3141:                                     'con conseguente APERTURA 1121
Set Coil_n                                        'eccita la bobina n
Waitms 500                                        'alimenta la bobina "R" per 500 ms
'If Ok_r = 1 Then Goto Fine_loop                             'test se scambio avvenuto: 1=non avvenuto ->ALARM!!
'If Ok_n = 0 Then Goto Fine_loop                             'test se scambio avvenuto: 0=non avvenuto ->ALARM!!
Reset Coil_n                                      'spegne la bobina "R"
Return
'
'R_on:
'Set Load_r
'If Ok_r = 0 Then Goto Fine_loop
'Return

'R_off:
'Reset Load_r
'If Ok_r = 1 Then Goto Fine_loop
'Return

'N_on:
'Set Load_r
'If Ok_n = 0 Then Goto Fine_loop
'Return

'N_off:
'Reset Load_r
'If Ok_n = 1 Then Goto Fine_loop
'Return
'

'sub check tastiera


Fine_loop:
Cls:
Waitms 100
Lcd "*** ALLARME! ***"
Lcd "CONTATTO APERTO!"
Wait 1
Goto Fine_loop

Fine_test:
Cls
Lcd "fine test:>>OK<<"
Lcd "START X RICOM."
'Gosub Check_key
If Key = 1 Then Goto Comincia                     'Fine_test
Goto Fine_test

Pausa:
Key = 0                                           'gestione tasto pausa
If Star_t = 0 Then Waitms 20
If Star_t = 0 Then Key = 1 : Goto Continue        'key=1 inizio/continua test
If Paus_e = 0 Then Waitms 20
If Paus_e = 0 Then Key = 2 : Goto Continue        'key=2 pausa test
If Sto_p = 0 Then Waitms 20
If Sto_p = 0 Then Key = 3 : Goto Continue         'key=3 fine test test
If Bypass = 0 Then Waitms 20
If Bypass = 0 Then Key = 4                        'key=4 al galoppo e poi torna qui

'If Key = 1 Then Lcd "testing"
'If Key = 3 Then Lcd "stop" : Goto Fine_test
Return

Galoppo:                                          'routine per incrementare velocemente in contatore esterno
Count = Count + 1
Toggle Cnt
Waitms 50                                         'aspetta un pò
Locate 1 , 1
Lcd "conteggio n." ; Count;
If Bypass = 0 Then Goto Galoppo
Return

End

fammi cortesemente sapere e grazie per il tuo interessamento
M

Re: dilemma sulla programmazione GOSUB e RETURN

PostPosted: 09 Jun 2014, 09:43
by pier
Immagini tu ti riferisca alla simulazione. Nel pannello di led a dx (quelli verdi) del simulatore sono visualizzati gli stati dei pin. nel tuo caso devi accendere, cliccandoli, i pin IC0,1,2 e 3 per simulare i pin alti (all'avvio della simulazione) altrimenti il simulatore li sente bassi e quindi salta, come dici tu, agli step successivi dopo il primo controllo sullo stato di pinC.0 come se il pulsante fosse premuto.
La simulazione della pressione del pulsante la ottieni ricliccando sul led verde corretto per spegnerlo.
Nessun problema di stack quindi (puoi approfondire l'argomento nell'help).
Per maggior chiarezza e semplicità del codice io userei l'apposito comando debounce (e l'associato config debuonce) al posto degli attuali waitms.

Quando programmerai fisicamente ricorda di eliminare il $sim.

Re: dilemma sulla programmazione GOSUB e RETURN

PostPosted: 09 Jun 2014, 13:59
by mario59
Ciao Pier,
grazie per la tua cortese attenzione.
L'operazione che mi dici di fare, già la facevo ed è nota a me.
Non sapevo, invece, che il problema risiede nell' IF :!: :!: :!:
Infatti, non è possibile nell'IF, includere più di un comando dopo il THEN, :shock: quindi non posso scrivere la riga così come la ho scritta. ma così (ho preso solo tre riche della scansione della tastiera):
...
If Star_t = 0 Then Waitms 20 'debounce
If Star_t = 0 Then Key = 1 : Goto Continue 'key=1 inizio/continua test
........................................^ questa istruzione non viene eseguita mai!!! :!:

e la sostituisco con:
...
If Star_t = 0 Then Waitms 20 'debounce
If Star_t = 0 Then Key = 1 'key=1 inizio/continua test
If Star_t = 0 Then Goto Continue
...

e questa cosa l'ho scoperta per caso, non avendola trovata descritta da nessuna parte...
Su questo aspetto, devo dire, l'HELP del BASCOM è un pò troppo "spartano" per lo meno per me che sono u neofita... :?
Poi, per quanto riguarda gli I/O:
Se io definisco lo stato logico degli output, e abilito il pull-up mi viene correttamente indicato lo stato con il cerchietto rosso... ma perchè se vado a leggere il pin della medesima porta leggo "0" se non lo metto a "1" io a mano???
Non mi sembra corretta stà cosa, per lo meno non è intuitivo.... :roll:
Anche perchè sul micro questo non accade...
Infine con il debounce:
Ho trovato anch'io questa istruzione, ma viste le difficoltà, diciamoci la verità, alquanto stupide che ho incontrato fin'ora, volevo essere sicuro di non andare a "caccia di guai"... :lol: :lol:
Comunque la proverò quanto prima! :mrgreen:
fammi sapere che ne pensi. Grazie e ciao.

Mario

Re: dilemma sulla programmazione GOSUB e RETURN

PostPosted: 09 Jun 2014, 16:12
by pier
Si, effettivamente se vuoi mettere diverse istruzioni dopo un IF devi usare la struttura IF condizione/i THEN istruzioni END IF. Questa modifica l'avevo fatta di default durante i miei test e questo mi ha portato fuori strada. Questo metodo è anche decisamente più elegante di una serie di IF come fai ora.
Per la verità nel tuo modo originario non è che le istruzioni sulla stessa riga non vengono eseguite MAI anzi, ma vengono tutte eseguite ma dalle prove che ho fatto il problema è che il "GOTO continue" (quella dopo i due punti) viene eseguito SEMPRE senza condizionamento da parte dell'IF.
Per il giudizio sull'help condivido e non siamo in pochi.
Per la simulazione anche qui, come dici tu, si dovrebbe "sentire" la configurazione mentre ora è privilegiato il controllo utente.
Il debounce invece è raccomandabile in quanto testa anche che il pulsante non sia premuto e mantenuto così ma richiede prima un ritorno in posizione di riposo prima di accettare una nuova pressione.

Re: dilemma sulla programmazione GOSUB e RETURN

PostPosted: 09 Jun 2014, 20:18
by einstein
come dice pier è possibilissimo inserire + istruzioni dentro IF - End IF, in questo modo:

Code: Select all
IF a=0 then
   istruzione 1
   istruzione 2
   istruzione n..
end if

è molto + elegante e si è sicuri che le istruzioni dentro contenute vengano sempre eseguite

Re: dilemma sulla programmazione GOSUB e RETURN

PostPosted: 10 Jun 2014, 10:22
by mario59
devo vergognarmi... :oops: :oops: :oops:
credetemi non avevo capito a che serviva l' ENDIF.... e che differenza ci fosse con l' ELSE.
Ma questo è dovuto sicuramente alla mia estrazione "BASIC-chiana" , di MOLTI DECENNI FA :? :o , in cui l'IF appunto si comportava in maniera un pò diversa.
Mi è piaciuta molto la spiegazione di EINSTEIN ed ho anche apprezzato il commento di pier. GRAZIE!!! :D :D :D
Infatti anche l'eleganza del codice mi attira sempre, perchè "istintivamente" penso che un codice elegante sia più razionale e funzioni meglio... mah ma forse sono solo fisime mie :cry: !

Però ora vorrei chiedervi una cosa: Ma a voi la simulazione con l'LCD funziona SEMPRE bene? :roll:
No, perchè quando simulo il pgm dopo la terza-quarta volta consecutiva, lo stesso va in pallone e trovo i seguenti problemi:
- La partenza della simulazione non è istantanea, ma parte dopo circa UN MINUTO che ho premuto la freccina :arrow: per far partire la simulazione
- sul display scrive A RILENTO, specialmente quando esegue una istruzione tipo : Lcd "conteggio :"; count . cioè è presente una variabile dopo un dato fisso.
- molte volte addirittura scrive fischi per fiaschi e sembra dislessico.
Tipo Lcd "prova" e scrive "w_*+qei" (si, neanche il numero dei caratteri corrisponde!!!)
Allora, se voglio continuare a lavorare, devo chiudere BASCOM (non solo il simulatore) e riaprirlo.
Ho provato molti pc, ma dappertutto è lo stesso.... :?: :?: :?:
Una vera seccatura ! :evil: :evil:
Succede anche a voi così???

Re: dilemma sulla programmazione GOSUB e RETURN

PostPosted: 10 Jun 2014, 13:16
by pier
Secondo me l'eleganza del codice non è solo una "fisima" ma aiuta nella sua lettura e comprensione.
Per quanto riguarda la simulazione "ballerina", occasionalmente capita anche a me (win7 pro).
In genere mi basta chiudere il simulatore (cosa che raccomando di fare sempre anche solo per passare alla scheda dell'editor. Raccomando anche di terminare una simulazione prima di chiudere la schermata con il pulsante "stop program" e, sarà solo scaramanzia, pongo sempre il cursore all'inizio del codice prima di un eventuale riavvio di simulazione). Nei casi più gravi anche a me è capitato di dover riavviare completamente il Bascom ma, ripeto, mi succede molto raramente e non ti so dire se quando avviene abbia o meno altri programmi particolari aperti.

Re: dilemma sulla programmazione GOSUB e RETURN

PostPosted: 10 Jun 2014, 21:03
by deluca
Salve a tutti e scusate se mi intrometto solo adesso, ma sono stato impegnatissimo con il lavoro...

ok, se il compilatore risulta essere abbastanza efficiente, purtroppo, e ne devo dare atto, il simulatore ha qualche pecca. Per questo motivo si sta cercando di ottimizzare il codice per eseguire una simulazione più realistica ed esente da bachi. Ho usufruito veramente poco del simulatore integrato che MCS mette a disposizione,
poichè, usando svariati tools per diverse famiglie di micro, ho necessariamente dovuto simulare i circuiti con diversi external-tools-simulator commerciali che macinano direttamente i bin/hex già compilati. Capisco che il simulatore non è efficientissimo ma in qualche modo, senza spendere alcun euro in più, permette a chiunque di testare semplici programmi.

@mario, ho simulato il tuo codice ed il sim parte istantaneamente. non ho ben intercettato il funzionamento nella sua completezza ma ovviamente l'uso dei pulsanti risulta essere molto ostica...
In genere conviene testare il codice attraverso la porta seriale.... o usando eventualmente gli Int....
I pulsanti rappresentati nel simulatore dai led, non sono molto efficienti.

Re: dilemma sulla programmazione GOSUB e RETURN

PostPosted: 11 Jun 2014, 08:51
by pier
Concordo assolutamente con Deluca. A parte piccoli quanto occasionali intoppi e qualche piccola scomodità, il simulatore di MCS è utilissimo e semplicissimo da usare. Visto il costo poi.....
Io lo uso costantemente e non potrei farne a meno.
Per eventuali simulazioni di pulsanti o altro di input uso la simulazione step by step che mi consente di intervenire al momento opportuno sul pannellino di led relativo agli input.
Se in futuro verrà un simulatore ancora migliore saremo ancora più felici sperando che l'utilizzo rimanga parimenti semplice

Re: dilemma sulla programmazione GOSUB e RETURN

PostPosted: 12 Jun 2014, 16:32
by mario59
Salve a tutti!
Accomunare le esperienze, per me, è una cosa bellissima e SERISSIMA, che mi permette di capire se non mi sto perdendo in un bicchiere d'acqua oppure sto navigando in alto mare... :P
Comunque torno con un altro "fagotto" di problemini... ma cominciamo con ordine:
1) i bits D0 e D1 di arduino non riesco a farli "muovere" similmente a come ho fatto per PORTC bit 4 e 5; pur essendo la istruzione identica (set, reset)
2) agli stessi pins ho attaccato una scheda con otto relay, quella standard per arduino ed ho un comportamento strano.
la scheda è questa :http://www.dx.com/p/8-channel-5v-solid-state-relay-module-board-red-blue-121337#.U5nGTHJ_tGY
i primi due relè li piloto con le uscite PORTC bit 4 e 5: no problem.
i seguenti due relè li piloto con le uscite PORTD bit 0 e 1 e qui nascono i problemi... :cry:
lo stato logico di questi due pins va a 3V e MAI a 5V e quindi il relè corrispondente risulta SEMPRE eccitato
se stacco le uscite di arduino i due pins vanno a 5V regolarmente.
Inutile dire che in simulazione i bits si muovono regolarmente, la differenza la trovo nella realtà...ovviamente!!!
:?: :?: :?: :shock: :o :?: :?: :?: perchè?
qualcuno saprebbe indicarmi cosa sta succedendo? :ugeek: :ugeek: :ugeek:

Re: dilemma sulla programmazione GOSUB e RETURN

PostPosted: 12 Jun 2014, 17:24
by pier
Il discorso non mi è chiaro.
D0 e D1 si muovono correttamente in simulazione?
Desumo problemi HW. Senza schema della scheda relè è difficile capire ma parrebbe un problema di carico.
Input a logica negativa?
Quando dici che staccando Arduino il livello passa da 3 a 5V parli degli input della scheda o degli output di Arduino?
Non conosco Arduino ma vedo che questi pin sono dedicati alla comunicazione per la programmazione. Non vorrei che questa configurazione rimanesse tale anche durante l'esecuzione del programma....
Hai controllato la configurazione di questi pin? Certo che se in simulazione sono ok....

Infine mi pare che l'argomento ora si sia discostato parecchio dal titolo del post. Forse sarebbe meglio aprirne uno adatto.