PDA

View Full Version : [Python->Pic] Controllo seriale di un display 100x7


Utone
26-01-2010, 16:56
Ciao a tutti,
io e altri 3 ragazzi stiamo sviluppando (per la tesina) un programma per controllare un tabellone a led (costruito precedentemente da altri ragazzi ) via seriale.
Questo tabellone è composto da 100 colonne da 7 led.
Ci sono 7 pic di cui uno master e sei slave.
Per visualizzare una schermata il pic master bisogno di ricevere 100byte in modo da settare una colonna alla volta.
Il programma in Python è quasi concluso, l 'ho uppato qui (http://www.mediafire.com/?5yojvfekezm) (se mi dite che posso lo allego anche sul forum tanto è 5k) ma il problema è che il tabellone in questo modo ha sempre bisogno di un pc.
L'obiettivo della tesina era di fare un hardware che faccia il lavoro del programma in python. Inferfacciabile via seriale (solo per settare la scritta e eventuale scorrimento), e magari o bluetooth o modulo gsm.
Esiste qualcosa programmabile in Python o in qualche altro linguaggio in grado di fare questo? Altri consigli?
Far fare questo lavoro ad un Pic sembra troppo complicato. Andrebbe completamente riscritto il codice.

PS: Nel programma in Python c'è anche un simulatore del tabellone per visualizzare il risultato.

cdimauro
26-01-2010, 19:57
Mi sa che dovrete riscrivervi il programmino in C.

Utone
26-01-2010, 20:23
Cavolo... qualche idea di come farlo?
Nel python abbiamo usato il dizionario, in C dovremmo usare le matrici e fare un if ogni carattere giusto?
Per esempio la prima implementazione era questa:
A=[[124,18,17,18,124,0],"A"]
T=[[1,1,127,1,1,0],"T"]
U=[[63,64,64,64,63,0],"U"]
C=[[62,65,65,65,34,0],"C"]
S=[[38,73,73,73,50,0],"S"]
spazio=[[0,0,0,0,0,0]," "]

testo=raw_input("Testo")
for x in testo:
if x in A:
L=L+A[0]
if x in T:
L=L+T[0]
ecc....
solo che in c non ho neanche il comando in...

ndakota
26-01-2010, 20:36
Un arduino (http://www.arduino.cc/)? Si programma in una specia di Java mi pare :D

Z80Fan
26-01-2010, 20:48
Cavolo... qualche idea di come farlo?
Nel python abbiamo usato il dizionario, in C dovremmo usare le matrici e fare un if ogni carattere giusto?
Per esempio la prima implementazione era questa:
A=[[124,18,17,18,124,0],"A"]
T=[[1,1,127,1,1,0],"T"]
U=[[63,64,64,64,63,0],"U"]
C=[[62,65,65,65,34,0],"C"]
S=[[38,73,73,73,50,0],"S"]
spazio=[[0,0,0,0,0,0]," "]

testo=raw_input("Testo")
for x in testo:
if x in A:
L=L+A[0]
if x in T:
L=L+T[0]
ecc....
solo che in c non ho neanche il comando in...

Ciao, io non conosco il python ma penso di intuire il problema. Penso non dovrebbe essere troppo difficile ricrearlo in C, visto che usi lettere singole come "indice" per l'array (parlo sempre i termini C-eschi :D ) Potresti usare il valore ascii equivalente come indice nell'array dove tieni le "bitmap" dei vari caratteri (immagino che tutti i numeretti siano i valori di acceso/spento da dare ai led), quindi per trovare l'indice dato il carattere ti basterebbe fare
int indice = (int) carattere;
o anche (penso, non sono sicuro):
int indice = (int)('A');
e forse anche
lettere[ (int)('A') ];

Poi crei una matrice fatta così:

int lettere[128][7] = {
{0,0,0,0,0,0,0}, //ascii 0
{0,0,0,0,0,0,0}, //ascii 1
{0,0,0,0,0,0,0}, //ascii 2
...
{124,18,17,18,124,0,0}, //ascii 65 ( 'A' )
...
};
Dove 128 sono il numero di caratteri ascii e 7 le righe di ogni carattere
Non dovrebbe essere troppo difficile visto che hai già dovuto creare una tabella di questo genere, al massimo dovrai riempire quei caratteri che non ti servivano prima.
Cmq se vuoi posso aiutarti nella traduzione :D

cdimauro
26-01-2010, 20:50
Cavolo... qualche idea di come farlo?
Nel python abbiamo usato il dizionario, in C dovremmo usare le matrici e fare un if ogni carattere giusto?
Per esempio la prima implementazione era questa:
A=[[124,18,17,18,124,0],"A"]
T=[[1,1,127,1,1,0],"T"]
U=[[63,64,64,64,63,0],"U"]
C=[[62,65,65,65,34,0],"C"]
S=[[38,73,73,73,50,0],"S"]
spazio=[[0,0,0,0,0,0]," "]

testo=raw_input("Testo")
for x in testo:
if x in A:
L=L+A[0]
if x in T:
L=L+T[0]
ecc....
solo che in c non ho neanche il comando in...
Quelli non sono dizionari, ma liste, e per simulare l'in in C ti basta scorrerle e controllare elemento per elemento.

Utone
26-01-2010, 21:08
Un arduino (http://www.arduino.cc/)? Si programma in una specia di Java mi pare :D
è fattibile un programma del genere in Java? Io non ho mai programmato..
il costo più o meno??
edit- Ho letto che si programma in Processing o Wiring. Qualcuno li conosce?
Per il prezzo ho visto che parte da 20€ ma quello con il bluetooth viene 80€!!
Ciao, io non conosco il python ma penso di intuire il problema. Penso non dovrebbe essere troppo difficile ricrearlo in C, visto che usi lettere singole come "indice" per l'array (parlo sempre i termini C-eschi :D ) Potresti usare il valore ascii equivalente come indice nell'array dove tieni le "bitmap" dei vari caratteri (immagino che tutti i numeretti siano i valori di acceso/spento da dare ai led), quindi per trovare l'indice dato il carattere ti basterebbe fare
int indice = (int) carattere;
o anche (penso, non sono sicuro):
int indice = (int)('A');
e forse anche
lettere[ (int)('A') ];

Poi crei una matrice fatta così:

int lettere[128][7] = {
{0,0,0,0,0,0,0}, //ascii 0
{0,0,0,0,0,0,0}, //ascii 1
{0,0,0,0,0,0,0}, //ascii 2
...
{124,18,17,18,124,0,0}, //ascii 65 ( 'A' )
...
};
Dove 128 sono il numero di caratteri ascii e 7 le righe di ogni carattere
Non dovrebbe essere troppo difficile visto che hai già dovuto creare una tabella di questo genere, al massimo dovrai riempire quei caratteri che non ti servivano prima.
Cmq se vuoi posso aiutarti nella traduzione :D

Per prima cosa ti ringrazio molto per la disponibilità.. :D
io con il C ho poca esperienza... ho programmato solo il pic 16f877...
Io gli mando una colonna alla volta.. Tipo la "I" è un 127,0.
Se creo una matrice che ha dentro liste (:confused: parentesi graffe??) di lunghezza fissa avrei 6 spazi vuoti di troppo giusto?

Quelli non sono dizionari, ma liste, e per simulare l'in in C ti basta scorrerle e controllare elemento per elemento.
lo so che sono liste queste infatti ho scritto che era solo la prima implementezione (che è più vicina al C). Il codice "finale" l'ho linkato..
Ne trascrivo qui un pezzo per far capire..

def leggiLettere():
lett={}
#MAIUSCOLE
lett ['A'] = [124,18,17,18,124,0]
lett ['B'] = [127,73,73,73,54,0]
lett ['C'] = [62,65,65,65,34,0]
lett ['D'] = [127,65,65,34,28,0]
lett ['E'] = [127,73,73,73,65,0]
lett ['F'] = [127,65,65,34,28,0]
lett ['G'] = [62,65,73,73,57,0]
lett ['H'] = [127,8,8,8,127,0]
lett ['I'] = [127,0]
eccccccc
return lett

def aggiornaTkDisplay(): #scrive i 100 byte sul display
for i in colonne:
tkDisp.write(chr(i)) #scrive sul simulatore
#ser.write(chr(i)) #scrive sulla seriale

def scriviColonne(s):
cnt=0
for z in s: #mi serve per contare quanti byte vado a variare
for x in lettere[z]:
cnt= cnt+1
pos=(100-cnt)/2
for c in s: #attraverso la stringa
for n in lettere[c]: #ricavo i valori dei vari carattere
colonne[pos] = n #scrivo i valori nella lista
pos+=1
def scrivi():
cancella()
testo=entry.get() #prendo il testo dal tkinter
scriviColonne(testo)
aggiornaTkDisplay()

colonne = [0]*100
lettere = leggiLettere()

cdimauro
27-01-2010, 07:22
Ieri non riuscivo a scaricare il sorgente. Comunque Z80Fan ti ha indicato una buona strada per riscrivere il tuo codice in C.

Solo un appunto: i dizionari li puoi dichiarare in maniera più elegante. :)

Utone
27-01-2010, 14:07
Solo un appunto: i dizionari li puoi dichiarare in maniera più elegante. :)

Per esempio?? :)

cdimauro
27-01-2010, 16:06
lett = {'A' : [124,18,17,18,124,0],
'B' : [127,73,73,73,54,0]}

Utone
27-01-2010, 16:43
Ah capito... ma è solo questione di forma.. non cambia niente giusto?

cdimauro
27-01-2010, 18:09
E' anche più veloce. Soprattutto con wpython. :cool:

Z80Fan
27-01-2010, 19:08
Per prima cosa ti ringrazio molto per la disponibilità.. :D
io con il C ho poca esperienza... ho programmato solo il pic 16f877...
Io gli mando una colonna alla volta.. Tipo la "I" è un 127,0.
Se creo una matrice che ha dentro liste (:confused: parentesi graffe??) di lunghezza fissa avrei 6 spazi vuoti di troppo giusto?

Esattamente, avresti una riga tipo
...
{ ... } /* H */
{127,0,0,0,0,0,0}, /* I */
{ ... } /* J */
...
Si, si usano le parentesi graffe in C per inizializzare vettori/matrici.
Cmq più che "matrice che ha dentro liste" direi che è un vettore di vettori ;)

Utone
27-01-2010, 21:01
E' anche più veloce. Soprattutto con wpython. :cool:
ah! Allora modificherò la sintassi..grazie mille.

Esattamente, avresti una riga tipo
...
{ ... } /* H */
{127,0,0,0,0,0,0}, /* I */
{ ... } /* J */
...
Si, si usano le parentesi graffe in C per inizializzare vettori/matrici.
Cmq più che "matrice che ha dentro liste" direi che è un vettore di vettori ;)
Mmm.. ma cosi non va bene perchè avrei troppo spazio bianco...
Poi ci sono altri caratteri più lungo come ad esempio la W.
I vettori che contengono questi valori non possono avere lunghezza variabile?
Tipo:
{127,0} /* I */
...
{...,...,...,...,...,...,...} /* W*/

Altra domanda:
Una volta riscritto tutto il programma in C lo carichiamo sui pic (a scuola dovremmo avere il 16F877). Ma dopo posso interfacciarlo con bluetooth o modulo gsm?

Utone
28-01-2010, 18:22
Ho cambiato la struttura delle matrici delle lettere e l'ho resa simile ai vettori in Così sarà più facile la trascrizione... qui (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/simulatoreDisplay-0.23.zip?cidReq=105BSISINF) il nuovo codice.. se non riuscite a scaricare lo uppo da qualche altra parte..
Che dici cdimauro? va bene così?

Z80Fan
28-01-2010, 18:26
Mmm.. ma cosi non va bene perchè avrei troppo spazio bianco...
Poi ci sono altri caratteri più lungo come ad esempio la W.
I vettori che contengono questi valori non possono avere lunghezza variabile?
Tipo:
{127,0} /* I */
...
{...,...,...,...,...,...,...} /* W*/

Altra domanda:
Una volta riscritto tutto il programma in C lo carichiamo sui pic (a scuola dovremmo avere il 16F877). Ma dopo posso interfacciarlo con bluetooth o modulo gsm?

Le matrici o vettori dichiarati staticamente (come questi) non possono avere dimensioni variabili, solo quelli dinamici, ma non si possono usare in ambito embedded. Cmq non è un problema per la visualizzazione: fai un ciclo che invia i dati di una lettera solo finchè non trova uno zero.
esempio:
void invia( char lettera )
{
int i=0;
while( matriceSimboli[ (int)lettera][i] != 0 ) //matriceSimboli sarà una variabile globale
{
invia_alla_seriale( matriceSimboli[ (int)lettera][i] );
i++;
}
}
Però diventa un problema se hai una quantità di memoria limitata, dove lo spreco di tutti i byte per tenere gli zero è notevole (beh, bisogna vedere quanti spazi vuoti rimangono effettivamente).
Per la seconda domanda, bisogna vedere come funziona il C del pic. Sicuramente la casa madre avrà dato delle librerie da includere in cui ci sono tutte le funzioni necessarie. Purtroppo non ti so dire altro perchè non ho mai programmato in C per i pic (probabilmente lo facciamo quest'anno), quindi ti posso dare consigli sul linguaggio più che altro.

Utone
28-01-2010, 18:30
Le matrici o vettori dichiarati staticamente (come questi) non possono avere dimensioni variabili, solo quelli dinamici, ma non si possono usare in ambito embedded. Cmq non è un problema per la visualizzazione: fai un ciclo che invia i dati di una lettera solo finchè non trova uno zero.
esempio:
void invia( char lettera )
{
int i=0;
while( matriceSimboli[ (int)lettera][i] != 0 ) //matriceSimboli sarà una variabile globale
{
invia_alla_seriale( matriceSimboli[ (int)lettera][i] );
i++;
}
}
Però diventa un problema se hai una quantità di memoria limitata, dove lo spreco di tutti i byte per tenere gli zero è notevole (beh, bisogna vedere quanti spazi vuoti rimangono effettivamente).
Per la seconda domanda, bisogna vedere come funziona il C del pic. Sicuramente la casa madre avrà dato delle librerie da includere in cui ci sono tutte le funzioni necessarie. Purtroppo non ti so dire altro perchè non ho mai programmato in C per i pic (probabilmente lo facciamo quest'anno), quindi ti posso dare consigli sul linguaggio più che altro.

Per il pic chiedo più info al prof... al max ne facciamo comprare uno più potente...quello che abbiamo noi dovrebbe avere oltre alla rom anche una eeprom interna..
Per il problema degli zeri.. dopo ci sarebbe il problema degli spazi. Lo spazio invia 4 zeri.. e un altra cosa... ogni lettera in fondo ha uno zero per spaziarsi dalla lettera successiva..
Per gli zeri

Z80Fan
28-01-2010, 18:57
Per il pic chiedo più info al prof... al max ne facciamo comprare uno più potente...quello che abbiamo noi dovrebbe avere oltre alla rom anche una eeprom interna..
Per il problema degli zeri.. dopo ci sarebbe il problema degli spazi. Lo spazio invia 4 zeri.. e un altra cosa... ogni lettera in fondo ha uno zero per spaziarsi dalla lettera successiva..
Per gli zeri

Per lo spazio possiamo fare un if che se il carattere passato è uno spazio noi inviamo quattro spazi altrimenti cerchiamo nella tabella. Per lo spaziamento dei caratteri è lo stesso: dopo il while che ho scritto io ci metti un invio di uno zero. Per il pic, penso che serva solo la rom, poichè la eeprom viene usata solo per i dati che devono venir modificati dal pic, queste matrici sono compilate direttamente nel codice del programma. E poi le eeprom sono veramente piccole, tipo 128 byte o poco + perchè servono proprio per memorizzare dati di configurazione ecc... Cmq questa tabella ti occupa intorno ai 800 byte quindi non dovrebbero esserci problemi di spazio, a meno che il pic non sia veramente minuscolo e il programma non sia esageratamente grande.

Utone
28-01-2010, 19:04
Per lo spazio possiamo fare un if che se il carattere passato è uno spazio noi inviamo quattro spazi altrimenti cerchiamo nella tabella. Per lo spaziamento dei caratteri è lo stesso: dopo il while che ho scritto io ci metti un invio di uno zero. Per il pic, penso che serva solo la rom, poichè la eeprom viene usata solo per i dati che devono venir modificati dal pic, queste matrici sono compilate direttamente nel codice del programma. E poi le eeprom sono veramente piccole, tipo 128 byte o poco + perchè servono proprio per memorizzare dati di configurazione ecc... Cmq questa tabella ti occupa intorno ai 800 byte quindi non dovrebbero esserci problemi di spazio, a meno che il pic non sia veramente minuscolo e il programma non sia esageratamente grande.

Non credo ci siano problemi di memoria...
PIC = Peripheral Interface Controller (Controllore di periferiche programmabile)
Il PIC16F877 ha 8k di flash memory (area programma), 368 byte di ram e 256 byte di e2prom. Tutte le istruzioni, ad eccezione di quelle di salto, che ne utilizzano 2, utilizzano 1 ciclo macchina che corrisponde a 4 periodi di clock. Il PIC16F877 può lavorare con un clock compreso da 0 a 20 Mhz, può avere fino a 14 sorgenti diverse di interrupt (da periferiche interne e/o esterne) ed è possibile annidare fino ad 8 chiamate a subroutine in quanto lo Stack ha una profondità pari a 8.
Ha un architettura RISC che significa : Reduced Instruction Set Computing, cioè elaborazione con insieme di istruzioni ridotto.
Le istruzioni sono quindi solo poche decine, sono eseguite molto velocemente e non serve un clock molto elevato per un efficiente funzionamento ( dai 4-8 MHz per i tipi più semplici, fino a 33-50 MHz per i tipi più evoluti)
Supporta la ICSP : In Serial Circuit Programmino cioè la possibilità di programmarlo senza togliere il chip dalla scheda, con un apposito cavetto.

Elenco delle periferiche contenute nel PIC16F877

3 Timer (Timer0 8 bit, Timer1 16 bit e Timer2 8 bit)
2 moduli CCP capture, compare e pwm
8 adc a 10 bit
porta seriale sincrona e i2c
porta di comunicazione parallela (PSP)
porta seriale asincrona (usart)
diversi pin di i/o distribuiti su 5 porte (Porta, Portb, Portc, Portd, Porte)


più o meno per la traduzione in C ci sono.. ora devo cambiare i cicli FOR in WHILE e cambiare la sintassi..
Il più dopo è capire come interfacciarlo con l'esterno senza usare la seriale..

Z80Fan
28-01-2010, 19:10
ora devo cambiare i cicli FOR in WHILE e cambiare la sintassi..
Perchè? esistono i for anche in C :p
Il più dopo è capire come interfacciarlo con l'esterno senza usare la seriale..
Come vorresti interfacciarlo? attraverso parallela, i2c, bluetooth ?

Utone
28-01-2010, 19:44
No i for erano in python.. :fagiano: li trasformavo in while anche su python così poi mi è più facile..

Per l'interfaccia avevamo pensato o al bluetooth in modo da interfacciarsi con un cellulare (sul quale ci sarà un programma possibilmente in java o in python che invia la stringa) o un modulo gsm programmato in modo che se riceve un messaggio da un determinato numero aggiorna la scritta..

cdimauro
29-01-2010, 05:16
Ho cambiato la struttura delle matrici delle lettere e l'ho resa simile ai vettori in Così sarà più facile la trascrizione... qui (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/simulatoreDisplay-0.23.zip?cidReq=105BSISINF) il nuovo codice.. se non riuscite a scaricare lo uppo da qualche altra parte..
Che dici cdimauro? va bene così?
Alcune note:

- usa xrange anziché range (la prima genera i numeri uno alla volta, quando servono; la seconda genera l'intera lista);

- questo pezzo di codice mi sembra che imposti bg sempre a 'black':
if col==self.posizione: bg = 'black'
elif col%5 == 0 :
if col%10 ==0 : bg = 'black'
else: bg = 'black'
else: bg = 'black'

- puoi usare l'espressione if else per calcolare valori in base a una condizione:
led['image'] = self.imgOn if n & (1<<rig) else self.imgOff

- quando devi controllare se un valore è compreso fra due limiti, puoi farlo in un colpo solo:
if 0 <= b <= 127:

- per contare si può utilizzare anche la funzione sum alcune volte:
cnt = sum(1 for z in s for x in lettere[ord(z)])

- in generale tendi a usare n = n + 1 anziché n += 1

Comunque se la tua tendenza è quella di scrivere codice facilmente portabile da Python a C, alcuni di questi consigli ti saranno inutili. :D

Utone
29-01-2010, 14:36
Alcune note:

- usa xrange anziché range (la prima genera i numeri uno alla volta, quando servono; la seconda genera l'intera lista);
la differenza sta nel fatto che range allunga la lista a ogni ciclo e invece xrange crea subito la lista di lunghezza n?
cambierebbe in termini di velocità quindi?
comunque adesso devo eliminare tutti i cicli for e trasformarli in while per il porting in C... al massimo terrò una copia e poi il programma in python lo tengo con i for...

- questo pezzo di codice mi sembra che imposti bg sempre a 'black':
if col==self.posizione: bg = 'black'
elif col%5 == 0 :
if col%10 ==0 : bg = 'black'
else: bg = 'black'
else: bg = 'black'

si.. l aveva messo il mio prof per differenziare il colore ogni 5 colonne ma non mi piaceva e ho messo sempre nero.. ma ho lasciato la funzione nel caso si offendesse..:D

- puoi usare l'espressione if else per calcolare valori in base a una condizione:
led['image'] = self.imgOn if n & (1<<rig) else self.imgOff

grazie sostituito..;)

- quando devi controllare se un valore è compreso fra due limiti, puoi farlo in un colpo solo:
if 0 <= b <= 127:

sostituito..:D

- per contare si può utilizzare anche la funzione sum alcune volte:
cnt = sum(1 for z in s for x in lettere[ord(z)])

lo lascerei così per il porting in C.. comunque se ho capito bene sum è un contatore che conta quanti cicli fa il programma?

- in generale tendi a usare n = n + 1 anziché n += 1

ecco!! ricordavo che c'era la forma contratta ma ho provato n++ ma non funzionava.. (mi ricordavo quella perchè l'avevo usata con il PIC..)


Comunque se la tua tendenza è quella di scrivere codice facilmente portabile da Python a C, alcuni di questi consigli ti saranno inutili. :D
Grazie per tutti i consigli..:)
il programma display e la base del main l'ha scritta il mio prof e non io personalmente...comunque ho fatto alcune correzioni che mi hai detto..
credo che ora sia tranquillamente scrivibile in C :sofico:

Hai idea di come si facciano i filtri digitali? Volevamo implementare in una parte del display un VuMeter. Questa volta però gestito solo dal python via seriale.. non da un Pic.

cdimauro
30-01-2010, 04:59
la differenza sta nel fatto che range allunga la lista a ogni ciclo e invece xrange crea subito la lista di lunghezza n?
No, xrange non crea nessuna lista: quando serve un nuovo numero al for, lo genera al volo.

range, invece, crea l'intera lista, anche se poi il for prenderà un numero alla volta, e alla fine butterà l'intera lista.
cambierebbe in termini di velocità quindi?
Sì.
comunque adesso devo eliminare tutti i cicli for e trasformarli in while per il porting in C... al massimo terrò una copia e poi il programma in python lo tengo con i for...
Tutti i for che usano range/xrange puoi lasciarli così anche in C.
lo lascerei così per il porting in C.. comunque se ho capito bene sum è un contatore che conta quanti cicli fa il programma?
sum fa la somma di tutti i numeri che gli vengono passati. In questo caso gli viene restituito 1 per ogni elemento presente nelle liste, per cui sommandoli tutti effettivamente li hai contati. :D
ecco!! ricordavo che c'era la forma contratta ma ho provato n++ ma non funzionava.. (mi ricordavo quella perchè l'avevo usata con il PIC..)
n++ non c'è e non verrà mai aggiunta al linguaggio.
Grazie per tutti i consigli..:)
il programma display e la base del main l'ha scritta il mio prof e non io personalmente...comunque ho fatto alcune correzioni che mi hai detto..
credo che ora sia tranquillamente scrivibile in C :sofico:
Sì, ma è stato ottimo avere già un programma funzionante con Python. Intanto avete verificato che tutto funzionasse.
Hai idea di come si facciano i filtri digitali? Volevamo implementare in una parte del display un VuMeter. Questa volta però gestito solo dal python via seriale.. non da un Pic.

Dovresti utilizzare l'FFT per ottenere lo spettro del segnale. E' un argomento un po' avanzato.

Utone
30-01-2010, 07:43
No, xrange non crea nessuna lista: quando serve un nuovo numero al for, lo genera al volo.

range, invece, crea l'intera lista, anche se poi il for prenderà un numero alla volta, e alla fine butterà l'intera lista.


Tutti i for che usano range/xrange puoi lasciarli così anche in C.
E come vengono scritti in C ??


sum fa la somma di tutti i numeri che gli vengono passati. In questo caso gli viene restituito 1 per ogni elemento presente nelle liste, per cui sommandoli tutti effettivamente li hai contati. :D
Ah. Gli viene restituito 1 perchè l'abbiamo messo nella parentesi all inizio?

n++ non c'è e non verrà mai aggiunta al linguaggio.
come no?? Lo usavo per incrementare n nei programmi per il pic con compilatore cc5x... lo forse era ++n

Sì, ma è stato ottimo avere già un programma funzionante con Python. Intanto avete verificato che tutto funzionasse.

Dovresti utilizzare l'FFT per ottenere lo spettro del segnale. E' un argomento un po' avanzato.
Ora sono scuola vedo se funziona bene sul tabellone.. :D
Per i filtri mi informerò meglio dopo aver fatto il tutto per il pic... :fagiano:
Grazie per i consigli!!

Ah una cosa... il programma l'hai provato su winzoz o linux?
Mi hanno detto che lo shift su ubuntu non funzia! :confused: :muro:

edit- nada non c'è l'assistente di laboratorio quindi niente prove...

cdimauro
30-01-2010, 08:35
E come vengono scritti in C ??
In Python:
for i in xrange(10):
Codice
In C:
for(i = 0; i < 10; i++) {
Codice
}
Ah. Gli viene restituito 1 perchè l'abbiamo messo nella parentesi all inizio?
Sì, quella in Python si chiama generator expression, e ha la seguente forma:
(ValoreDaRestituire for ElencoVariabili1 in Espressione1 ... for ElencoVariabiliN in EspressioneN if Condizione1 ... if CondizioneM)
Dove almeno il primo for dev'essere presente, mentre tutto il resto, if compresi, è opzionale).
come no?? Lo usavo per incrementare n nei programmi per il pic con compilatore cc5x... lo forse era ++n
Mi riferivo al Python, dove la sintassi n++ non verrà mai implementata.
Ora sono scuola vedo se funziona bene sul tabellone.. :D
Per i filtri mi informerò meglio dopo aver fatto il tutto per il pic... :fagiano:
Grazie per i consigli!!
Figurati.
Ah una cosa... il programma l'hai provato su winzoz o linux?
Onestamente no. Ho guardato soltanto i sorgenti.
Mi hanno detto che lo shift su ubuntu non funzia! :confused: :muro:
Mi sembrano stranissimo.

Z80Fan
30-01-2010, 13:11
Ah una cosa... il programma l'hai provato su winzoz o linux?
Mi hanno detto che lo shift su ubuntu non funzia! :confused: :muro:

E' vero... sul terminale si vedono tantissimi ritorni a capo (praticamente righe vuote), e il prog si blocca per un secondo prima di disattivare da solo lo shift

Utone
30-01-2010, 14:00
E' vero... sul terminale si vedono tantissimi ritorni a capo (praticamente righe vuote), e il prog si blocca per un secondo prima di disattivare da solo lo shift

capito.. nel main guarda la funzione shiftCento. C'è un print che ho dovuto mettere se no nella grafica veniva aggiornato tutto solo alla fine del ciclo..
prova a commentarlo.. io ora non no nessun pc con linux a disposizione quindi non posso provare..

Z80Fan
30-01-2010, 15:59
capito.. nel main guarda la funzione shiftCento. C'è un print che ho dovuto mettere se no nella grafica veniva aggiornato tutto solo alla fine del ciclo..
prova a commentarlo.. io ora non no nessun pc con linux a disposizione quindi non posso provare..

no, niente. esattamente come prima solo senza gli a-capo

Utone
30-01-2010, 18:12
no, niente. esattamente come prima solo senza gli a-capo

Non capisco... su windows va tranquillamente... se metti un print colonne la lista viene shiftata?

Z80Fan
30-01-2010, 18:51
Non capisco... su windows va tranquillamente... se metti un print colonne la lista viene shiftata?

Si, sembra di si. Che sia un bug nell'implementazione dell'interfaccia grafica su Ubuntu?

Utone
30-01-2010, 18:55
Secondo me si.. cioè se su windows non metto il print dopo ogni shift lui mi fa vedere solo il risultato finale dei 100shift e quindi in pratica l'immagine rimane ferma.. Ho provato a mettere il print e ha funzionato e aggiornava ogni volta...
Prova a mettere un altro numero al posto di 100 nel ciclo for dentro shiftCento. Tipo 50.. Dovresti vedere la scritta spostarsi tutta in un colpo di metà tabellone...

Z80Fan
30-01-2010, 18:57
Dovresti vedere la scritta spostarsi tutta in un colpo di metà tabellone...

Si è così

Utone
30-01-2010, 18:59
Si allora è così... Aggiorna la grafica solo alla fine del ciclo...:muro:
Puo fare questa prova?
c'è commentato #time.sleep(...)
Prova a decommentarlo e vedere se aggiorna...

Grazie mille per il supporto... :)

Z80Fan
30-01-2010, 19:00
Forse quando è nel ciclo for non gli lascia gestire gli eventi all'interfaccia grafica?

EDIT : No, non lo fa. Mi è venuta un' idea cmq, aspetta che provo...

Z80Fan
30-01-2010, 19:03
C'è un modo per avere un controllo Timer, in modo che mi richiami una certa funzione ogni tot tempo?

Utone
30-01-2010, 19:23
Si può fare facendo la differenza tra il tempo d'inizio e il tempo di fine ciclo e controllare che si 1 secondo per esempio...

def richiamaFunz():
timeini=time.time()
funzione()
timefin=time.time()
for x in xrange[99]:
if (timefin-timeini)>1:
timeini=time.time()
funzione
timefin=time.time()

non so se funziona però...
dando un help(time) si ha questo
Help on built-in module time:

NAME
time - This module provides various functions to manipulate time values.

FILE
(built-in)

DESCRIPTION
There are two standard representations of time. One is the number
of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer
or a floating point number (to represent fractions of seconds).
The Epoch is system-defined; on Unix, it is generally January 1st, 1970.
The actual value can be retrieved by calling gmtime(0).

The other representation is a tuple of 9 integers giving local time.
The tuple items are:
year (four digits, e.g. 1998)
month (1-12)
day (1-31)
hours (0-23)
minutes (0-59)
seconds (0-59)
weekday (0-6, Monday is 0)
Julian day (day in the year, 1-366)
DST (Daylight Savings Time) flag (-1, 0 or 1)
If the DST flag is 0, the time is given in the regular time zone;
if it is 1, the time is given in the DST time zone;
if it is -1, mktime() should guess based on the date and time.

Variables:

timezone -- difference in seconds between UTC and local standard time
altzone -- difference in seconds between UTC and local DST time
daylight -- whether local time should reflect DST
tzname -- tuple of (standard time zone name, DST time zone name)

Functions:

time() -- return current time in seconds since the Epoch as a float
clock() -- return CPU time since process start as a float
sleep() -- delay for a number of seconds given as a float
gmtime() -- convert seconds since Epoch to UTC tuple
localtime() -- convert seconds since Epoch to local time tuple
asctime() -- convert time tuple to string
ctime() -- convert time in seconds to string
mktime() -- convert local time tuple to seconds since Epoch
strftime() -- convert time tuple to string according to format specification
strptime() -- parse string to time tuple according to format specification
tzset() -- change the local timezone

CLASSES
__builtin__.object
struct_time

class struct_time(__builtin__.object)
| Methods defined here:
|
| __add__(...)
| x.__add__(y) <==> x+y
|
| __contains__(...)
| x.__contains__(y) <==> y in x
|
| __eq__(...)
| x.__eq__(y) <==> x==y
|
| __ge__(...)
| x.__ge__(y) <==> x>=y
|
| __getitem__(...)
| x.__getitem__(y) <==> x[y]
|
| __getslice__(...)
| x.__getslice__(i, j) <==> x[i:j]
|
| Use of negative indices is not supported.
|
| __gt__(...)
| x.__gt__(y) <==> x>y
|
| __hash__(...)
| x.__hash__() <==> hash(x)
|
| __le__(...)
| x.__le__(y) <==> x<=y
|
| __len__(...)
| x.__len__() <==> len(x)
|
| __lt__(...)
| x.__lt__(y) <==> x<y
|
| __mul__(...)
| x.__mul__(n) <==> x*n
|
| __ne__(...)
| x.__ne__(y) <==> x!=y
|
| __reduce__(...)
|
| __repr__(...)
| x.__repr__() <==> repr(x)
|
| __rmul__(...)
| x.__rmul__(n) <==> n*x
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| tm_hour
|
| tm_isdst
|
| tm_mday
|
| tm_min
|
| tm_mon
|
| tm_sec
|
| tm_wday
|
| tm_yday
|
| tm_year
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __new__ = <built-in method __new__ of type object at 0x1E1FDFF0>
| T.__new__(S, ...) -> a new object with type S, a subtype of T
|
| n_fields = 9
|
| n_sequence_fields = 9
|
| n_unnamed_fields = 0

FUNCTIONS
asctime(...)
asctime([tuple]) -> string

Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.
When the time tuple is not present, current time as returned by localtime()
is used.

clock(...)
clock() -> floating point number

Return the CPU time or real time since the start of the process or since
the first call to clock(). This has as much precision as the system
records.

ctime(...)
ctime(seconds) -> string

Convert a time in seconds since the Epoch to a string in local time.
This is equivalent to asctime(localtime(seconds)). When the time tuple is
not present, current time as returned by localtime() is used.

gmtime(...)
gmtime([seconds]) -> (tm_year, tm_mon, tm_mday, tm_hour, tm_min,
tm_sec, tm_wday, tm_yday, tm_isdst)

Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.
GMT). When 'seconds' is not passed in, convert the current time instead.

localtime(...)
localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,
tm_sec,tm_wday,tm_yday,tm_isdst)

Convert seconds since the Epoch to a time tuple expressing local time.
When 'seconds' is not passed in, convert the current time instead.

mktime(...)
mktime(tuple) -> floating point number

Convert a time tuple in local time to seconds since the Epoch.

sleep(...)
sleep(seconds)

Delay execution for a given number of seconds. The argument may be
a floating point number for subsecond precision.

strftime(...)
strftime(format[, tuple]) -> string

Convert a time tuple to a string according to a format specification.
See the library reference manual for formatting codes. When the time tuple
is not present, current time as returned by localtime() is used.

strptime(...)
strptime(string, format) -> struct_time

Parse a string to a time tuple according to a format specification.
See the library reference manual for formatting codes (same as strftime()).

time(...)
time() -> floating point number

Return the current time in seconds since the Epoch.
Fractions of a second may be present if the system clock provides them.

DATA
accept2dyear = 1
altzone = -7200
daylight = 1
timezone = -3600
tzname = ('ora solare Europa occidentale', 'ora legale Europa occident...

Z80Fan
30-01-2010, 19:57
ho trovato una soluzione al tuo problema:
Queste sono le modifiche fatte:


def cancella():
global statoShift
#statoShift=0 #lasciamo modificare la variabile statoShift solo in stopShift e shiftCento
scriviColonne('~') #carattere speciale che useremo per resettare
aggiornaTkDisplay()





def scrivi():
global statoShift
cancella()
#statoShift=1 # come sopra
testo=entry.get()
try:
scriviColonne(testo)
except:
error.grid(row=5,column=0,pady=5)
but4.grid(row=6,column=0,pady=5)
aggiornaTkDisplay()





def stopShift():
global statoShift
statoShift=0
but5.grid_forget()
but3.grid(row=4,column=0,pady=5)



def shift():
colonneShift=colonne[:]
n=1
colonne[0]=colonneShift[99]
for k in colonneShift:
if n<100:
colonne[n]=k
n=n+1




def shiftCento(): #questa ora dovrebbe chiamarsi "startShift"
global statoShift
# if statoShift==1: #non vedo l'utilità di questo test, i bottoni li devi modificare cmq.
but3.grid_forget()
but5.grid(row=4, column=0, pady=5)
statoShift=1
clock()


def clock(): #dopo un po' di tempo, esegui uno shift e torna in attesa
if statoShift == 1: #qui si dobbiamo vedere se lo shift è ancora attivo
shift()
aggiornaTkDisplay()
root.after(100, clock)

Non ho mai programmato in Python, spero che il codice sia giusto, per lo meno mi funziona ;)

EDIT: Ho visto ora il tuo post sul tempo, non era proprio quello che avevo in mente, cmq ho già sistemato come vedi :)

Utone
30-01-2010, 20:09
def cancella():
global statoShift
#statoShift=0 #lasciamo modificare la variabile statoShift solo in stopShift e shiftCento
scriviColonne('~') #carattere speciale che useremo per resettare
aggiornaTkDisplay()

def scrivi():
global statoShift
cancella()
#statoShift=1 # come sopra
testo=entry.get()
try:
scriviColonne(testo)
except:
error.grid(row=5,column=0,pady=5)
but4.grid(row=6,column=0,pady=5)
aggiornaTkDisplay()

se non lo metto prima a zero e poi a uno se schiaccio scrivi mentre sta shiftando una scritta la nuova scritta parte a shiftare da sola...

def shiftCento(): #questa ora dovrebbe chiamarsi "startShift"
global statoShift
# if statoShift==1: #non vedo l'utilità di questo test, i bottoni li devi modificare cmq.
but3.grid_forget()
but5.grid(row=4, column=0, pady=5)
statoShift=1
clock()
quel controllo serve perchè se shift è a zero e premo il pulsante "shift" deve rimanere il pulsante "shift" e non "ferma" perchè lo shift non è partito.

Funziona a te con le modifiche che hai fatto?

Z80Fan
30-01-2010, 20:17
se non lo metto prima a zero e poi a uno se schiaccio scrivi mentre sta shiftando una scritta la nuova scritta parte a shiftare da sola...
Ah d'accordo tu non vuoi avere questo effetto, allora si, metti pure a zero. Anzi, ti consiglio di richiamare il stopShift(), perchè se sta shiftando e tu premi cancella, lo shift si ferma , ma i bottoni non vengono reimpostati e ti rimane "ferma shift" anche con lo shift spento.

quel controllo serve perchè se shift è a zero e premo il pulsante "shift" deve rimanere il pulsante "shift" e non "ferma" perchè lo shift non è partito.
beh, ma dopo aver settato la variabilestatoShift=1 e aver impostato i pulsanti, avvio cmq un ciclo di shift, quindi non dovresti avere troppi problemi.

Funziona a te con le modifiche che hai fatto?
Si, perfettamente.

Utone
30-01-2010, 20:23
Ah d'accordo tu non vuoi avere questo effetto, allora si, metti pure a zero. Anzi, ti consiglio di richiamare il stopShift(), perchè se sta shiftando e tu premi cancella, lo shift si ferma , ma i bottoni non vengono reimpostati e ti rimane "ferma shift" anche con lo shift spento.
Ah giusto! modificherò...:sofico:

beh, ma dopo aver settato la variabilestatoShift=1 e aver impostato i pulsanti, avvio cmq un ciclo di shift, quindi non dovresti avere troppi problemi.
Ora che me lo fai notare c'è qualcosa che non va..
Devo trovare un modo per gestire questa cosa...

Si, perfettamente.
Beneee! Sei un genio! :oink:

Z80Fan
30-01-2010, 20:28
Ora che me lo fai notare c'è qualcosa che non va..
Devo trovare un modo per gestire questa cosa...

Ok, fammi sapere :D

cdimauro
31-01-2010, 03:44
C'è un modo per avere un controllo Timer, in modo che mi richiami una certa funzione ogni tot tempo?
Arrivo tardi, comunque:

17.2.7. Timer Objects
This class represents an action that should be run only after a certain amount of time has passed — a timer. Timer is a subclass of Thread and as such also functions as an example of creating custom threads.

Timers are started, as with threads, by calling their start() method. The timer can be stopped (before its action has begun) by calling the cancel() method.

The interval the timer will wait before executing its action may not be exactly the same as the interval specified by the user.

For example:
def hello():
print "hello, world"

t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed
class threading.Timer(interval, function, args=[], kwargs={})
Create a timer that will run function with arguments args and keyword arguments kwargs, after interval seconds have passed.

Timer.cancel()
Stop the timer, and cancel the execution of the timer’s action. This will only work if the timer is still in its waiting stage.

Utone
31-01-2010, 19:04
Per risolvere il problema dello stato shift avevo pensato ad un flip flop set reset.
Dove le due entrare sarebbero abilitaShift e disabilitaShift.
Si può implementare con Pythone?

Ora che ci penso è inutile tanto quando andrà su pic non serve..

Perchè? esistono i for anche in C :p

Come vorresti interfacciarlo? attraverso parallela, i2c, bluetooth ?
Questo post mi era scappato o l'avevo letto male..

Il ciclo for in c si fa cosi:
for(<inizializzazione>; <test>; <incremento>)
<istruzione>;
quindi un
for x in range[10]:
istruzioni
diventerebbe

char x
for(x=0;x<10;1)
istruzioni

giusto?

DanieleC88
01-02-2010, 10:34
Il ciclo for in c si fa cosi:
for(<inizializzazione>; <test>; <incremento>)
<istruzione>;
quindi un
for x in range[10]:
istruzioni
diventerebbe

char x
for(x=0;x<10;1)
istruzioni

giusto?
No, così non incrementa un bel niente: al posto dell'1 mettici un ++x (o x++ o x = (x + 1)... insomma, un incremento :p).

Utone
01-02-2010, 10:37
No, così non incrementa un bel niente: al posto dell'1 mettici un ++x (o x++ o x = (x + 1)... insomma, un incremento :p).

ah ok!! Credevo che ci andasse solo di quando andasse incrementato... :mc:

DanieleC88
01-02-2010, 10:42
"Purtroppo" no... hai la libertà di metterci le istruzioni che ti pare, può tornare comodo perché se scorri una lista invece che un'array lì puoi metterci un node = node->next, per esempio. (Anzi, se usi delle comma expressions puoi fare anche più incrementi alla volta, però è un insulto alla leggibilità del codice. :p)

Utone
01-02-2010, 15:30
Potresti spiegarmi o indirizzarmi verso una guida dove spiega questo?
node = node->next
serve per attraversare il vettore?

Utone
01-02-2010, 16:34
Qui (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Software/simulatoreDisplay-0.25.zip?cidReq=105BSISINF) la nuova versione.. Potete guardarla e magari alcuni consigli su come migliorarla.. :D
(per ubuntu a scuola sono riuscito a farlo andare senza modifiche al codice.. solo installando tutte le librerie)

L' "ultima" implementazione da fare sarebbe quella della scritta lunga...
Cioè io gli dò una scritta che occupa più delle 100 colonne e lui me la fa scorrere sul tabellone...
bisognerebbe fare una nuova lista e usarla come se fosse colonne e poi copio su colonne i primi 100 valori, aggiorno il display, e poi faccio scorrere la nuova lista dentro colonne aggiornando il display ogni volta. Giusto il ragionamento?

Z80Fan
01-02-2010, 17:36
Potresti spiegarmi o indirizzarmi verso una guida dove spiega questo?
node = node->next
serve per attraversare il vettore?

No, serve per scorrere una lista, al minimo semplicemente concatenata. Non avete fatto le liste a scuola? :eek:

for(<inizializzazione>; <test>; <incremento>)
<istruzione>;

Più che "incremento", io metterei "istruzione da farsi alla fine di ogni ciclo", ma è troppo lungo ;) Diciamo che un for di questo tipo:

for(<a>; <b>; <c>)
<d>

è equivalente a questo ciclo while:

<a>
while( <b> )
{
<d>

<c>
}


(per il vettore basta il classico vettore[indice] giusto per essere chiari;) )

Utone
01-02-2010, 17:39
Sei stato chiarissimo... grazie mille... :D :D

DanieleC88
01-02-2010, 17:42
Potresti spiegarmi o indirizzarmi verso una guida dove spiega questo?
node = node->next
serve per attraversare il vettore?
No, non un vettore, ma una lista di nodi collegati tra di loro attraverso puntatori al successivo ed al precedente elemento. Te lo potrei spiegare tranquillamente, ma poi andiamo off-topic. :D (Quindi mi limito a Wikipedia: http://it.wikipedia.org/wiki/Lista_concatenata#Liste_doppiamente_concatenate)

P.S.: come non detto, Z80Fan non si è fatto grossi problemi... :p

Z80Fan
01-02-2010, 18:04
Cioè io gli dò una scritta che occupa più delle 100 colonne e lui me la fa scorrere sul tabellone...
bisognerebbe fare una nuova lista e usarla come se fosse colonne e poi copio su colonne i primi 100 valori, aggiorno il display, e poi faccio scorrere la nuova lista dentro colonne aggiornando il display ogni volta. Giusto il ragionamento?
Si, è corretto come ragionamento. Stavo pensando a come poterlo ottimizzare in velocità, ma penso che questo sia cmq abbastanza veloce; l'unica cosa è che se devi implementarlo in un PIC non ti puoi permettere di sprecare troppa memoria... io opterei per una funzione che ti genera sul momento i valori corretti, avendo la stringa da visualizzare e lo scostamento da generare; poi quando devi fare uno shift incrementi l' "offset" e richiami la funzione che ti rigenera il nuovo set di numeri da passare al display. Non so se son stato chiaro...

P.S.: come non detto, Z80Fan non si è fatto grossi problemi... :p
C'ho già troppi problemi col Sistema Operativo (vedi nuova firma ... :D )

Utone
01-02-2010, 19:04
Si, è corretto come ragionamento. Stavo pensando a come poterlo ottimizzare in velocità, ma penso che questo sia cmq abbastanza veloce; l'unica cosa è che se devi implementarlo in un PIC non ti puoi permettere di sprecare troppa memoria... io opterei per una funzione che ti genera sul momento i valori corretti, avendo la stringa da visualizzare e lo scostamento da generare; poi quando devi fare uno shift incrementi l' "offset" e richiami la funzione che ti rigenera il nuovo set di numeri da passare al display. Non so se son stato chiaro...

In pratica tu dici:
-Genero la lista (più lunga di 100 byte) con tutti i byte dalla stringa che passo
-Primi 100 byte sul display
-Ciclo di Shift (però ora devo mettere in testa i nuovi byte e non ricopiare quelli in coda) e a ogni ciclo aggiorno. Giusto?

No, serve per scorrere una lista, al minimo semplicemente concatenata. Non avete fatto le liste a scuola? :eek:

Questo pezzo non l'ho capito.. chiederò al prof che a voce sarà sicuramente più facile spiegarlo..
No il C l'abbiamo usato poco... io faccio elettronica e telecomuicazioni.. Abbiamo fatto soprattutto python. Il C l'abbiamo usato pochissimo su pc e poi un po' su pic..

Utone
01-02-2010, 21:38
Ci sono riuscitoooooo!
Qui (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Software/simulatoreDisplay-0.27.zip?cidReq=105BSISINF) la nuova versione.

Che ne pensate?

Ps: dovrei chiedere a un mod di cambiare titolo. Andrebbe bene "[PythonToC] Comando display 100*7 via seriale" ??

Z80Fan
02-02-2010, 13:50
Che ne pensate?
Penso che in Python và bene, ma se devi trasportarlo in C sorge questo problema: Quanto grande lo fai l'array per la "listaLunga" ? Poichè lavori su un pic e non hai a disposizione l'allocazione dinamica della memoria, devi definire i vettori a dimensione fissa. O limiti la stringa ad un valore massimo e calcoli la lunghezza del vettore in funzione del caso peggiore (cioè quando la stringa è piena del più largo carattere che hai), o devi cambiare metodo (la stringa la dovrai cmq limitare ad un tot, ma con un algoritmo diverso potresti aumentarla di più senza pericolo di dover aumentare di troppo la lunghezza del vettore dei dati per il display)

Ieri sera ero venuto fuori con una soluzione di questo tipo (poi ho perso la connesssione e non la ho più inviata) :
--------
In pratica tu dici:
-Genero la lista (più lunga di 100 byte) con tutti i byte dalla stringa che passo
-Primi 100 byte sul display
-Ciclo di Shift (però ora devo mettere in testa i nuovi byte e non ricopiare quelli in coda) e a ogni ciclo aggiorno. Giusto?

No, veramente questo (a quanto avevo capito) lo volevi fare tu. La mia versione è un po' + complicata. Nella mia versione, hai il vettore di solo 100 byte, e la stringa. Una funzione deve generare direttamente l'immagine già shiftata da passare al display, e dovrai richiamare questa funzione ad ogni ciclo di shift. La versione per il tuo display è un po' più complessa perchè hai caratteri di larghezza variabile... vediamo se riesco a codificarla in qualche modo:


// ipotizzando che il vettore con i dati per il display sia definito così:
unsigned char datiDisplay[100];

void funzione( char *stringa, int offsetShift )
{

int lung = lunghezza_in_colonne_della_stringa( s );
int is = 0; // indice all'interno della stringa
int id = 0; // indice all'interno dei dati display
int c, c2; // contatore per il for


// questo codice serve per trovare in quale carattere si trova la prima colonna da visualizzare
offsetShift = offsetShift % lung;
while( offsetShift > 0 )
{
for(c=0; (c < larghezzaLettera( stringa[is] )) && (offsetShift>0); c++)
{
offsetShift -- ;
}
if( offsetShift > 0 ) is++; //passiamo alla prossima lettera, solo se non siamo usciti a causa della fine di offsetShift
}

// ora copiamo la parte visibile nei dati per il display, finchè o non finiscono
// le righe, o finchè non finisce la stringa
while( (stringa[is] != '\0') && (id<100) )
{
for( /* lascio la C al valore che aveva prima */; (c < larghezzaLettera( stringa[is] ) ) && (id<100); c++)
{
datiDisplay[id] = matriceCaratteri[ (int)stringa[is] ][c] ;
id++;
}
is++
}

if( id<100 ) // se c'è ancora posto nel display (è uscito dal ciclo perchè ha finito la stringa
{
id += SPAZIO_FRA_CARATTERI; // salto un piccolo spazio e ricomincio dall'inizio della stringa
for(c=0; id<100; c++)
{
for(c2=0; c2<larghezzaLettera( stringa[c] ) && id<100; c2++)
{
datiDisplay[id] = matriceCaratteri[ (int)stringa[c] ][c2];
id++;
}
}
}

} //fine funzione


---------

Ora faccio un veloce programma in C e Allegro per vedere se ho ragione :D

Ps: dovrei chiedere a un mod di cambiare titolo. Andrebbe bene "[PythonToC] Comando display 100*7 via seriale" ??
Io opterei per un "[Python]->[C] Invio dati a display led 100*7 tramite seriale, conversione da python a C per PIC.", o forse è un po' troppo lungo ? :D

cionci
02-02-2010, 14:36
Z80Fan: gli stai facendo tutta la tesina tu, questo non è corretto ;)

Z80Fan
02-02-2010, 14:42
Z80Fan: gli stai facendo tutta la tesina tu, questo non è corretto ;)

Mi son dimenticato che era una tesi ... ;)

Cmq sei poi non lo sà spiegare al prof, non ci fà niente lo stesso ;)

Utone
02-02-2010, 14:48
Mi son dimenticato che era una tesi ... ;)

Cmq sei poi non lo sà spiegare al prof, non ci fà niente lo stesso ;)

infatti il tuo codice non l'ho capito tanto..:muro: :muro:
Ora che abbiamo una versione in python completa cominciamo il porting in C e ci facciamo spiegare un po' di C dal prof...
Per il problema della memoria se non basta useremo una memoriaflash per il Pic..

Z80Fan
02-02-2010, 15:00
infatti il tuo codice non l'ho capito tanto..:muro: :muro:
Ora che abbiamo una versione in python completa cominciamo il porting in C e ci facciamo spiegare un po' di C dal prof...
Per il problema della memoria se non basta useremo una memoria flash per il Pic..

Beh la memoria flash ti serve poco, perchè ti serve sopratutto memoria ram per elaborare i dati, altrimenti diventerebbe lentissimo. diciamo che con 368 byte dovresti riuscire ad arrivare anche a 256 byte per il vettore di dati, e limitare la stringa a 32 caratteri (cioè il caso peggiore, con tutti caratteri di 7 colonne + 1 colonna per lo spazio tra lettere).

Cmq il programma con Allegro me lo faccio cmq per conto mio, così almeno mi rilasso un po' da quel cavolo di kernel ;)

Utone
02-02-2010, 15:22
Beh la memoria flash ti serve poco, perchè ti serve sopratutto memoria ram per elaborare i dati, altrimenti diventerebbe lentissimo. diciamo che con 368 byte dovresti riuscire ad arrivare anche a 256 byte per il vettore di dati, e limitare la stringa a 32 caratteri (cioè il caso peggiore, con tutti caratteri di 7 colonne + 1 colonna per lo spazio tra lettere).

Cmq il programma con Allegro me lo faccio cmq per conto mio, così almeno mi rilasso un po' da quel cavolo di kernel ;)

Bhe la uso per copiarci dentro le bitmap dei caratteri e le varie liste...


Poi me lo fai vedere il programma vero? :sofico:
Cos'è allegro? :confused:

Z80Fan
02-02-2010, 15:29
Bhe la uso per copiarci dentro le bitmap dei caratteri e le varie liste...

Le bitmaps stanno dentro alla rom insieme al codice, poichè sono delle costanti. Diciamo che se le metti in flash le potresti modificare senza ricompilare il programma.

Poi me lo fai vedere il programma vero? :sofico:
Come nooo ... ^^

Cos'è allegro? :confused:
Una libreria che ti permette di fare grafica con C/C++.

Utone
02-02-2010, 15:33
Le bitmaps stanno dentro alla rom insieme al codice, poichè sono delle costanti. Diciamo che se le metti in flash le potresti modificare senza ricompilare il programma.


Come nooo ... ^^


Una libreria che ti permette di fare grafica con C/C++.

Le bitmaps le terrei nella flash così mi tengo pulito il programma..
La flash credo che mi serva comunque perchè ci serve avere la possibilità di inserire una lista abbastanza lunga...

Grazie mille per il programma... sempre se riuscirò a capirlo! :D

Z80Fan
02-02-2010, 15:36
Grazie mille per il programma... sempre se riuscirò a capirlo! :D
Non ho detto che funzioni ... ;)

Utone
02-02-2010, 15:41
Non ho detto che funzioni ... ;)

Beh almeno troverò qualche dritta spero..:)

dalla prossima lezione iniziamo a fare il porting e saranno dolori.... :doh:

Z80Fan
02-02-2010, 15:45
Beh almeno troverò qualche dritta spero..:)

dalla prossima lezione iniziamo a fare il porting e saranno dolori.... :doh:

Dai non sarà un così gran trauma :sofico:
Cmq ti conviene andare col tuo metodo (vettore lungo) e se ti resta tempo interpreta e sistema il mio codice.

Utone
04-02-2010, 08:11
Sono riuscito a recuperare il programma del pic master...
Solo che non ho capito cosa mi trasmette, il protocollo di comunicazione che hanno fatto gli altri ragazzi. Voi lo capite?
Il programma è QUI (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Documenti/endmast.c?cidReq=105BSISINF)

Ora stiamo commentando il codice visto che loro non avevano commentato niente!

Utone
06-02-2010, 11:15
Abbiamo commentato un po' il programma del pic master (che non abbiamo fatto noi.). Qui (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Documenti/pic_Master/endmast_%28commentato%29_v0.2.c.c?cidReq=105BSISINF) per il download...qualche consiglio per migliorarlo??

Bisognerebbe fare un protocollo per migliorarlo..
Perchè quando noi fare la nuova scheda, questa deve comunicare in seriale in trasmissione sia con il pc che con il tabellone, e in ricezione dal pc ( e si vedrà per il tabellone). Quindi servirebbero 2 asincrone ma il pic ne ha solo una. :mc:

cionci
06-02-2010, 11:21
Metti un adattatore seriale<->usb

Utone
06-02-2010, 11:23
la scuola ci ha già preso un adattatore seriale/bluetooth.. ma poi come risolvo? sia per l adattatore usb che bluetooth la seriale serve sempre.. o no?

cionci
06-02-2010, 11:28
Avevo letto PC invece di PIC :D

Utone
06-02-2010, 11:31
Avevo letto PC invece di PIC :D

ahhh.. :D magari fosse quello il problema..
comunque il prof aveva pensato di mettere un multiplexer sulla seriale ma poi diventava troppo complicato.. quindi abbiamo abbandonato quella strada e scelto di operare sul protocollo del pic master del tabellone. Solo che prima bisogna comprenderlo bene.. purtroppo i ragazzi che l hanno fatto hanno lasciato pochissima documentazione.. :muro:

Utone
13-02-2010, 22:10
UP :sofico:

Abbiamo perfezionato il programma in python. Download QUI (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Software/simulatoreDisplay/simulatoreDisplay-0.27.zip?cidReq=105BSISINF).

e abbiamo fatto alcune modifiche al programma del pic Master.
Qui (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Documenti/pic_Master/endmast_%28commentato%29_v0.3.c?cidReq=105BSISINF)programma originale commentato
e qui (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Software/picMaster/picMaser_v0.2.c?cidReq=105BSISINF) programma modificato da noi

Nel tabellone saranno aggiunte le funzioni di orologio (batteria tampone sul pic) e termometro (su hw con LM35).

Z80Fan
14-02-2010, 10:15
UP :sofico:

Abbiamo perfezionato il programma in python. Download QUI (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Software/simulatoreDisplay/simulatoreDisplay-0.27.zip?cidReq=105BSISINF).

e abbiamo fatto alcune modifiche al programma del pic Master.
Qui (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Documenti/pic_Master/endmast_%28commentato%29_v0.3.c?cidReq=105BSISINF)programma originale commentato
e qui (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Software/picMaster/picMaser_v0.2.c?cidReq=105BSISINF) programma modificato da noi

Nel tabellone saranno aggiunte le funzioni di orologio (batteria tampone sul pic) e termometro (su hw con LM35).

Ciao.
Ho dato un'occhiata al programma python, ma non funziona ancora su ubuntu :cry: ma mi fido di te e presumo che funzioni correttamente ;)

Invece posso darti dei consigli sulla programmazione C, e sopratutto su eventuali ottimizzazioni:
void service_i2c(); //inizializzo la funzione
No, non la inizializza, la dichiara, quella riga viene chiamata "prototipo" della funzione. Se tu in una funzione chiami una funzione che però è scritta più in basso nel file, la devi dichiarare prima, o il compilatore non saprà cosa fare perchè non la ha mai incontrata prima (il python ti abitua troppo bene :D )
int_save_registers //NON CAPISCO COSA FA!!!!!!!!!

char sv_FSR = FSR;
Forse serve... per salvare i registri? ;) Avete mai studiato una routine di servizio di un comune processore? Si salvano i registri usati per non sporcarli.

case 0: PORT0[b] =c; b++; TXREG = c; break; //nel caso la variabile a sia a 0, cioè il pic selezionato sia il primo scrive sulla colonna
case 1: PORT2[b] =c; b++; TXREG = c; break; //b del primo pic
case 2: PORT4[b] =c; b++; TXREG = c; break;
case 3: PORT6[b] =c; b++; TXREG = c; break; //i valori restituiti sono visualizzabili su hyperterminal
case 4: PORT8[b] =c; b++; TXREG = c; break;
case 5: PORT10[b] =c; b++; TXREG = c; break;
case 6: PORTX[b] =c; b++; TXREG = c; break; //ultimo pic
Dovresti evitare come la peste di scrivere codice ripetuto, poichè aumenta inutilmente la dimensione del codice. Dovresti trovare (se possibile) una formula matematica per individuare subito il valore invece di fare degli switch (quì non è possibile ma vedrai dopo). Quì ad esempio ci sono il b++ e il TXREG=c che sono ripetuti, puoi toglierli da ogni case e metterli subito sotto lo switch.

switch (c) { //c=valore ricevuto dalla seriale // scelgo il pic su cui scrivere
case 200: a=0; b=0; TXREG = c; break; //primo pic
case 201: a=1; b=0; TXREG = c; break;
case 202: a=2; b=0; TXREG = c; break;
case 203: a=3; b=0; TXREG = c; break;
case 204: a=4; b=0; TXREG = c; break;
case 205: a=5; b=0; TXREG = c; break;
case 206: a=6; b=0; TXREG = c; break; //ultimo pic
}
idem qui, ed ora vedi cosa intendo per formula: questo codice non lo puoi scrivere semplicemente:

a = (c-200);
b = 0;
TXREG = c;

? Oppure:
switch (a) { // trasmetto pic attuale
case 0: TXREG=247;break; //possibilmente da cambiare mettendo il pic master con valore di ritorno 252 e il pic 0
case 1: TXREG=248;break; //con valore di ritorno 246 per averli in ordine dal primo all´ultimo
case 2: TXREG=249;break;
case 3: TXREG=250;break;
case 4: TXREG=251;break;
case 5: TXREG=252;break;
}
In
TXREG = a+247;

if ( f==2 ) { //f e g sono come a e b cioè f=pic selezionato, g=colonna selezionata
while(g<15) { trasf=PORT0[g];TX[g]=trasf; g++; } //copio quello che ho sul PORTO sul vettore TX che ha 15 segmenti
g=0; pic=21; //riporto la colonna a 0 //non capisco l'utilità della variabile "pic"...????????
} // SELEZIONE IL NOME IN SWITCH(PIC) //??????????????
else if ( f==4 ) {
while(g<15) { trasf=PORT2[g];TX[g]=trasf; g++; }
g=0; pic=21;
}
else if ( f==6 ) {
while(g<15) { trasf=PORT4[g];TX[g]=trasf; g++; }
g=0; pic=21;
}
Questo è estremamente ottimizzabile, ma te lo lascio fare a te :D
(In effetti la variabile pic non viene mai usata)
/* ------------ conversione PORTn a PORTx ---------- */
switch(col) {
case 0: PORTA = PORTX[0];
PORTB.5 = PORTX[0].6; break;
case 2: PORTA = PORTX[1];
[...]
case 7: PORTA = 0b0000.0000;
PORTB.5 = 0; break;
case 9: PORTA = 0b0000.0000;
PORTB.5 = 0; break;
}

switch(col) {
case 0: PORTD = PORTX[5]; break;
case 2: PORTD = PORTX[6]; break;
[...]
case 7: PORTD = 0b0000.0000; break;
case 9: PORTD = 0b0000.0000; break;
}
Vediamo se riesci a compattare questo codice, ti dico solo che devi usare solo 1 if, 1 else e devi usare al massimo 12 righe (esclusi gli spazi bianchi) :D

Utone
14-02-2010, 10:39
I commenti non li ho fatti io ma un altro del gruppo.. Io ho modificato il programma e basta..:)
grazie mille per gli utilissimi suggerimenti...
(mi sembra che tu stia guardando il programma originale e non quello modificato)

Il primo pezzo di codice come lo comprimeresti?? con uno switch?

Il secondo pezzo:

if (col%2==1){
PORTA = 0b0000.0000;
PORTB.5 = 0;
PORTD = 0b0000.0000; break;
}else {
PORTA = PORTX[col/2];
PORTB.5 = PORTX[col/2].6;
PORTD = PORTX[((col/2)+5)]; break;

posso fare operazioni così o mi devo inizializzare una variabile??

Z80Fan
14-02-2010, 10:50
I commenti non li ho fatti io ma un altro del gruppo.. Io ho modificato il programma e basta..:)
grazie mille per gli utilissimi suggerimenti...
(mi sembra che tu stia guardando il programma originale e non quello modificato)

Io ho guardato endmast_(commentato)_v0.3.c


Il primo pezzo di codice come lo comprimeresti?? con uno switch?

Ho usato un while e uno switch


Il secondo pezzo:

if (col%2==1){
PORTA = 0b0000.0000;
PORTB.5 = 0;
PORTD = 0b0000.0000; break;
}else {
PORTA = PORTX[col/2];
PORTB.5 = PORTX[col/2].6;
PORTD = PORTX[((col/2)+5)]; break;

posso fare operazioni così o mi devo inizializzare una variabile??
Esatto, esattamente come ho fatto io :D (attento hai lasciato 2 break e hai dimenticato una parentesi chiusa ;) )
certo puoi fare tranquillamente queste operazioni, almeno in C comune; dovresti vedere cosa ti dice il compilatore per il pic, perchè di solito sono molto + restrittivi. al massimo se ti dà problemi con il modulo puoi scrivere l'equivalente (col&1) e per la divisione per due (col>>1).

Utone
14-02-2010, 11:00
Prova a guardare questo (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Software/picMaster/picMaser_v0.2.c?cidReq=105BSISINF). Abbiamo fatto piccole modifiche...

allora vediamo..
while(g<15){
switch(f){
case 0: trasf=PORT0[g]; break;
case 1: trasf=PORT2[g]; break;
case 2: trasf=PORT4[g]; break;
case 3: trasf=PORT6[g]; break;
case 4: trasf=PORT8[g]; break;
case 5: trasf=PORT10[g]; break;
}
TX[g]=trasf; g++
}
g=0

Giusto?

Z80Fan
14-02-2010, 11:09
Prova a guardare questo (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Software/picMaster/picMaser_v0.2.c?cidReq=105BSISINF). Abbiamo fatto piccole modifiche...

allora vediamo..
while(g<15){
TX[g]=trasf; g++;
switch(f){
case 0: trasf=PORT0[g]; break;
case 1: trasf=PORT2[g]; break;
case 2: trasf=PORT4[g]; break;
case 3: trasf=PORT6[g]; break;
case 4: trasf=PORT8[g]; break;
case 5: trasf=PORT10[g]; break;
}
TX[g]=trasf;
}
g=0

Giusto?

Ahi Ahi Ahi....
La sintassi è giusta, ma c'è un errore logico ;)
TX[g]=trasf; g++;
Questi li devi mettere dopo lo switch (e puoi togliere il secondo), perchè se vedi il codice originale
{ trasf=PORT4[g];TX[g]=trasf; g++; }
prima modifica trasf, poi tx[g] e poi incremente g. Con il tuo codice modificavi l'ordine delle istruzioni.
Per il resto è corretto :D

Il secondo listato non è che abbiamo molte modifiche, dovresti riuscire ad adattare i consigli anche a quello nuovo.

Utone
14-02-2010, 11:11
:doh: era il rimanente di un copia-incolla..:sofico:

si volevo mettero come dici tu dopo lo switch..:D

si se guardi ho corretto solo un il protocollo (l'ho compattatto tutto dopo il 128 senza valori sparsi) e ho (credo) corretto l'indirizzamento del pic che prima non cambiava f.
Ora modifico e carico..:)

Utone
14-02-2010, 11:34
Fatto!
Eccolo qui (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Software/picMaster/picMaser_v0.3.c?cidReq=105BSISINF).
Il nome del file è "picMaser_v0.3.c". :D

Utone
02-03-2010, 10:10
uppo la discussione perché ci siamo arenaiti...
Da quanto ho capito il pic non gestisce le stringhe, quindi dovremmo trasformare la stringa..
Solo che visto che non ho mai usato liste e array in C non so quale usare..
Qualcuno potrebbe aiutarmi almeno a iniziare?

Utone
05-03-2010, 09:03
up

come faccio a trasformare una lettera nel suo codice ASCII??
Per esempio A in 65.

Altra domanda, è possibile usare l'array di array in ambito embedded?

kk3z
05-03-2010, 09:30
int num = 'A'+0; //65

DanieleC88
05-03-2010, 11:31
int num = 'A'+0; //65

int num = (int) 'A';

cionci
05-03-2010, 11:43
int num = (int) 'A';
Perché ?

Utone
05-03-2010, 14:03
mmmh, quindi qual'è la versione giusta?

Per l array di array?

DanieleC88
05-03-2010, 17:16
Perché ?

http://www.youtube.com/watch?v=14ABu_msibM

:p

DanieleC88
05-03-2010, 17:17
Altra domanda, è possibile usare l'array di array in ambito embedded?
Il limite dov'è?

Utone
05-03-2010, 17:19
il compilatore (cc5x) dava errore..
come li inzializzo?

Z80Fan
06-03-2010, 16:52
il compilatore (cc5x) dava errore..
come li inzializzo?
I compilatori per sistemi embedded sono molto rompipalle, non tutto si può fare del C normale.
Cmq un array multidimensionale (in C normale) si inizializza così:

int array[numX][numY] =
{
{ elemY0, elemY1, elemY2 ... elemYn }, // questo per numX che vale 0
{ elemY0, elemY1, elemY2 ... elemYn }, // questo per numX che vale 1
{ elemY0, elemY1, elemY2 ... elemYn }, // questo per numX che vale 2
{ elemY0, elemY1, elemY2 ... elemYn } // questo per numX che vale 3
};

Utone
16-03-2010, 09:07
Ecco l errore che mi da il compilatore:
Building VETTORI.HEX...

Compiling VETTORI.C:
Command line: "C:\CC5XFREE\CC5X.EXE -CC -fINHX8M -Ic:\cc5xfree -a -L -Q -V C:\2010\5BLEN\VETTORI.C"
CC5X Version 3.3H, Copyright (c) B Knudsen Data, Norway 1992-2009
--> FREE edition, 8-16 bit int, 24 bit float, 1k code, reduced optim.
C:\2010\5BLEN\VETTORI.C:

#include <16f877.h>
int array [2][2]={
^------
Error C:\2010\5BLEN\VETTORI.C 2: No ';' found
(Each statement (and definition) must be terminated by a semicolon. Check
previous statement)

#include <16f877.h>
int array [2][2]={
^------
Error C:\2010\5BLEN\VETTORI.C 2: Syntax error (or limitation)
(CC5X is unable to compile the expression due to syntax error or
limited C support. Code correction is required. Check also for
unbalanced block delimiters '{ .. }' in previous statements)

Error options: -ew: no warning details -ed: no error details -eL: list details

MPLAB is unable to find output file "VETTORI.HEX". This may be due to a compile, assemble, or link process failure.

Build failed.

Il codice è questo:
#include <16f877.h>
int array [2][2]={
{2,2},
{1,2}
};

Cosa può essere?

Mettendo il punto e virgola tra i due indici (così: int array [2];[2]) non da più l'errore di sintassi però rimane l'altro errore.

Z80Fan
16-03-2010, 18:24
Ecco l errore che mi da il compilatore:


Il codice è questo:
#include <16f877.h>
int array [2][2]={
{2,2},
{1,2}
};

Cosa può essere?

Mettendo il punto e virgola tra i due indici (così: int array [2];[2]) non da più l'errore di sintassi però rimane l'altro errore.

Eh come pensavo, il compilatore è molto rompipalle e, come dice lui stesso, "limited C support". Penso che voglia che ogni comando rimanga sulla stessa riga. Prova a scrivere:

int array [2][2]={ \
{2,2}, \
{1,2} \
};
(Nota che subito dopo le barre devi andare subito a capo senza scrivere nulla, nemmeno spazi)
Oppure
int array [2][2]={ {2,2}, {1,2} };
Magari in questo caso lo prende poichè è sulla stessa riga, ma prova prima il codice sopra. Se nè uno nè l'altro funzionano è proprio il compilatore che non supporta le matrici (che in effetti non è una struttura completamente banale, poichè le interpreta come vettori di vettori, quindi deve dereferenziare 2 volte i puntatori, operazione onerosa in un microcontrollore tipo pic)

Utone
16-03-2010, 19:41
appena vado in laboratorio provo.
E se non accettasse neanche questo codice devo usare i case? :(
Se cambiassi compilatore cambierebbero le cose?

Z80Fan
16-03-2010, 19:48
appena vado in laboratorio provo.
E se non accettasse neanche questo codice devo usare i case? :(
Se cambiassi compilatore cambierebbero le cose?
Non sò se cambiare compilatore risolverebbe le cose, tutti più o meno sono a questo livello. Magari un'altro te lo lascia fare, ma il codice sarà sicuramente lento (il pic per accedere ad una locazione di memoria indirettamente deve prima caricare dei registri appositi, poi leggere da altri, per accedere ad una matrice devi ripetere 2 volte questo procedimento (la prima volta carichi l'indirizzo del sucessivo vettore), senza contare il calcolo della posizione)

C'è una soluzione migliore al tuo problema (penso sia anche diffuso), che consiste nell'usare un po' di assembly e usare un trick probabilmente voluto dalla stessa Microchip per semplificare l'accesso agli array di elementi costanti. Intanto tu prova a fare quelle modifiche, in caso ne riparliamo.

Utone
16-03-2010, 19:58
Ottimo!! Sei un grande..
Il mio prof aveva proposto di usare gli switch ma io l'ho scartata subito..
Un altro prof mi ha proposto di usate N array dove N è la lunghezza del carattere più lungo.
Così salvavo il primo byte di A su array1 alla posizione 65, il secondo su array2 alla posizione 65 e così via.
Anche questa potrebbe essere una soluzione valida..

Z80Fan
16-03-2010, 20:14
Ottimo!! Sei un grande..
Il mio prof aveva proposto di usare gli switch ma io l'ho scartata subito..
Un altro prof mi ha proposto di usate N array dove N è la lunghezza del carattere più lungo.
Così salvavo il primo byte di A su array1 alla posizione 65, il secondo su array2 alla posizione 65 e così via.
Anche questa potrebbe essere una soluzione valida..
Già, e anche in previsione del trick di cui sopra, verrebbe più facile.
Già che ci sono te lo dico subito stò trick :D

Il trick serve per accedere velocemente (3-4 cicli di clock) ad un valore presente in un vettore di elementi costanti (vettore, non matrice).
Si richiama questa procedura con l'indice dell'elemento che si vuole ottenere nel registro W, e al ritorno si ha l'elemento desiderato di nuovo in W.

PCL EQU 02 ; All'inizio del programma


TABELLA ADDWF PCL
RETLW elemento0
RETLW elemento1
RETLW elemento4
...
RETLW elementoN

Presto spiegato:
L'istruzione ADDWF somma il valore contenuto in W con quello del file specificato (in questo caso la parte bassa del program counter), e lo ripone nel file. Così si ottiene un "salto" non condizionato, di W posizioni in avanti. Se il numero non era troppo grande da andare fuori dal vettore, la prossima istruzione che il pic eseguirà sarà una RETLW, che oltre a ritornare dalla chiamata di procedura, carica anche un valore nel registro W (come fare return Valore; ).

Diciamo che è equivalente a fare:
switch( elementoVoluto )
{
case 0:
return elemento 0;
case 1:
return elemento 1;
case 2:
return elemento 2;
case 3:
return elemento 3;
case n:
return elemento n;
}

E' un trick abbastanza diffuso, se cerchi su internet sicuramente lo trovi :)

Utone
18-03-2010, 10:01
ma porca....hanno formattato i pc e non va più MPlab -.-"
Mi sa che lo dovrò installare a casa...

Utone
19-03-2010, 14:32
Purtroppo l'array di array non funziona in nessun modo..:muro:
Con il trick che dici tu l'elemento può essere un array?

Z80Fan
19-03-2010, 16:49
Purtroppo l'array di array non funziona in nessun modo..:muro:
Con il trick che dici tu l'elemento può essere un array?

L'elemento del RETLW ? No può essere solo un valore numerico a 8 bit (1 byte o unsigned char quindi). Potresti usare l'idea del tuo professore di usare tanti array quanto è il carattere più lungo.

Utone
19-03-2010, 17:12
Si... dobbiamo scegliere tra usare gli switch o usare quel metodo.
Secondo te qual'è il migliore?

Z80Fan
19-03-2010, 17:15
Si... dobbiamo scegliere tra usare gli switch o usare quel metodo.
Secondo te qual'è il migliore?
Beh, se riuscite ad integrare C e assembly senza troppe difficoltà, direi di implementare il codice assembly, visto che il compilatore usando lo switch potrebbe compilare codice equivalente, ma più lento. Visto che una volta scritto questo codice non dovrete più metterci mano, ti consiglio il metodo Assembly.

Utone
19-03-2010, 17:17
Beh, se riuscite ad integrare C e assembly senza troppe difficoltà, direi di implementare il codice assembly, visto che il compilatore usando lo switch potrebbe compilare codice equivalente, ma più lento. Visto che una volta scritto questo codice non dovrete più metterci mano, ti consiglio il metodo Assembly.

ah io mi sa che avevo capito male, faccio 5 o 6 array con il trick che mi hai consigliato tu. Giusto?

Era questo no il tuo consiglio?

Z80Fan
19-03-2010, 17:19
ah io mi sa che avevo capito male, faccio 5 o 6 array con il trick che mi hai consigliato tu. Giusto?

Era questo no il tuo consiglio?
Si certo. E peschi il primo byte da inviare nel primo trick, il secondo dal secondo trick ecc...

Utone
19-03-2010, 17:20
OoooooKKkk! Allora avevo capito male! Grazie mille!
Sei di grande aiuto

Z80Fan
19-03-2010, 17:30
OoooooKKkk! Allora avevo capito male! Grazie mille!
Sei di grande aiuto
Non c'è di chè. (Pensa che adesso stò pure facendo una relazione di elettronica :D)

Utone
04-05-2010, 10:16
Aggiorno un po la situazione anche se i lavori procedono lentamente.. :(

Abbiamo fatto il programma per il nuovo pic da aggiungere, ora ha il messaggio memorizzato nella memoria programma, poi lo dovrà ricevere via seriale/bluetooth, memorizzarlo in una eeprom e poi trasferire il blocco da 100byte via i2c al pic master che comunica con gli altri PIC.

Poi stiamo cambiando la ricezione dei dati del pic master da rs232 a i2c.
Visto che la ricezione non è più un evento esterno ma è deciso dal master abbiamo eliminato l'interrupt e il programma diventa lineare.

Secondo voi è la strada giusta?

Allego qui i programmi.
Download (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/BackUpProgrammiVari.zip?cidReq=105BSISINF)
Download alternativo (in arrivo)

PS: per fare capire un po' meglio il tutto linko anche la relazione. Click qui (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Documenti/relazione.pdf?cidReq=105BSISINF)

Z80Fan
04-05-2010, 16:48
Aggiorno un po la situazione anche se i lavori procedono lentamente.. :(

Abbiamo fatto il programma per il nuovo pic da aggiungere, ora ha il messaggio memorizzato nella memoria programma, poi lo dovrà ricevere via seriale/bluetooth, memorizzarlo in una eeprom e poi trasferire il blocco da 100byte via i2c al pic master che comunica con gli altri PIC.

Poi stiamo cambiando la ricezione dei dati del pic master da rs232 a i2c.
Visto che la ricezione non è più un evento esterno ma è deciso dal master abbiamo eliminato l'interrupt e il programma diventa lineare.

Secondo voi è la strada giusta?

Allego qui i programmi.
Download (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/BackUpProgrammiVari.zip?cidReq=105BSISINF)
Download alternativo (in arrivo)

PS: per fare capire un po' meglio il tutto linko anche la relazione. Click qui (http://debian.itis.pr.it/dokeos1/courses/105BSISINF/document/Tesina-_-_Tabellone_elettronico-__groupdocs/Documenti/relazione.pdf?cidReq=105BSISINF)

Sto controllando i listati, e ho buttato un occhio su vettori.c
non so se te ne sei accorto, ma ad esempio alle righe 95-96, 226-227, 357-358 ... la riga precedente termina con un \, e anche se è a commento, il compilatore pensa che la riga successiva faccia altrettanto parte del commento, quindi i dati delle righe 96, 227, 358 non vengono inclusi nel vettore.

EDIT: Non sembrano esserci altri errori negli altri listati a livello sorgente, sulla programmazione non sò perchè non ho mai lavorato a fondo con i pic e l'i2c :(

Utone
05-05-2010, 14:11
Non ho capito, dopo la \ il compilatore pensa che non sono andato a capo?

Z80Fan
05-05-2010, 17:01
Non ho capito, dopo la \ il compilatore pensa che non sono andato a capo?
Se inserisci una \ su una linea e vai subito a capo (neanche spazi, subito a capo), lui interpreta la linea successiva come la continuazione della precedente. Viene usato spesso quando una codice deve necessariamente stare su una riga (ad esempio dopo un #define), ma si ha la necessità di dividerla su più righe per esempio per rendere il codice leggibile o stampare su un foglio stretto; con la \ si inganna il compilatore.

Utone
05-05-2010, 20:15
Se inserisci una \ su una linea e vai subito a capo (neanche spazi, subito a capo), lui interpreta la linea successiva come la continuazione della precedente. Viene usato spesso quando una codice deve necessariamente stare su una riga (ad esempio dopo un #define), ma si ha la necessità di dividerla su più righe per esempio per rendere il codice leggibile o stampare su un foglio stretto; con la \ si inganna il compilatore.

ah capito.. aggiungo un punto allora. :doh:

Utone
11-05-2010, 21:30
Nessun esperto in programmazione di pic?