Aiuto con il C

Adesso non uccidetemi: so che questo è il forum di arduino ma io ho un problema con i PIC :smiley: e visto che c'è gente preparata sottopongo comunque il mio quesito.
Praticamente devo vedere se mi arriva una tensione sull' ADC del pic e se arriva, accendere un led per 5 secondi. Sto lavorando con Mikro C Pro, questo è il codice, compila ma non funziona:

void main() {
 trisb=0x00000000;
adc_init();



while(1){
unsigned int val;
val = adc_read(0) * 5/1024;
if(val>3) portb.rb0=1;


}
}

aha
Ciedi a un Forum dove usano Microcontroller ATMEL del aiuto per un Microcontroller Micochip.
Interessante. :grin: :grin: :grin:
Ciao Uwe

Da quello che leggo, non sapendo come si programmi un PIC, hai settato una variabile (credo un registro) a zero.
Poi inizializzi l'adc. Fai un ciclo infinito con dentro una lettura analogica e se questa è maggiore di 3 setti ad 1 una porta.
2 cose:
Dov'è che conti 5 secondi?
Sei sicuro che l'adc abbia il valore massimo a 1024?

Dov'è che conti 5 secondi?
Sei sicuro che l'adc abbia il valore massimo a 1024?

+1

uwefed:
aha
Ciedi a un Forum dove usano Microcontroller ATMEL del aiuto per un Microcontroller Micochip.
Interessante. :grin: :grin: :grin:
Ciao Uwe

+1
almeno dici che vuoi far comunicare un pic con un atmega :wink:

Grazie mille a tutti, in effetti non ho inserito nel codice la storia dei 5 secondi, ora riprovo :grin:.
Scusate che ho chiesto su un forum di atmel ma è uno dei migliori che conosco (su grix ci mettono tantissimo a rispondere nella sezione pic). Per il codice mi ha aiutato un mio amico dandomi delle dritte e io ho assemblato il tutto cercando di usare un libro sui pic che avevo comprato tempo fa :smiley:

cece99:
ora riprovo :grin:.

Ritenta sarai più fortunato :smiley:
Sopratutto posta queste domande nello spamm bar visto che siamo più che mai OT con Arduino, se sei fortunato forse ti rispondo e ti dico perché non funziona.

astrobeed:

cece99:
ora riprovo :grin:.

Ritenta sarai più fortunato :smiley:
Sopratutto posta queste domande nello spamm bar visto che siamo più che mai OT con Arduino, se sei fortunato forse ti rispondo e ti dico perché non funziona.

Astieniti pure visto che ho rispoto :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue:

cece99:
rispoto :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue:

Che fai cominci a parlare il "Lestese", guarda che poi vi capite solo tu e Lesto :grin:

w la dislessia che tutte le lettere si porta via!

oppure

life is too short to use the spell-checker

lesto:
w la dislessia che tutte le lettere si porta via!

oppure

life is too short to use the spell-checker

io sapevo life is too short for safely remove :smiley:

o usi virgola mobile o devi fare così:

long val ;
val = ((long)adc_read(0) * 5L)/1024L;

Il perchè fattelo pure spiegare da quelli che ti sfottono.

hreplo:
o usi virgola mobile o devi fare così:

long val ;
val = ((long)adc_read(0) * 5L)/1024L;

Il perchè fattelo pure spiegare da quelli che ti sfottono.

Grazie per il tuo intervento pertinente :D, io, ad esempio, ho risolto in un altro modo. Ho risolto così:

    unsigned int val;
void main() {
 trisb=0x00000000;
adc_init();



while(1){
unsigned int val;
val = adc_read(0) *5 /1024;
if(val>3){
portb.rb0=1;
delay_ms(5000);
portb.rb0=0;
}

}
}
[code]

[/code]

hreplo:
o usi virgola mobile o devi fare così:

long val ;
val = ((long)adc_read(0) * 5L)/1024L;

Il perchè fattelo pure spiegare da quelli che ti sfottono.

non mi torna. al massimo adc_read nrtitorna ritorna 1024(altrimenti sarebbe errato il divisore), e 1024*5=5120, il che sta tranquillissimamente in un int, o in un unsigned int.
A questo punto che la divisione avvenga tra long o int è inifluente, la precisione sarà sempre limitata a +-0.5V se il numero viene arrotondato, da 0V a -1V se il numero viene troncato (credo che si scriva +-0.5V -0.5V)

poi magari mi perdo io per strada qualche passaggio eh..

Sì, ti perdi qualche passaggio... tipo i fondamenti del C, la precedenza degli operatori, l'ordine di valutazione dell'espressione etc.

ho visto dopo che val era dichiarata UINT, e bastava, però ci sono PIC dove l'ADC è a 12bit XD...

tagliandola a fettine sottili, la divisione int 5/1024 in aritemetica intera torna valore 0 ed è valutata per prima (è a destra dell'espressione) quindi qualsiasi sia il valore letto da analogread viene moltiplicato x 0...

usando le parentesi, come ho scritto, viene prima moltiplicato il risultato dell'analogread*5 quindi diviso per 1024 e funzia

Consiglio a tutti di leggersi il K&R Linguaggio C(del 1974!!!) di cui conservo gelosamente copia originale :smiley: :smiley: :smiley: :smiley:

Edit: la mia edizione è del 1984, quando ho iniziato a programmare

non sto mettendo in dubbio l'uso di parentesi, che ammetto che mi sia sfuggito, ma l'uso dei long.

e se l'ADC è a 12bit e SE vuole il valore in volt, allora il divisore dovrebbe essere 4096

hreplo:
ho visto dopo che val era dichiarata UINT, e bastava, però ci sono PIC dove l'ADC è a 12bit XD...

Forse è meglio che lo rileggi il K&R, in C le operazioni matematiche "+ - * /" sono eseguite da sinistra verso destra, da destra verso sinistra sono eseguite le assegnazioni con operazione come "+=".
Dato che non ha specificato il modello di PIC è possibile che ha un ADC a 12 bit, però 4096 * 5 = 20480 che entra senza problemi anche in un signed int, quindi non c'è nessun motivo per usare i long.
Giusto per togliere ogni dubbio questo è uno sketch per Arduino che fa la stessa cosa e funziona perfettamente senza usare le parentesi, che comunque è sempre bene mettere ai fini della leggibilità del programma e per eliminare eventuali ambiguità, oltre ad accendere il led sul pin 13, per 100 ms, se il valore è maggiore di 3 stampa sul monitor seriale i valori letti che variano tra 0 e 4 come previsto.
Da notare che con il calcolo proposto da Cece il valore massimo è 4 e non 5 come probabilmente pensa lui perché l'out del ADC è al massimo 1023 e 1023 * 5 / 1024 = 4.995 che viene troncato a 4.

int SV;

void setup() {
   pinMode(13, OUTPUT);  
  Serial.begin(19200);
}

void loop() {
  SV = analogRead(A0) * 5 / 1024;
  if(SV>3) digitalWrite(13,HIGH);
  Serial.println(SV,DEC);
  delay(100);  
  digitalWrite(13, LOW);     
}

Giusto per troncare alla radice ogni discussione, K&R capitolo 2, paragrafo 12, tabella 2.1, precedenza degli operatori che è la stessa riportata qui.

ah, questa è una tabella da tenere sotto mano, anche se abbondo di parentesi e non ci faccio caso (lavorando con più linguaggi al giorno è facile mischiare i concetti)

interessante anche la tabella a fine pagina per l'uso delle precedenze coi puntatori..
io di solito scrivo (*p)++ ma non mi piace avere mille parentesi in giro ogni volta che accedo al valore della varibaile.
magari potrei passare a ++*p che mi pare anche abbastanza intuitivo.

lesto:
ah, questa è una tabella da tenere sotto mano, anche se abbondo di parentesi e non ci faccio caso (lavorando con più linguaggi al giorno è facile mischiare i concetti)

Da notare che la tabella oltre a specificare il verso di lettura indica anche la priorità degli operatori, che poi è la stessa indicata dalle regole matematiche, p.e. * e / vengono eseguite prime di + e -, va da se che usare le parentesi anche se non realmente necessario è comunque utile per la leggibilità della riga.