ho un numero 8 bit da 0-255 e devo scriverlo nei pin 2-3-4-5-6-7-8-9 di arduino.
ho fatto delle funzioni che converte il numero in binario e poi bit per bit li scrive sui rispettivi pin.
mi sono accorto che questo metodo è molto lento e rallenta il resto del programma.
nei bit è collegato un decodificatore D/A R2R.
int b1x=2;
int b2x=3;
int b3x=4;
int b4x=5;
int b5x=6;
int b6x=7;
int b7x=8;
int b8x=9;
void setup() {
pinMode(b1x, OUTPUT);
pinMode(b2x, OUTPUT);
pinMode(b3x, OUTPUT);
pinMode(b4x, OUTPUT);
pinMode(b5x, OUTPUT);
pinMode(b6x, OUTPUT);
pinMode(b7x, OUTPUT);
pinMode(b8x, OUTPUT);
}
void stampa(int x){
int bx=1;
while(x!=0){
if(x%2==0){
x=x/2;
scrivi_bx(bx, 0);
}else{
x=(x-1)/2;
scrivi_bx(bx, 1);
}
bx++;
}
}
void scrivi_bx(int bx, int livello){
switch (bx){
case 1:
digitalWrite(b1x, livello);
break;
case 2:
digitalWrite(b2x, livello);
break;
case 3:
digitalWrite(b3x, livello);
break;
case 4:
digitalWrite(b4x, livello);
break;
case 5:
digitalWrite(b5x, livello);
break;
case 6:
digitalWrite(b6x, livello);
break;
case 7:
digitalWrite(b7x, livello);
break;
case 8:
digitalWrite(b8x, livello);
break;
}
}
void loop(){
stampa(N° desiderato)
}
se vi sembra complesso e incompressibile il programma è perché prima di chiedervi volevo provare a modo mio ed era l'unica idea che avevo
Sapete come posso pilotare un D/C R2R?
ilmandorlone:
Sapete come posso pilotare un D/C R2R?
Non usare la digital Write, collega il DAC a PORTD, pin da 0 a 7, scrivi il byte direttamente sul PORTD tramite relativo registro, dato che i pin 0 e 1 vengono utilizzati come OUT non ci sono problemi per caricare il software tramite bootloader.
Confermo erpomata, per avere il max della velocità potresti manipolare le porte in modo diretto.
In questo modo 8 pin li cambi con un'unica operazione. Però ovviamente dovresti usare i pin dallo 0 al 7, per cui dovresti mettere un paio di jumper sui pin 0 e 1 per non perdere la possibilità di upload dei nuovi sketch.
leo72:
per cui dovresti mettere un paio di jumper sui pin 0 e 1 per non perdere la possibilità di upload dei nuovi sketch.
Come ho già detto poco sopra non serve perché 0 e 1 sono OUT e come tale non danno fastidio alla seriale durante la programmazione, il problema si pone quando sono INPUT con device collegati.
se uso i 7 bit vado a usare i pin 0 e 1.
non capisco come la seriale non vada a influire sui pin 0-1??
mi fareste un esempio con un blink su pin 0 per capire meglio?
ilmandorlone:
non capisco come la seriale non vada a influire sui pin 0-1??
Ma lo hai letto quello che ho scritto oppure no ?
Vuoi provare con il blink ? Benissimo usa il programma d'esempio e cambia il pin da 13 a 0, o a 1, e vedrai che la cosa non crea nessun problema per la programmazione.
ilmandorlone:
se volessi scrivere una variabile decimale al posto di 0b... cosa devo fare?
La scrivi direttamente sul port, le varie notazioni sono solo per comodità umana, per il micro esiste solo il binario, scrivere PORTD = 0b11111111, oppure PORTD = 0xff, oppure PORTD = 255 è esattamente la stessa cosa e sono tutte e tre sintatticamente valide.
leo72:
Confermo erpomata, per avere il max della velocità potresti manipolare le porte in modo diretto.
In questo modo 8 pin li cambi con un'unica operazione. Però ovviamente dovresti usare i pin dallo 0 al 7, per cui dovresti mettere un paio di jumper sui pin 0 e 1 per non perdere la possibilità di upload dei nuovi sketch.
E' in generale lenta la digitalWrite o la lentezza che riscontra @mandorlone è legato ai 4 kg di int che ha dichiarato?
Usando bitRead(x, n) e una variabile byte sarebbe comunque lento ? (bitRead è solo una define, no call a funzione)
ora che ho fatto vari test mi sono ricordato che uso 2 convertitori R2R ma c'è solo la porta logica D che ha 8 bit mentre B e C solo 6.
posso "fondere" B con C?
salve
usando i registri delle porte per migliorare la velocità di set dei pin avrei bisogno di 2 porte da 7 bit
l'ATmega 328 ha 1 porta da 7 e 2 da 5 bit
posso usare 2 bit della porta C per aggiungerle a quelle della porta B?
Con una maschera di bit fatta con un AND binario.
Se fai un AND con 00111111 solo i primi 6 bit vengono considerati, facendo un AND con 11000000 solo gli ultimi 2.
Quindi
PORTB = valore & 0b00111111;
PORTC = valore & 0b11000000;
Attenzione che così per cambi tutti pin delle 2 porte.
Se vuoi approfondire, ho scritto un articolo a riguardo