Se sei già registrato           oppure    

Orario: 19/03/2024 03:44:32  

 

Energia Alternativa ed Energia Fai Da Te > PPTEA

Pagine: (2)   [1]   2    (Ultimo Msg)


La Guida Galattica al PPTEA per autostoppisti!, Ovvero, siamo tutti principianti... e la documentazione ci annoia!
FinePagina

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 15/2/2013,17:54

faccine/unsure.gif Capitolo 1, a che serve?
La Guida Galattica, intendo... beh, ad imparare ad usare il PPTEA senza sorbirsi la noiosissima documentazione a corredo... in fondo, a che serve sapere usare i vettori, se col PPTEA ci voglio accendere un led? E allora, cominciamo... Ma nel capitolo 2, che già mi sono stancato a scrivere... faccine/smile.gif

P.S. Dato che voglio che questa sia una guida e rimanga pulita, vi prego di postare i vostri commenti nella apposita discussione "Commenti alla Guida Galattica"... quelli già presenti saranno spostati la... quelli negativi saranno misteriosamente inceneriti... faccine/wink.gif

Darò a questa guida un carattere molto "leggero", sia per non cadere nel noioso, sia per non annoiarmi io... Non intendo con questo offendere nessuno, dando toni scherzosi alla questione. Programmare non è facile, farlo bene ancora meno, insegnarlo è difficilissimo... non sto prendendo in giro nessuno, ne chi sa programmare, ne chi non lo sa ancora fare, ne chi lo insegna... Io, non sono in nessuna delle tre categorie... il PPTEA lo USO, ho delle basi arcaiche e lacunose di programmazione BASIC e Pascal, ma posso dedicare qualche tempo a questa cosa. Buon divertimento!




Modificato da MarKoZaKKa - 15/2/2013, 20:05


---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 15/2/2013,19:04

faccine/rolleyes.gif Capitolo 2: il PPTEA, a che serve?
Il PPTEA è un microcontrollore della famiglia PICMicro (ovvero un circuito integrato o IC che contiene al suo interno quattro dozzine di oggetti che, sinceramente, non mi interessano), che un'elettricista fulminato e megalomane in cerca di fama fortuna e gloria ha dotato di un "firmware", ovvero di una programmazione, che rende accessibile il suo utilizzo a tutti coloro siano in grado di programmare, senza curarsi di tutti quegli acchrocchi che si trovano al suo interno, utilizzando una sua personale versione del BASIC, che come dice il nome è un linguaggio di programmazione di base, rendendo tanto banale la cosa che quasi mi vergono a farci una guida sopra...

Dando per scontato che se stai leggendo questa guida, è inutile che ti spieghi come si installa il firmware, come si accende e cosa si collega al PPTEA per farlo funzionare, perchè probabilmente hai la tua bella scheda PPTEA/KSB nuova fiammante che avrai comprato pagandola profumatamente al sottoscritto e che stai guardando come Amleto guardava il teschio del suo precettore (?!?), o forse è il contrario (è il PPTEA che guarda te, sperando in un tuo segno di vita) iniziamo a parlare dell'I/O (input/output; ingresso/uscita)

Il PPTEA ha 16 linee di I/O configurabili, ovvero che possono essere impostate ciascuna come Input (ingresso) oppure Output (uscita) digitale... no, non devi mettere il dito li... uffa! Intendo dire che ogni linea impostata come Output può assumere uno stato ALTO (il PPTEA porterà la tensione di quella linea a circa +5Vdc) oppure uno stato BASSO (la tensione sarà prossima a 0Vdc) come comandato dal programma in esecuzione; se impostata come Input, sulla base della tensione presente sulla linea, verrà considerata come stato logico ALTO (se la tensione applicata dall'esterno sarà prossima a +5Vdc) oppure BASSO (se la tensione sarà prossima a 0Vdc) ed il programma potrà eseguire comandi diversi sulla base di questo stato.

Bene, ma a che serve il PPTEA? Fondamentalmente a farti spendere soldi in maniere che non avresti neppure immaginato... ad esempio ad accendere la luce della tua cantina mentre ti trovi in giardino usando un pulsante che prima (del PPTEA) accendeva le luci del giardino ed ora, con una modica spesa, accende due luci diverse...
Oppure, a comandare l'irrigazione dello stesso giardino, quando ci sono gli ospiti, cosa che avresti fatto con 20euro di programmatore orario cinese preso al brico del centro commerciale. Un simpatico effetto collaterale del PPTEA è che tua moglie avrà un motivo in più per essere "furiosa" con te...

Al prossimo capitolo...



---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 15/2/2013,19:39

faccine/ohmy.gif Capitolo 3: Il mio primo programma...

Per fare un programma, innanzitutto serve un problema da risolvere con un programma... il fatto che poi il programma crei problemi nuovi, è totalmente irrilevante. Il mio problema è: accendere un LED. Soluzione: collega il LED ad una pila. Il programma deve dividere questa semplice azione in passi ancora più semplici, che eseguiti in sequenza, mi portino al risultato.
Programma:

1) prendi un LED
2) prendi una pila
3) metti un piedino del led sul "+" della pila
4) metti l'altro piedino sul "-" della pila
5) il led si è acceso? se si, vai al punto 8), se no, vai al punto 6)
6) inverti i piedini del LED, girandolo
7) vai al punto 5)
8) il led è ancora acceso? se si, vai al punto 13), se no vai al punto 9)
9) scrivi su un postit "led bruciato"
10) attacca il postit al led
11) butta il led nei rifiuti RAEE
12) vai al punto 1)
13) scrivi su un postit "led funzionante"
14) attacca il postit al led
15) fine

Ecco fatto. Abbiamo risolto un problema dividendolo in passi... sembra che tutto funzioni... ma è proprio così? Qualcuno potrebbe dire che questo è un programma per bruciare i led, non per accenderli. Vi posso assicurare che si accendono di luce vivissima, e cambiano pure colore, prima di bruciare... ma se il led fosse già bruciato prima che io lo colleghi alla pila senza resistenza, bruciandolo? Rimarrei "inlooppato" (bloccato in un loop) sulle istruzioni 5...7... Ecco, al primo programma abbiamo già creato un "bug" e lo abbiamo pure scoperto...
Come? volevate fare un programma per il PPTEA? Ma se non sapete nemmeno accendere un led senza bruciarlo!



---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 17/2/2013,01:08

faccine/huh.gif Capitolo 4: Il mio primo programma per il PPTEA
Innanzitutto, dove lo scrivo il programma? Anche su un pezzo di carta della focaccia, il problema è che se ungi il PPTEA non è che vada più veloce... meglio usare l'apposito COMPILER che hai provveduto a scaricare senza sapere cosa sia, e che hai installato seguendo il manuale, prima di fermarti davanti alla sua schermata bianca appena lanciato...
Quella pagina bianca è il posto giusto per scrivere il tuo primo programma per il PPTEA. Bene, abbiamo ancora il problema del LED
da risolvere... sappiamo che il PPTEA ha 16 I/O... sappiamo che possiamo configurarli... come si fa?
Torniamo al nostro LED: dobbiamo decidere a quale linea di I/O del PPTEA lo collegheremo... direi alla numero 15, tanto per fare qualcosa di eccentrico... Inoltre, vogliamo che il LED si accenda quando la linea è a livello ALTO, oppure quando è a livello BASSO? Dato che sono sbarazzino, voglio che si accenda quando la linea si trova a livello ALTO...
Pertanto, colleghiamo il nostro LED con l'anodo alla linea 15 del PPTEA, il catodo ad uno dei terminali di una resistenza da 1KOhm, e l'altro terminale a massa... no, non il pilota di F1, intendo il negativo dell'alimentazione... come? non sapete quale sia l'anodo e quale il catodo? Allora, fate così... collegate il terminale del LED al positivo di alimentazione invece che al PPTEA, se si accende, l'anodo è quello, altrimenti girate il led e riprovate, poi ricollegatelo alla linea 15.
Adesso, iniziamo a scrivere qualcosa nel compiler. La prima istruzione sarà:


10 SETIO=&B0111111111111111


Dire che non c'è bisogno di spiegazioni... SETIO dice al PPTEA come voglio impostare le sue linee, &B indica che voglio usare la notazione binaria, le sedici cifre indicano quali linee voglio impostare come uscite (0) oppure ingressi (1), a partire dalla linea 15, quella più a sinistra, per arrivare alla linea 0, quella più a destra. Se ad esempio avessi voluto impostare le linee da 0 a 7 come ingressi, e le altre come uscite, avrei scritto:


10 SETIO=&B0000000011111111


Bene, ora che abbiamo detto al PPTEA quali devono essere le linee di uscita e quali di ingresso, dobbiamo dire al PPTEA di impostare la linea alla quale abbiamo collegato il LED al valore ALTO, in modo da accenderlo. Useremo pertanto un'altra istruzione:


20 OUTBIT(15)=HIGH


Possiamo anche scrivere "1", oppure "TRUE" oppure "ONE" al posto di "HIGH"... l'effetto sarebbe lo stesso, il nostro bravo elettricista ha deciso di confonderci le idee permettendoci di dire in quattro maniere diverse la stessa cosa...
Bene, il led è acceso... e adesso? Sarebbe carino farlo pure spegnere... e come si fa? Bravi, sempre con la OUTBIT... basta dire che adesso vogliamo la linea 15 a livello BASSO, quindi:


30 OUTBIT(15)=LOW (oppure "0", oppure "FALSE", oppure "ZERO"


Ok, abbiamo acceso, abbiamo spento... direi che possiamo fermarci:


40 END


E adesso come facciamo a vedere se il nostro programma funziona? Avrete sicuramente notato che si sono attivati i menù "Save" e "Compile"... Innanzitutto, salviamo questo complicatissimo programma, sennò ci tocca riscriverlo; poi, dobbiamo "Compilarlo", ovvero far eseguire un controllo di correttezza e successivamente una "traduzione" nel linguaggio del PPTEA, facendo click su "Compile". La parte bassa della finestra mostrerà alcuni messaggi di alcun'interesse, ed una barra che ci indica se è tutto OK (colore verde) e quanta memoria del PPTEA stiamo utilizzando.
A questo punto, se avete scritto tutto correttamente, vedrete una piccola barra verde in basso, ed in alto si sarà attivata anche la voce "Debug". Facciamo click li sopra, ed attiviamo il "Debugger". Qui possiamo far funzionare il nostro programma come se fosse già dentro al PPTEA, vedere cosa succede, fermarlo e farlo ripartire, oppure farlo avanzare una riga alla volta, in maniera da capire dove è il baco che non lo fa funzionare correttamente. Basta fare click su "RUN" per fare partire l'esecuzione simulata. Fatto? Cosa avete visto? Nulla? Vi siete fatti distrarre dalla barra blu che si muove, vero? Guardate nell'area "I/O", in particolare il bit 15 e rifate click su "RUN"... visto? è apparsa un'attimo una "v" nel quadratino, e poi è scomparso... Se spostate il cursore "Speed" verso "Slow", rallenterete l'esecuzione, e capirete meglio cosa accade ad ogni singola istruzione. Certo, però è una tristezza... un led si accende e subito si spegne... sarebbe meglio che lampeggiasse... come fare... potremmo scrivere righe e righe di OUTBIT, ma prima o poi finiremmo la memoria del PPTEA... Bisognerebbe poter far tornare indietro il programma... ma certo, con il GOTO, che stupido! Facciamo click su EXIT DEBUG, e modifichiamo la linea 40:


40 GOTO 20


diciamo così al PPTEA di ritornare alla linea 20 e riprendere da li l'esecuzione. Rifacciamo Save, Compile, Debug, Run... e vediamo che il nostro bel "v" appare e scompare e appare e scompare e appare... A questo punto, vi potrei far trasferire il codice al PPTEA, per poi sentirvi esclamare stizziti "Ma è sempre acceso!!!"... invece, vi dico ancora una cosetta... vista la velocità di esecuzione delle istruzioni da parte del PPTEA, la durata del ciclo sarebbe così breve da darvi l'impressione di un led sempre acceso. Dobbiamo aggiungere due righe, che ci permettono di "rallentare" il PPTEA:


25 WAITMS 500
35 WAITMS 500


l'istruzione WAITMS permette di inserire una pausa (WAIT) nell'esecuzione di tot millisecondi; noi stiamo inserendo due pause di 500 millisecondi, immediatamente dopo l'accensione e dopo lo spegnimento del LED; l'effetto sarà quello di lasciare il LED acceso per 500ms, poi lasciarlo spento per altri 500ms e così via... Provare per credere, sapete già cosa fare.
Adesso potremmo trasferirlo al PPTEA, ma dopo tutte queste spiegazioni, sono stanco e vado a nanna...
Al prossimo capitolo.




Modificato da MarKoZaKKa - 16/4/2013, 11:15


---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 18/2/2013,21:26

faccine/sick.gif Capitolo 5: Il mio primo programma per il PPTEA è una m&®Ð@

Avete fatto, vero? Vi siete andati a leggere nella documentazione come si trasferisce il codice EABasic al PPTEA, lo avete fatto, siete stati li un pò a vedere il vostro led che faceva ACC...SPENT...ACC...SPENT... poi vi siete detti "che mer...enda di programma..." In effetti, è veramente una schifezza... per 1,50€ vi compravate un led lampeggiante che faceva già tutto... Rendiamo la cosa più interessante... usiamo anche un'input, e facciamo in modo che se l'ingresso è ALTO il led lampeggia, e viceversa. Rivediamo il nostro codice in tutto il suo splendore:


10 SETIO=&B0111111111111111
20 OUTBIT(15)=HIGH
25 WAITMS 500
30 OUTBIT(15)=LOW
35 WAITMS 500
40 GOTO 20

Prendiamo una linea qualsiasi, la 14 ad'esempio, è già configurata come input... Come possiamo modificare il codice per gestire lo stato della linea? Innanzitutto, l'istruzione che ci serve è la INPBIT(n) che restituisce lo stato della linea n (che deve essere configurata come input...). Allora, deve essere dentro al ciclo perchè dobbiamo controllarla prima di decidere se far lampeggiare il led, e farlo ad ogni ciclo per fermarci quando il suo stato cambia. Quindi, se 14 è ALTA, lampeggio, altrimenti, aspetto che diventi alta. L'istruzione che ci serve è il cosiddetto "SALTO CONDIZIONALE" (OOOOoooohhhhh!!!! fà la folla, rullo di tamburi, OOOOOOpla!) ovvero una istruzione che, al verificarsi di una condizione, ci manda in un posto oppure in un'altro... un pò quello che succede con le donne, solo che in quel caso, loro non sanno quale sia la condizione (1 pragma misogino_mode=off)
La struttura dell'istruzione è questa:

IF condizione_da_verificare_è_vera THEN riga ELSE altrariga
SE condizione_da_verificare_è_vera ALLORA vai alla riga ALTRIMENTI vai all'altra riga

La parte di istruzione ELSE altrariga è facoltativa, se serve si usa, altrimenti si può non scriverla.
Tornando al nostro LED, io farei così:

15 IF INPBIT(14)=HIGH THEN 20 ELSE 15

Ma potrei anche fare così:

15 IF INPBIT(14)=LOW THEN 15

oppure

15 IF INPBIT(14)=FALSE THEN 15

risparmiando ben 1 token, eliminando l'ELSE; dato che ne abbiamo 256 disponibili nel PPTEA, se il programma è lungo e con molti salti, ciò si traduce in un bel risparmio di memoria... come? cos'è un token? Perdincibacco! il token è l'unità minima di memoria programma del PPTEA... Il PPTEA senza espansione di memoria ha 256token di memoria... vabbè che il manuale è noioso, ma se lo leggete, evito di perdere tempo in quisquilie... torniamo all'IF và...

Potrei pure scrivere:

15 IF !INPBIT(14) THEN 15

Chi me la spiega? Si... lei, signorina Grace Arkansas... si.. bene... brava... come dice? La linea 40? Ah,si, è vero, mi sono scordato di dirlo... capito tutti? Bene, proseguiamo. Quindi adesso il nostro programma aspetterà che la linea 14 sia ALTA per iniziare a lampeggiare, e lo farà fino a che non tornerà bassa. Dato che siete stati così bravi a trasferire il primo programma, trasferitevi sul PPTEA anche questo, e vedete che accade. Si, la linea 14 la potete collegare ai +5V o a massa direttamente, senza resistenze...

Al prossimo capitolo...




Modificato da MarKoZaKKa - 16/4/2013, 11:17


---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 25/2/2013,17:33

Capitolo 6: Un, due, tre... stella!

Bene, il led ora lampeggia a comando, o meglio lampeggia fino a che gli diamo il comando...Pensiamo invece ad una cosa un pò più
raffinata, un led che si accende quando arriva il comando su una linea, e si spegne quando il comando arriva su un'altro input...
avete qualche idea? Innazitutto, teniamo buona la configurazione degli i/o, dato che già abbiamo quanto ci serve... cambio solo la
notazione, perchè quella bitmap mi stressa... conoscete tutti la numerazione esadecimale, vero? No? peccato... lasciando perdere
la matematica che sta dietro (nascosta e con un randello in mano), per quanto ci interessa ora, possiamo solo dire alcune cose: la
numerazione decimale utilizza 10 simboli per comporre i numeri (0,1,2,3,4,5,6,7,8,9), quella esadecimale ne usa 16
(0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F), quella binaria ne usa due (0,1)... per i nostri scopi, possiamo dire che usare la notazione
esadecimale permette di esprimere un numero binario in maniera più compatta ed immediata: vediamo una tabellina di equivalenza tra le varie notazioni...

CODICE
binario           esadecimale      decimale
bin                 hex                    dec
00000000      00                     0
00000001      01                     1
00000010      02                     2
...
00001001      09                     9
00001010      0A                     10
00001011      0B                     11
00001100      0C                     12
00001101      0D                     13
00001110      0E                     14
00001111      0F                     15
00010000      10                     16
...
11101110      EE                     238
11101111      EF                     239
11110000      F0                     240
11110001      F1                     241
...
11111010      FA                     250
11111011      FB                     251
...
11111110      FE                     254
11111111      FF                     255

notate che per passare da un numero espresso in binario alla notazione esadecimale, è in pratica sufficiente imparare a memoria la corrispondenza tra cifra hex e combinazione di 4 bit, mentre per passare da bin a dec bisogna eseguire dei calcoli. In più, passando da numeri a 8bit a numeri a 16bit, il metodo non cambia; si prendono i bit a 4 a 4 e si sostituiscono con la cifra hex corrispondente. Quindi la nostra SETIO espressa in hex sarà:

10 SETIO=&H7FFF

Meglio, no? Bene, abbiamo il led sul bit15, un input sul bit14, usiamo il bit13 per l'altro input, e diciamo che se il bit14 va H (alto) il led si accende e rimane acceso, se il bit13 va H il led si spegne e rimane spento. Quindi il nostro programma diventerà:

10 SETIO=&H7FFF
20 IF (INPBIT(14)=LOW AND INPBIT(13)=LOW) THEN 20
30 IF INPBIT(13)=LOW THEN 50
40 GOTO 80
50 IF INPBIT(14)=LOW THEN 70
60 GOTO 110
70 GOTO 20
80 OUTBIT(15)=LOW
100 GOTO 20
110 OUTBIT(15)=HIGH
130 GOTO 20

Come dite? non capite la riga 20? beh, non è sicuramente colpa vostra se non stavate attenti a sQola... Allora, ricordate come funziona l'IF...THEN? Bene, in questo caso, la condizione da verificare è più complessa, e dovrò parlare di OPERATORI LOGICI... ma lo farò nel prossimo capitolo, intanto imparatevi la corrispondenza tra hex e bin...

Capitolo 7: to Be OR NOT to Be?
Allora, conosciamo bene nel nostro linguaggio il significato di quelle paroline che non ricordo come si chiamano (perchè IO stavo attento, quando c'erano le materie tecniche... me la viaggiavo durante le lezioni di italiano e storia) e che sono "E", "O", "NON". Bene, ci fu un tale di nome Boole che, avendo evidentemente molto tempo libero e campando di rendite immobiliari, si inventò l'algebra dei numeri binari, e da quel momento il mondo non fu più lo stesso. In parole mooOoolto semplici, se A e B sono proposizioni semplici (oh, mamma...) che possono essere ciascuna o VERA o FALSA, esse possono essere combinate tra loro con degli operatori per ottenere una proposizione complessa che a sua volta potrà essere VERA o FALSA. Gli operatori che individuò sono AND ("E", OR ("O", NOT ("NON". Per farla breve e capirci qualcosa, si possono scrivere le cosiddette "Tavole della verità" (no, i testi sacri non c'entrano) degli operatori:

CODICE
A        B       (NOT A)    (A AND B)    (A OR B)
f         f          v               f                 f
f         v         v               f                 v
v        f          f                f                 v
v        v         f                v                 v


Vediamo quindi che NOT A è vero quando A è falso (e che scoperta, se non piove e io dico "piove", o sono pirla o sto mentendo...), che A AND B è vero solo quando sia A che B sono veri, che A OR B è vero quando almeno una tra A e B è vera. Sia l'operatore AND che l'operatore OR possono operare su più operandi (operbacco!), ed esistono delle regole noiosissime che permettono di calcolare espressioni che contengono combinazioni di AND, OR e NOT, ma non ho nessuna intenzione di spiegarvele...
Vi faccio solo l'esempio della disuguaglianza logica, ovvero una espressione il cui valore è VERO solo se uno solo degli operandi è vero, e falsa in tutti gli altri casi:

CODICE
A        B        (A AND (NOT B)) OR ((NOT A) AND B)
f         f           f
f         v          v
v        f           v
v        v           f


Questa espressione è tanto utile che viene normalmente indicata con il nome di XOR; pertanto A XOR B = (A AND (NOT B)) OR (NOT A) AND B). Quando poi un'altro tizio di nome Shannon intuì che l'algebra di Boole ed i circuiti commutatori avevano molto in comune, il mondo fu definitivamente diverso...
Tornando al nostro codice, adesso la capite la riga 20? Se entrambi gli ingressi sono bassi, il programma rimane sulla riga 20, appena uno và alto, l'esecuzione prosegue; a questo punto si verifica quale delle linee è andata alta, e lo faccio controllando quale è rimasta bassa (perchè mi piace complicare le cose semplici, anni di esperienza all'UCAS :-) ), e si esegue l'operazione appropriata. Questo codice, pur facendo quanto ci siamo proposti, ha alcuni piccoli problemini, che però vedremo nel prossimo capitolo...




Modificato da MarKoZaKKa - 16/4/2013, 11:20


---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 4/3/2013,13:14

faccine/cry.gif Capitolo 8: al peggio non c'è limite!

Mentre è molto difficile migliorare qualcosa, e più lo si migliora, più è difficile migliorarlo ancora, per peggiorare qualcosa che funziona ci vuole un'attimo.
Il codice visto nell'ultimo esempio, è già funzionante, fà quello che ci siamo proposti, però ha IMHO ancora due punti di miglioramento possibili:

1) si può ottimizzare il codice, rendendolo più "leggero" in terini di token occupati
2) se dallo stato bit13=H, bit14=H si passa allo stato bit13=L, bit14=H, l'uscita va immediatamente alta. Se questo fosse il comando di una macchina, in caso di blocco del comando di start, si rischierebbe di stoppare e far ripartire immediatamente la macchina non appena si levasse il dito dal pulsante di stop.

Punto 1: dato che le condizioni lavorano sullo stato "L" degli input, è possibile ottimizzarle con l'uso dell'operatore NOT, nell'EABASIC, basta anteporre un "!" all'operando, così

10 SETIO=&H7FFF
20 IF (!INPBIT(14) AND !INPBIT(13)) THEN 20
30 IF !INPBIT(13) THEN 50
40 GOTO 80
50 IF !INPBIT(14) THEN 70
60 GOTO 110
70 GOTO 20
80 OUTBIT(15)=LOW
100 GOTO 20
110 OUTBIT(15)=HIGH
130 GOTO 20

Inoltre, è possibile eliminare la riga 20, senza modificare il funzionamento del codice.

Punto 2: per evitare questo problema, una delle strade possibili potrebbe essere quella di imporre il ritorno allo stato bit13=L, bit14=L prima di riprendere a controllare lo stato delle linee:

10 SETIO=&H7FFF
20 IF !(!INPBIT(14) AND !INPBIT(13)) THEN 20
30 IF (!INPBIT(14) AND !INPBIT(13)) THEN 30
40 IF !INPBIT(13) THEN 60
50 GOTO 90
60 IF !INPBIT(14) THEN 80
70 GOTO 110
80 GOTO 20
90 OUTBIT(15)=LOW
100 GOTO 20
110 OUTBIT(15)=HIGH
120 GOTO 20

vedete però che così, abbiamo perso la possibilità di portare il bit15 basso anche in presenza di bit13 alto... quindi se si bloccasse il famoso pulsante di start, stavolta non avremmo possibilità di stoppare la macchina, se non togliendo alimentazione...
A questo punto, occorre una bella boccata d'aria fresca, distrarsi un poco, per poi tornare a pensare al nostro problema:

se ho bit14 alto e bit13 basso, devo portare alto bit15
se ho bit13 alto, devo portare bit15 basso, e lasciarlo così indipendentemente da cosa succede a bit14.

dopo profonda riflessione, otteniamo questo:

1 SETIO=&H7FFF
2 IF (INPBIT(14) AND !INPBIT(13)) THEN 42
3 IF INPBIT(13) THEN 6 ELSE 2
4 OUTBIT(15)=HIGH
5 GOTO 2
6 OUTBIT(15)=LOW
42 IF (INPBIT(14) OR INPBIT(13)) THEN 42 ELSE 2

Azz... meno righe e pure meno token rispetto alle versioni precedenti... e funziona pure meglio!!!
In effetti, la risposta a tutto è la riga 42 faccine/wink.gif
Al prossimo capitolo... se ci sarà...




Modificato da MarKoZaKKa - 16/4/2013, 11:21


---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 2/4/2013,11:19

faccine/angel1.gif Capitolo 9: convertiamoci col PPTEA

Bene, dopo aver giocato con gli I/O digitali del PPTEA, passiamo a parlare dei suoi ingressi analogici. Ma prima di questo dobbiamo parlare dei Convertitori Analogico/Digitale, ovvero di quei circuiti che permettono di convertire una grandezza elettrica (solitamente una tensione) in un numero binario ad n bit. Vi sono varie metodologie costruttive e tecniche raffinate per realizzare un ADC che sia più o meno veloce, preciso e lineare, e di sicuro non mi metterò a spiegarvi quali; per i nostri scopi è sufficiente capire come funziona un ADC.
Allora, immaginiamo il nostro segnale che vogliamo digitalizzare; si tratta di una rampa che aumenta linearmente tra 0 e 5V, per poi tornare a zero. Se lo inviamo all'ingresso di un ADC a 4bit, questo lo convertirà in un numero tra 0 e 15, e spero sia chiaro a tutti perchè... ecco, lo sapevo, encefalogramma piatto... allora se abbiamo 4 bit, le possibili combinazioni saranno 2^4 (perchè abbiamo 2 simboli, "0" e "1", elevato alla 4 potenza perchè abbiamo quattro "posizioni" da usare per le combinazioni... se non ci credete, come vi ho già detto in passato, andate a cercare la matematica che se ne sta sempre lì dietro, nell'ombra, pronta con il randello) ovvero 16 combinazioni, di cui la prima sarà "0000" e l'ultima "1111"... e come sappiamo, il numero binario "1111" equivale a 15 in decimale. Di quanto dovrà aumentare il segnale perchè l'uscita binaria dell'ADC aumenti di 1? Lo otteniamo vacendo la seguente operazione:

5V (massima escursione del segnale) / 15 (massimo numero binario) = 0,3333333333333...V

Quindi, ogni volta che il segnale in ingresso aumenterà di circa 0,333V, avremo un incremento di 1 del numero binario in uscita; quindo la nostra rampa continua tra 0 e 5V, verrà trasformata in una rampa di gradini binari, ciascuno dei quali equivarrà ad un range di valori dell'ingresso:

out binario input tensione
0000 da 0 a 0,333
0001 da 0,333 a 0,666
0010 da 0,666 a 0,999
...
1110 da 4,333 a 4,666
1111 da 4,666 a 5

Avrete sicuramente capito che per avere una maggiore raffinatezza di conversione, bisogna aumentare il numero di bit del convertitore. Per quanto riguarda il PPTEA, i cinque convertitori a/d di cui è dotato, chiamati CAD, restituiscono valori binari a 10bit per segnali di ingresso tra 0 e 5V; dato che 10bit->1024combinazioni->1023 intervalli, avremo una risoluzione di 5V/1023=0,0048875855327468230694037145650049V, ovvero poco meno di 5mV.

Vediamo come utilizzare i CAD nel nostro codice. Innanzitutto, dobbiamo dire quali sono le linee di I/O che possono essere usate come ingressi analogici: sono i bit 0,1,2,3,5 corrispondenti ai pin 2,3,4,5 e 7 del circuito integrato PIC18F2550 con il firmware PPTEA a bordo. Abbiamo una istruzione che ci consente di dichiarare quanti CAD vogliamo usare nel codice, e si tratta della istruzione CADS:

CADS=0 nessun I/O configurato come ingresso analogico
CADS=1 bit0 configurato come ingresso analogico
CADS=2 bit0 e bit1 configurati come ingresso analogico
...
CADS=5 bit0, bit1, bit2, bit3, bit5 configurati come ingressi analogici

E'importante sapere che nel debugger, l'istruzione CADS= prevale sulla SETIO, quindi se scrivo

10 CADS=5
15 SETIO=&H0000

oppure

10 SETIO=&H0000
15 CADS=5

nonostante siano in conflitto (la SETIO definisce tutti i bit come uscite, la CADS= ne definisce 5 come ingressi analogici) il risultato sarà sempre quello di avere 5 CAD configurati, indipendentemente dall'ordine in cui sono state scritte, anche se la logica vorrebbe che nel primo caso, definendo prima gli ingressi analogici e poi dichiarando tutti i bit come output, o il compilatore mi restituisce un warning, oppure prevale l'ultima istruzione... non ho mai fatto esperimenti in merito, per verificare che la stessa cosa avvenga in hardware, bisognerebbe chiedere lumi al cappellaio, pardon, elettricista matto... comunque, la seconda sintassi non dovrebbe dare problemi, quindi prima la SETIO e poi la CADS=, si sa mai...
Perfetto, ora non rimane che sapere come fare a leggere il valore binario corrispondente alla tensione applicata al CAD che ci interessa. A questo ci pensa l'istruzione CADSx dove x è il numero (da 1 a 5) del convertitore che vogliamo leggere, quindi CADS1 per il primo, CADS2 per il secondo e così via. Abbiamo anche una sintassi diversa, utile ad esempio per leggere i convertitori in un ciclo for...next, che è la CADSIND(x) dove la x puo essere una variabile che, ovviamente, deve assumere valori interi da 1 al massimo dei CADS configurati.

Visto che abbiamo già un bel programmino funzionante, perchè non sfruttarlo? Sostituiamo i due ingressi digitali con due ingressi analogici, e vediamo cosa accade...

10 SETIO=&H7F00
15 CADS=2 'configuro bit0 e bit1 come input analog
20 IF CADS1>=512 AND CADS2<512 THEN 40 'se bit1>2,5V e bit2>2,5V, uscita va HI
30 IF CADS2>=512 THEN 60 ELSE 20 'se bit2>2,5V uscita va LOW
40 OUTBIT(15)=HIGH
50 GOTO 20
60 OUTBIT(15)=LOW
70 IF (CADS1>=512 OR CADS2>=512) THEN 70 ELSE 20 'se bit1 oppure bit2 sono >2,5V, rimango sulla linea

Come funziona il programma, già lo sappiamo; abbiamo solo che ora vi è una soglia di commutazione per i due ingressi, pari al valore binario 512, ovvero 5V/1023*512=2,5V circa, per cui se la tensione applicata all'ingresso è inferiore a 2,5V tutto funziona come nel caso precedente di ingresso digitale LOW, se è uguale o superiore, funziona come nel caso prededente di ingresso digitale HI. Nel compiler, potete usare i cursori per simulare l'ingresso analogico e vedere il funzionamento; in hardware, dovete collegare un potenziometro con il cursore sull'ingresso analogico, un estremo ai 5V e l'altro a massa:

5V
|
|
X
X
X
X<--- CAD
X
|
|
GND

Posso anche assegnare il valore del CADS ad una variabile, con la sintassi X=CADS1 oppure X=CADSIND(Y); in questa maniera "congelero" la lettura dell'ingresso analogico nella variabile, al momento dell'esecuzione della riga.

Al prossimo capitolo, che è ora di nanna...




Modificato da MarKoZaKKa - 16/4/2013, 11:22


---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 12/4/2013,08:54

faccine/wub.gif Capitolo 10: CADS & The Measure...

Ora che siamo entrati nel favoloso mondo della conversione A/D sul PPTEA, vediamo quali possono essere i pericoli che possiamo incontrare...
Innanzitutto, la tensione di ingresso sull'I/O (che sia configurato come input analogico o digitale) non deve superare la tensione di alimentazione del PPTEA, ovvero 5V, pena problemi che possono arrivare anche al danneggiamento irreversibile; inoltre, per avere una misura affidabile, sarebbe opportuno che la tensione di alimentazione del PPTEA sia la più stabile possibile, ed il più possibile centrata sui 5,000V, questo perchè per calcolare il valore dell'ingresso partendo dal risultato della conversione, nella formuletta vista prima quei 5V che troviamo indicati sono proprio il riferimento di tensione del convertitore A/D, ovvero l'alimentazione del PPTEA ; se utilizziamo nella formula un valore di 5V, ma il convertitore ha il suo riferimento a 4,8V oppure 5,2V, avremo delle differenze tra valore del segnale reale e valore calcolato dal risultato della conversione. Facciamo un'esempio ideale : con ingresso a 2,50000V abbiamo come conversione 2,500*(1023/5)=511,5 (quindi nella realtà solo per questo motivo la lettura come minimo "ballerà" tra 511 e 512 a causa del rumore...) se Valim=4,8V, con lo stesso ingresso, avremo che il convertitore restituirà 2,500*(1023/4,8)=532,8125 ovvero 533; se nel programma EABasic non teniamo conto del valore di tensione dell'alimentazione, ma facciamo i calcoli come se il riferimento fosse a 5V, otterremmo una misura pari a 533*(5/1023)=2,60508...V ovvero 105mV più del reale. Le soluzioni possibili possono essere diverse: realizzare una alimentazione stabile a 5,000V; utilizzare il valore reale della alimentazione nelle conversioni (ovviamente, dimenticandosi delle costanti di conversione già predisposte dall'Elettricista nell EABasic, ovver CAD_TO_VOLT e CAD_TO_TEMP, che sono valide solo con una tensione di alimentazione di 5,00V); usare un riferimento di tensione per "calibrare" gli ingressi analogici prima di ogni misura, limitando così le variazioni della sorgente di alimentazione; la scelta del metodo dipenderà dalla precisione richiesta dalla misura e da quanto ci preoccupiamo della deriva dell'alimentazione.
Tornando nel mondo reale, poi, dobbiamo tenere presente il rumore a cui siamo sottoposti; rumore che ha diverse origini, la più importante delle quali è quella di natura elettromagnetica causata dalle innumerevoli sorgenti RF che ci circondano, e che può venire captato dai collegamenti del nostro circuito, andando a variare la tensione misurata dal CAD. Una buona norma è quella di non limitarsi ad una lettura "one shot", ma eseguirne una serie per poi calcolare il valor medio, "limando" quindi i picchi dei disturbi. Per questo, l'Illuminato ha creato l'istruzione CADSEQ, che permette con una sola istruzione EABasic di catturare una serie di letture del CADS.
Nel proseguo vedremo come utilizzare queste nozioni; alla prossima.

P.S. rileggendomi a partire dal capitolo 1, ho notato come abbia via via preso il tono di un docente... non preoccupatevi, è solo un calo di zuccheri...



---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 15/4/2013,14:33

faccine/sad.gif Capitolo 11: CADS Dreaming

Bene... ci serve un esempio che calzi meglio del logoro ed un pò stantìo led... un esempio che utilizzi almeno un'ingresso digitale... un'esempio che sia d'interesse per molti... che abbia l'obiettivo del risparmio energetico... che possa essere utilizzato anche in futuro... che sia utile anche a me visto che ci perdo del tempo... mah... boh... mumblemumble... thinking... thinking...
CI SONO!!! IL TERMOSTATO!!! iniziamo con un termometro, al quale poi metteremo un bel display, che poi diventerà cronotermostato, che poi diventerà cronotermostato settimanale, che poi diventerà centralina di controllo integrata del riscaldamento ed acqua calda sanitaria, che poi diventera con telecontrollo via GSM... sisisi mi piace!!! MI PIACEEEE!!! I know, it's only PPTEA, but I like it!

Iniziamo: cosa fa un termostato? semplice, acc/spent di un qualcosa in base ad una soglia di temperatura... quindi deve innanzitutto misurare la temperatura... come facciamo... con un bel sensore con uscita digitale!...ah, no, dobbiamo usare i CAD... con un sensore analogico... una PT1000? Esagerato, con quello che costano... un sensore a stato solido, economico... un bel LM35, fa figo e non impegna!!!

Che cos'è un LM35? è un circuito integrato a 3 pin, simile per dimensioni e contenitore ad un qualsiasi transistor, che fornisce un'uscita linearmente dipendente dalla temperatura a cui è esposto, secondo un coefficiente di proporzionalità noto (ecco, è tornato il professore...), in pratica, alimentandolo ci darà 10mV per ogni grado centigrado di temperatura cui è arrivato il suo contenitore, ciò vuol dire che (idealmente) a 0°C la sua uscita sarà 0mV, a 100°C sarà 1000mV ovvero 1,00V; nella realtà, dai datasheet si vede che con singola alimentazione, la minima temperatura misurabile è 2°C; comunque, per un termostato ne abbiamo d'avanzo.

Iniziamo col misurare la temperatura. Utilizzare un LM35 è semplice, un pin va ai +5V, l'altro alla massa dell'alimentazione, l'uscita dritta sparata su di un CAD, almeno per ora che ci stiamo giocando, poi magari daremo un'occhiata al datasheet (no, non è una parolaccia anglosassone, così si chamano le pubblicazioni contenenti le specifiche tecniche di un componente elettronico) per vedere come usare al meglio il componente. Il CAD che useremo sarà, ovviamente, il #1 dato che con l'istruzione CADS=1 possiamo attivare solo questo. L'alimentazione che useremo sarà ovviamente 5,00000000V per semplificarci l'esistenza, e la misura della temperatura la comunicheremo via USB al PC.

Allora, innanzitutto

10 SETIO=&H0001
20 CADS=1

COME? E'uscita la versione 4 che usa più i numeri di riga? Ma se siete così bravi, perchè seguite questa guida? Qui siamo tutti ripetenti per 6 in condotta, i secchioni non li vogliamo...

Proseguiamo... iniziamo con delle semplici letture dell'ingresso e successivo output via USB, senza elaborazione...

30 USBOUT="T: " & CADS1

a questo punto che si fa? si continua a leggere l'ingresso e a sputare la lettura sulla USB

40 GOTO 30

In effetti l'output è un po bruttino... iniziamo a far andare a capo le scritte e convertiamo la lettura raw del convertitore in gradi centigradi:

30 PRINT "T: " & CADS1 * CAD_TO_TEMP

A questo punto, se volete buttarlo in hardware, potete utilizzare o il caro veccho potenziometro, oppure dotarvi di LM35, e vedere di nascosto l'effetto che fà (ciao, Enzo!)...




Modificato da MarKoZaKKa - 16/4/2013, 11:25


---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 16/4/2013,09:52

faccine/construction.gif Capitolo 12: Another (pair of) Brick(s) in The PPTEA

Allora, abbiamo implementato un bel termometro USB, ma che rottura doverlo collegare al PC... ed inoltre, quei dati che sfrecciano nella finestra... ci vorrebbe un bel display...
Ma basta chiedere! come lei saprà, il PPTEA implementa l'interfaccia verso moduli LCD alfanumerici compatibili Hitachi HD44780; il modulo può essere collegato sia direttamente con 6 linee, perdendo quindi 6 linee di i/o, sia attraverso uno shift register esterno, il quale permette un collegamento con sole 2 linee di i/o, sacrificando la velocità di aggiornamento. No, che cos'è uno shift register non ve lo spiego... noOo... no, no e no. Va bè, solo per questa volta... uno shift register è un circuito digitale, formato da una serie di celle di memoria collegate in cascata, l'uscita di una all'ingresso dell'altra, con una linea di comando in comune che forza l'aggiornamento delle celle, le uscite di ogni cella sono disponibili all'esterno. Se all'ingresso della prima cella invio un flusso di bit, sincronizzato con il comando di aggiornamento, posso trasformare il flusso seriale in flusso parallelo: vediamolo in concreto:

inizialmente, al tempo t0, immaginiamo che le celle dello shift register (a 4 bit) contengono tutte il valore "0"; quale che sia il valore dell'ingresso ("X" ovvero indifferentemente 0 o 1), non avendo ricevuto il comando di aggiornamento (detto clock, che lasciamo al valore 0, lo indico con "__" le celle se ne stanno beatamente nel loro stato.

CODICE
tempo   clock       in   out1    out2    out3    out4
t0          ____      X    0         0         0          0


Al tempo t1, immaginiamo di inviare il segnale di clock (lo indico con "/\", il quale farà si che ogni cella catturi il valore presente al suo ingresso, e lo memorizzi; in pratica, essendo gli ingressi di ciascuna collegate all'uscita della precedente (escluse la prima e l'ultima, ovviamente) avremo che ogni cella prenderà il valore di quella precedente, e la prima prenderà il valore dell'ingresso in quell'istante (che immaginiamo sia 1, giusto per vedere cosa accade), il valore precedente dell'ultima cella andrà ovviamente perso.

CODICE
tempo   clock       in   out1    out2    out3    out4
t0          ____      X    0         0         0          0
t1          _/\_       1    1         0         0          0


Ripetiamo il giochino per altre tre volte:

CODICE
tempo   clock       in   out1    out2    out3    out4
t0          ____      X    0         0         0          0
t1          _/\_       1    1         0         0          0
t2          _/\_       1    1         1         0          0
t3          _/\_       1    1         1         1          0
t4          _/\_       1    1         1         1          1


In pratica, abbiamo inviato 4 bit di dato (in questo caso "1111" su una linea seriale a due fili (data + clock) ed otteniamo una uscita parallela a 4 bit. Con questo "barbatrucco" ed un paio di componenti esterni, è possibile inviare i comandi dal PPTEA all'LCD con soli due fili, anche se abbiamo bisogno di 6 volte il tempo necessario rispetto al collegamento diretto; sarà poi necessario ripulire lo shift register inviando una sequenza di 6 "0", quindi il tempo totale sarà di 12 volte quello del collegamento diretto, e questo avviene per ogni carattere scritto sul display... ma che cosa sono pochi cicli di clock rispetto all'eternità?

Ovviamente, abbiamo tutta una serie di comandi dedicati al comando dell'LCD, ma li vedremo man mano che ci serviranno, altrimenti perdiamo di vista l'obiettivo; lo shift register era interessante spiegarlo, perchè può funzionare anche al contrario, quindi prendere un ingresso parallelo ad n bit e trasformarlo in un flusso seriale... a cosa ci serve? Beh, così su due piedi, a leggere n linee di input digitali con solo due linee di i/o del PPTEA...

Tutto questo è molto bello, ma... ma come facciamo a dire al PPTEA che ha un LCD collegato, e magari pure a soli 2 fili (modo LCD2W)?
Ricordate la SETIO? Vi dissi che passando un valore a 16 bit possiamo configurare le linee di I/O, in realtà la SETIO ha anche altre funzioni: permette di dire al PPTEA che ha collegato un display a 2 o a 6 fili e come lo deve indirizzare (una funzionalità utile per display non standard, ma che al momento ignoreremo). Allora, ripetiamo quanto già detto: i bit da 0 a 15 della SETIO corrispondono alle 16 linee di I/O dl PPTEA, "1" se vogliamo un ingresso, "0" se vogliamo un'uscita; ora aggiungiamo altri 2 bit, il bit16 ed il bit17, i quali si occupano di definire il tipo di indirizzamento (bit16, "0" per indirizzamento standard, "1" per indirizzamento gestito da codice eabasic, qualsiasi cosa questo voglia dire...) ed il tipo di collegamento del display (bit17, "0" per LCD6W, "1" per LCD2W). come avrete già capito, se non esplicitiamo questi due bit nella SETIO, tutto rimane configurato per un display standard collegato a 6fili (bit16="0", bit17="0".
Per il collegamento fisico dell'LCD, fate riferimento allo schema elettrico contenuto in quel tomo che porta il poco rassicurante titolo di "MANUALE PPTEA"; io personalmente ho strappato la pagina relativa e l'ho incollata sul muro di fronte al mio tavolo di lavoro, almeno non devo sfogliarlo ogni volta...
Dato che sono un'estremista dell'LCD2W, configureremo il PPTEA per usare questo tipo di display. Una cosa che non ho detto: dato che le linee di collegamento all'LCD sono in tutto e per tutto degli OUTPUT, dobbiamo assicurarci di specificarle come tali nella SETIO; per qualche strano ed imperscrutabile motivo, il Supremo ha donato la priorità alla CADS sulla SETIO, ma se scriviamo una cosa del tipo SETIO=&H2FFFF, quindi diciamo di avere un LCD2W collegato ma non specifichiamo che le linee di I/O relative al suo collegamento sono OUTPUT, "'un funziona nulla!"; dobbiamo sempre impostare i bit della SETIO relativi alle linee che vanno a collegarsi all'LCD come OUTPUT... fatevene una ragione...
Alla prossima, che mi si sono scaricate le batterie del laptop...




Modificato da MarKoZaKKa - 16/4/2013, 11:13


---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 16/4/2013,13:54

faccine/ban.gif Capitolo 13: Pay no attention to the writings on the LCD...
Bene, avete comprato un bellissimo LCD 4X20 cinese retroilluminato fucsia, pagato nulla, lo avete collegato a 6 fili, a 2 fili, al contrario, e non funziona ancora... e ve lo avevano pure detto prima di vendervelo che era "fucksia"... Andate a comprarne un'altro, va... che adesso vediamo come modificare il codice...Senza menare il can per l'aia, che poi si stanca, ecco:

<pre>10 SETIO=&H20001
20 CADS=1
25 LCDCLEAR
30 LCDPOS=&H11
35 LCDWRITE="T: " & CADS1 * CAD_TO_TEMP
40 GOTO 30

Vediamo che la SETIO ha guadagnato i 2 bit di configurazione (per chi ancora non pensa HEX, ma solo SEX, SETIO=&B100000000000000001) che informano il PPTEA di avere un display collegato 2W, con indirizzamento standard; poi abbiamo alcuni nuovi comandi specifici per l'LCD, ovvero LCDCLEAR (che pulisce il display da quanto eventualmente rimasto), LCDPOS che posiziona il cursore di scrittura nel punto voluto, LCDWRITE che invia i dati da mostrare all'LCD.
Vediamo ciascuna nel dettaglio:

- LCDCLEAR: banale, direte voi... in effetti si, bisogna solo tenere presente che l'LCD ha una sua memoria, quindi una volta scritto qualcosa, questo rimane, anche quando fermate il PPTEA... e anche quando lo riavviate... e quello che scrivete si mixa con quanto già presente... meglio ripulire prima...

- LCDPOS: Posiziona il "cursore di scrittura" in una locazione del display. Essendo alfanumerico, il display avrà R righe e C colonne, ad esempio un classico 2x16. Bene, se ragionate in decimale, per posizionare il cursore al primo carattere della prima riga, dovrete calcolare il valore da passare all'istruzione con la formula LCDPOS=(16*R)+C; se ragionate in esadecimale, avrete che il primo carattere della prima riga sarà LCDPOS=&H11, l'ottavo della seconda riga sarà LCDPOS=&H28, l'ultimo della seconda riga sarà &H2F... bello l'hex, vero? ATTENZIONE: se il display ha più di 16 caratteri per riga, non vi è più questa corrispondenza diretta...

- LCDWRITE: ovviamente, scrive quello che gli passiamo sul display, nel punto specificato dall'ultima LCDPOS, oppure a partire dalla posizione seguente quella dell'ultimo carattere scritto con una precedente LCDWRITE... attenzione che se finiamo fuori dai massimi caratteri, il display non va a capo in automatico...

Alla luce di queste spiegazioni, possiamo modificare il nostro codice come segue:
10 SETIO=&H20001
20 CADS=1
25 LCDCLEAR
26 LCDPOS=&H11
27 LCDWRITE="TEMPERATURA:"
28 LCDPOS=&H27
29 LCDWRITE="CELSIUS"
30 LCDPOS=&H21
35 LCDWRITE=LEFT(CADS1 * CAD_TO_TEMP,5)
40 GOTO 30

Ovvero scriviamo prima i caratteri "fissi" e poi andiamo a modificare solo le parti variabili del messaggio, questo usando un display LCD2W vuol dire velocizzare le operazioni di aggiornamento.L'istruzione LEFT(S,n) introdotta adesso permette i primi n caratteri di una stringa S; esiste anche la RIGHT(S,n) che esegue la stessa cosa partendo però da destra, quindi estrae gli ultimi n caratteri... no, le stringhe non sono quelle delle scarpe...
Con questa semplicissima operazione, abbiamo anche convertito un valore numerico in virgola mobile (CADS1*CAD_TO_TEMP) in una stringa di caratteri... ma delle conversioni tra tipi ne parleremo poi... o forse no... boh!
Come forse avrete notato, se avete messo tutto sul PPTEA e provato a vedere il funzionamento in hardware, probabilmente i numeri saranno "ballerini", questo a causa del rumore (elettrico) che entrerà nel circuito. Come già detto, per ridurne l'impatto è opportuno acquisire più valori successivi, per poi mediarli; vediamo come farlo in diversi modi, teniamo tutto buono fino alla riga 29 e poi modifichiamo il seguito:

metodo 1: somma e divisione
30 CONSTANT N=10
31 LCDPOS=&H21
32 FOR X=1 TO N
33 T=T+CADS1
34 NEXT X
35 LCDWRITE=LEFT(T/N* CAD_TO_TEMP,5)
36 T=0
40 GOTO 31


Cominciamo qui a parlare di cicli: un ciclo FOR...NEXT fa si che le istruzioni contenute tra il FOR ed il NEXT vengano ripetute tante volte quanto viene specificato come limite... in questo caso il valore contenuto in N, pari a 10.
A ogni ciclo la lettura istantanea del convertitore viene sommata nella variabile T, che poi viene divisa per N e convertita alla riga 35, l'effetto di questo è che mediamo su dieci misure quanto poi mostriamo a display.

PRO: questo metodo lo capiscono tutti;
CONTRO: sprechiamo 2 variabili ed una costante, la velocità di acquisizione è limitata dal tempo di esecuzione del ciclo.

metodo 2: CADSEQ
E chi la conosce, non l'ho mai usata... devo documentarmi... CIAOOOOOoooooo.....



Modificato da MarKoZaKKa - 17/02/2014, 16:18:48


---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 13/5/2013,11:51

faccine/w00t.gif INSERTO SPECIALE: Come trasformare un anonimo PIC18F2550 in un PPTEA ed iniziare ad usarlo!

N.B.: Mi ero ripromesso di non farlo, ma sto cercando di guadagnarmi la reincarnazione, o la vita eterna, o il riposo eterno, fate voi...


Allora, vediamo nel dettaglio cosa deve fare un 'absolute beginner' per far funzionare il PPTEA; facciamo le seguenti ipotesi:

TIZIO non sa nulla di elettronica/pic/connessioni seriali/parallele/USB;
TIZIO sa accendere un pc e fare click, installare i programmi ed utilizzarli, nulla di più;
TIZIO non sa programmare.
TIZIO non ha in mano un PPTEA funzionante, ha solo un PIC18F2550 ed una scheda costruita secondo lo schema del manuale PPTEA
TIZIO possiede un PICKIT2 di cui ha già installato l'applicazione
TIZIO ha già scaricato l'ultima consegna del software PPTEA, che comprende Compiler, firmware e documentazione, l'ha scompattata in una cartella che si chiama PPTEA.

Allora, abbiamo il PC acceso, nulla collegato, vogliamo innanzitutto trasformare un anonimo PIC18F2550 in un potentissimo e sfolgorante PPTEA.

1) COLLEGARE il PIC18F2550 al PICKIT2, secondo lo schema (thnks to PinoTUX):

PIN...............Nome.............PIN
pickit2...........segnale..........PIC18F2550
1.................VPP..............1
2.................VDD (+5).........20
3.................VSS (GND)........19
4.................PGD dati.........28
5.................PGC clock........27
6.................NON USATO........NON USATO
Questa operazione è possibile anche con un banale adattatore costruito con uno zoccoletto DIP 14+14, 5 fili ed un pezzo di pin strip. Se usate la mia KSB-II, avete un favoloso connettore dedicato...

2) COLLEGARE il PICKIT2 ad una porta USB del PC dove si è installato l'applicazione "Microchip PICKIT2 Programmer", ed avviare tale applicazione.

3) SE TUTTO OK, nel campo Device si leggerà "18F2550", altrimenti tornare al punto (1)

4) Dal menu "FILE" selezionare "IMPORT HEX" ed andare a caricare il firmware PPTEA presente nella cartella "Firmware" all'interno della cartella PPTEA dove avete scompattato i files della consegna.

5) Fare click su [Write] ed attendere il corretto completamento, confermato da un messaggio su sfondo verde.

6) CHIUDERE "Microchip PICKIT2 Programmer"

7) SCOLLEGARE dalla porta USB il PICKIT2

8) Rimontare il PIC18F2550 nella scheda PPTEA (Se usate la KSB-II, staccate il PICKIT2 e rimettete i jumper caps)

9) Collegare la scheda PPTEA al PC con il cavo USB

10) Il PC riconosce un nuovo hardware, e vi chiederà i drivers relativi. Si trovano nella cartella, indovinate un po, "Drivers" sempre dove avete scompattato la consegna.

11) Ignorate i vari messaggi allarmistici di Winzozz riguardo ai certificati, e installate.

12) Aprite il Device Manager... la maniera + rapida è fare "START"->"Esegui" scrivere "devmgmt.msc" e dare <invio> o click su [Esegui], aprite l'albero alla voce "Porte (COM e LPT)", cercate la voce "//http:energiaalternativa.forumcommunity.net/ (COMnn)",
prendete nota del numerino nn dopo "COM"; se è minore di 10, andate al passo (14)

13) Se siete qui avete nn>=10; fate doppio click sulla voce "//http:energiaalternativa.forumcommunity.net/ (COMnn)". Si aprirà una nuova finestra, andate su "Impostazioni della porta", fate click su [Avanzate...] impostate un "Numero porta COM:" minore di 10 e date [OK]; quale numero scegliere dipende dalla particolare situazione del vostro PC... Ad esempio, il mio mi dice "COM1 in uso" "COM2 in uso"anche se il PC non ha porte seriali native; solo perchè utilizzo adattatori RS232/USB e chiavette internet UMTS.

14) Chiudete tutti gli spifferi, SCOLLEGATE la scheda PPTEA ed aprite (finalmente!) il Compiler PPTEA. Se avete un'antivirus, probabilmente romperà le scatole in varie maniere, tutto normale... infischiatevene. Se non si avvia, probabilmente avete un'antivirus MOLTO rompiscatole... disattivatelo o mettete un'eccezione.

15) Avete davanti una finestra vuota, con solo i menu "File", "Setting" e "?" attivi... scrivete due righe di codice banale, tipo:

10 USBOUT="ECCOMI!"
20 END
a questo punto si attiverà anche il menù "Compile". Selezionatelo, il Compiler triterà un'attimo, vi darà una piccola barretta verde in basso alla voce "Status & Chip Usage" e si attiveranno i pulsanti [RENUM] e [TRAN(s)FER CODE ON PIC] (strano che nessuno abbia mai visto questo refuso...)

16) Indovinate su cosa fare click? Bravi! La finestra cambia un poco, avrete in alto un frame "PIC Com(m)unication", controllate che dove vedete scritto "COMnn" quel numerino sia uguale al "vostro" nn, altrimenti correggete e fate click su [Mem.Port]

17) Fate click sul pulsante [Synchronized], e finalmente....

18) Collegate la scheda PPTEA alla porta USB... (per scaramanzia, ve lo faccio fare allo step 18... faccine/smile.gif) Se tutto ok, dopo qualche istante (per la precisione, 4secondi) apparirà una cosa del tipo "PPTEA V.xx.xxx.xx.x.x.x.x NonSoloBolleDiAcqua" . Questo vi conferma che il PIC è diventato un PPTEA, e comunica col PC... faccine/clap.gif

19) A questo punto, il PPTEA sta ancora eseguendo il codice EABASIC che il folle elettricista ha inserito nel firmware, quindi anche se non fa nulla, il PPTEA è ancora in ESECUZIONE. per metterlo in APPRENDIMENTO ed accettare un nuovo codice, bisogna premere il pulsante "STOP" sulla schedina... c'è, VERO?!?!

20) Nel compiler apparirà una scritta "STOP", conferma che il PPTEA ha fermato l'esecuzione del codice EABASIC, e sta aspettando istruzioni.

21) Se volete, potete provare a trasferire il vostro fantastico codice, fate click su [GO!] nel frame "Transfer Code on PIC" (qui la S c'è), NON TOCCATE NULLA, NON CAMBIATE FINESTRA, STATE SOLO A GUARDARE ed avrete il codcie EABASIC trasferito nel PPTEA.

22) Adesso, riavviate l'esecuzione del codice nel PPTEA, facendo click su [Run PIC], e godetevi lo spettacolo.

23) Ripetete gli step da 15 a 22 ogni volta che volete inserire un nuovo programma EABASIC nel vostro nuovo, fiammante, esoterico, esuberante PPTEA. Il controllo della porta COM è necessario solo se collegate la scheda PPTEA ad una porta USB diversa... io normalmente faccio gli step da 9 a 13 su tutte le porte USB, impostando la stessa COM... almeno non mi sbaglio...
Buon divertimento! faccine/biggrin.gif faccine/bye2.gif



---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 17/02/2014 16:07:54

Capitolo 14: Cads reprise

Bene, dopo questa lunga pausa, ho trovato un poco di tempo per proseguire con la guida galattica... nel frattempo sono uscite diverse versioni del PPTEA, ed ora siamo alla 4.2.4... stavamo per parlare dell'istruzione CADSEQ, ma nel debugger della 3.2 non funzionava... e da una breve verifica nemmeno nella 4.2.4. Direi che a questo punto ne parleremo comunque, ma non potremo simularla nel compiler, a meno di qualche trucchetto...

Dunque, abbiamo lasciato il nostro codice a questo punto:

<pre>10 SETIO=&H20001
20 CADS=1
25 LCDCLEAR
26 LCDPOS=&H11
27 LCDWRITE="TEMPERATURA:"
28 LCDPOS=&H27
29 LCDWRITE="CELSIUS"
30 CONSTANT N=10
31 LCDPOS=&H21
32 FOR X=1 TO N
33 T=T+CADS1
34 NEXT X
35 LCDWRITE=LEFT(T/N* CAD_TO_TEMP,5)
36 T=0
40 GOTO 31</pre>


la temperatura viene calcolata mediando 10 letture del CAD1, per minimizzare gli effetti del rumore; possiamo ottenere una cosa simile con l'istruzione CADSEQ, la cui sintassi è:

CADSEQ(vettore,CADn,intervallo,letture)

vettore: variabile di tipo vettore (ma và!?!)
CADn: il numero del convertitore che stiamo utilizzando
intervallo: mettete via le merendine... è il tempo che vogliamo attendere tra due letture successive del CADn, in microsecondi (usec)
letture: il numero di letture successive che vogliamo

Quindi, se scriviamo CADSEQ(T,1,100,10) otterremo (?forse?) che nel vettore T finiranno 10 letture successive del CAD1 intervallate di 100usec. Si, ma cos'è un vettore? Detta in parole povere, è una variabile "a scomparti", immaginatela come una scatola, con sopra scritto il contenuto divisa in scomparti, ciascuno contenente un'elemento. Per utilizzarla, dobbiamo prima dire al compiler di che tipo di valori abbiamo bisogno, e quanti ne vogliamo; in fase di compilazione verrà "costruita" la scatola che poi utilizzeremo nel codice. Abbiamo alcuni vincoli, nell'utilizzare vettori: dobbiamo dichiararli all'inizio del codice sia come numero di elementi che come tipo di contenuto, in più, le dimensioni massime dipenderanno da quanta memoria utilizzeremo per le altre variabili. Pertanto, aggiungeremo al nostro codice la riga:
5 DIM T(10) AS WORD

con la quale dichiariamo un vettore di 10 elementi di tipo WORD (ovvero numero binario a 16bit, dato che le letture del CAD sono numeri binari a 10bit); poi, la routine di lettura e visualizzazione diventerà:
30 CADSEQ(T,1,5000,10)
31 LCDPOS=&H21
32 FOR X=1 TO 10
33 TM=TM+T(X)
34 NEXT X
35 LCDWRITE=LEFT(TM/10* CAD_TO_TEMP,5)
36 TM=0
40 GOTO 30

Ovviamente, per misurare una temperatura, entrambi i metodi sono efficaci; questo perchè la variazione di temperatura non è così rapida da necessitare una cattura di campioni a distanza di microsecondi; se invece desideriamo catturare un segnale elettrico a rapida variazione, la CADSEQ ci permetterà di catturarlo efficacemente.



Modificato da MarKoZaKKa - 17/02/2014, 16:12:00


---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 

MarKoZaKKa

Avatar
GigaWatt


Gruppo:Utente
Messaggi:1886

Stato:



Inviato il: 01/10/2014 12:30:02

Capitolo 15: Back to the Guide

Credevate che la Guida Galattica fosse caduta nel limbo delle cose incompiute... invece, ecco un nuovo capitolo...
Bene, sappiamo come acquisire la temperatura... cosa dovevamo costruire... ah,si, un termostato... quindi dovremo fissare almeno una soglia, comparare il valore della temperatura con la soglia, e decidere cosa fare quando siamo sopra oppure sotto quel valore. Questo è (quasi) quello che fà un termostato meccanico, se non consideriamo l'isteresi del meccanismo che provoca la commutazione a 23°C o più quando la temperatura sta salendo, ed a 21°C o meno quando sta scendendo, a fronte di un setpoint di 22°C... E se ci pensiamo bene, l'isteresi è proprio ciò che evita un continuo accendi/spegni del sistema, per cui dovremo replicare nel codice anche questa caratteristica.
Abbiamo già il programma che legge una temperatura e la mostra sul display, dobbiamo aggiungere la possibilità di attivare o disattivare una uscita in base al valore della temperatura. Decido di voler mantenere una temperatura di 22°C. Voglio evitare un continuo accendersi/spegnersi del riscaldatore, pertanto decido che si accenda solo quando la temperatura scende sotto i 21°C e si spenga non appena supera i 23°C; in questa maniera manterrò il valore medio della temperatura intorno ai 22°C. Decido che l'uscita da utilizzare per il pilotaggio del riscaldatore è la numero 14. Perchè, direte voi... beh, perchè le linee 1,2,3,5 possono essere usate come ingressi analogici, quindi me le tengo libere per eventuali sviluppi, la 4 e la 11 servono per il collegamento a due fili con il display LCD, la 9 e la 10 per il bus I2C di collegamento a memoria esterna ed orologio, la 15 può essere utilizzata come uscita audio... rimane poca scelta...
Innanzitutto, mettiamo in ordine il codice... spostiamo configurazioni e costanti tutti all'inizio del codice, tanto una volta letti non ci interessano più... anzi, facciamo una bella cosa, eliminiamo pure i numeri di riga, sfruttando le funzionalità avanzate del compilatore PPTEA:

<pre>
PRAGMA NO_NUM_LINE
PRAGMA INTERNAL_EEPROM
SETIO=&H20001
CADS=1
CONSTANT N=10
LCDCLEAR
LCDPOS=&H11
LCDWRITE="TEMPERATURA:"
LCDPOS=&H27
LCDWRITE="CELSIUS"
:31
LCDPOS=&H21
FOR X=1 TO N
T=T+CADS1
NEXT X
LCDWRITE=LEFT(T/N* CAD_TO_TEMP,5)
T=0
GOTO :31
</pre>


Sono apparse alcune istruzioni sconosciute... e sono spariti i numeri di riga... Andiamo con ordine...
Abbiamo le direttive PRAGMA, che comunicano al compilatore alcune impostazioni, nello specifico, PRAGMA NO_NUM_LINE dice che non vogliamo più (evviva!) usare i numeri di linea, saremo quindi liberi di aggiungere/cancellare/spostare parti di codice senza dover ogni volta impazzire con la numerazione; PRAGMA INTERNAL_EEPROM dice che il nostro codice dovrà risiedere (per ora) nella eeprom interna del PPTEA.
Avendo eliminato i numeri di linea, per effettuare i salti abbiamo bisogno di un riferimento... questo è la LABEL, un riferimento menmonico preceduto dal carattere ":" al momento ho mantenuto il vecchio numero di riga, creando la label ":31" e modificando l'ultima linea in "GOTO :31"...
Miglioriamo ancora un poco la leggibilità del codice, utilizzando un altro strumento che finora abbiamo ignorato, i commenti. Possiamo scrivere delle frasi di documentazione all'interno del codice, che ci permettono di capire quello che ci siamo inventati in un momento di genio e che a distanza di due mesi non riusciamo più a decifrare. Possiamo inserire sia righe intere che non contengono null'altro che testo umanamente comprensibile, sia commenti alla fine di una riga di codice:

PRAGMA NO_NUM_LINE
PRAGMA INTERNAL_EEPROM
REM CODICE PER TERMOSTATO
SETIO=&H20001 'IMPOSTO LINEA 1 INPUT ALTRE OUTPUT E DISPLAY 2FILI
CADS=1 'USO IL PRIMO CONVERTITORE A/D
CONSTANT N=10 'NUMERO DI LETTURE A/D DA MEDIARE
LCDCLEAR 'PULISCO E PREDISPONGO SCRITTE FISSE SU LCD
LCDPOS=&H11
LCDWRITE="TEMPERATURA:"
LCDPOS=&H27
LCDWRITE="CELSIUS"
:31 'LOOP DI VISUALIZZAZIONE
LCDPOS=&H21
FOR X=1 TO N
T=T+CADS1 'LOOP DI LETTURA CAD
NEXT X
LCDWRITE=LEFT(T/N* CAD_TO_TEMP,5)
T=0
GOTO :31


Un'altro bello strumento per rendere il codice più leggibile è la cosiddetta indentazione, ovvero lo spostare di una o piu tabulazioni a destra le sezioni di codice all'interno di un ciclo o di un IF/THEN/ELSE e così via, se poi mettiamo anche qualche linea vuota per separare i blocchi di codice che hanno funzioni diverse, il tutto migliora ulteriormente:

PRAGMA NO_NUM_LINE
PRAGMA INTERNAL_EEPROM

REM CODICE PER TERMOSTATO

SETIO=&H20001 'IMPOSTO LINEA 1 INPUT ALTRE OUTPUT E DISPLAY 2FILI
CADS=1 'USO IL PRIMO CONVERTITORE A/D
CONSTANT N=10 'NUMERO DI LETTURE A/D DA MEDIARE

LCDCLEAR 'PULISCO E PREDISPONGO SCRITTE FISSE SU LCD
LCDPOS=&H11
LCDWRITE="TEMPERATURA:"
LCDPOS=&H27
LCDWRITE="CELSIUS"

:31 'LOOP DI VISUALIZZAZIONE
LCDPOS=&H21
FOR X=1 TO N
	T=T+CADS1 'LOOP DI LETTURA CAD
NEXT X
LCDWRITE=LEFT(T/N* CAD_TO_TEMP,5)
T=0
GOTO :31


Meglio, vero? Adesso facciamo un ulteriore salto di qualità; ci siamo slegati dai numeri di riga, il nostro codice non è più limitato dalla rigida posizione numerica, quindi possiamo identificare dei blocchi funzionali e racchiuderli all'interno di una routine, che chiameremo al lavoro quando ci servirà (e magari, possiamo pure crearci una libreria di subroutine già pronte). Abbiamo già due blocchi, quello che inizializza il display con le scritte fisse e quello che esegue calcolo della media e visualizzazione della temperatura... e già che ci siamo, chiamiamo le variabili e le costanti in modi che ci aiutino a capire... e non lamentatevi della fatica che fate a digitare.

PRAGMA NO_NUM_LINE
PRAGMA INTERNAL_EEPROM

REM CODICE PER TERMOSTATO

REM IMPOSTAZIONI
SETIO=&H20001		'imposto 1 input ed il resto output
CADS=1 			'uso il primo a/d
CONSTANT LETTURE=10 	'numero di letture dell'a/d da mediare
CONSTANT RIGA1="TEMPERATURA:"
CONSTANT RIGA2="CELSIUS"

REM INIZIO ESECUZIONE
	CALL PREPARA_DISPLAY
:CALCOLA_E_MOSTRA
	CALL MISURA
	CALL MOSTRA
	T=0
	GOTO :CALCOLA_E_MOSTRA
	END

	SUB PREPARA_DISPLAY 'inizializzo il display e predispongo scritte fisse
		LCDCLEAR
		LCDPOS=&H11
		LCDWRITE=RIGA1
		LCDPOS=&H27
		LCDWRITE=RIGA2
	SUBEND

	SUB MISURA 'calcola la media delle letture a/d
		FOR N=1 TO LETTURE
			T=T+CADS1
		NEXT N
		T=T/LETTURE*CAD_TO_TEMP
	SUBEND

	SUB MOSTRA 'scrive la temperatura misurata e mediata
		LCDPOS=&H21
		LCDWRITE=LEFT(T,5)
	SUBEND


Non è molto più comprensibile, ora?



---------------
Tecnico qualificato in clownerie
Windsurfer a tempo perso
Slalomaro senza speranze

 
 InizioPagina
 

Pagine: (2)   [1]   2    (Ultimo Msg)

Versione Mobile!

Home page       TOP100-SOLAR      Home page forum