San Pier Niceto (ME), Sicily
Offline
Newbie
Karma: 0
Posts: 48
Scopriamo arduino...
|
 |
« on: June 05, 2012, 01:19:45 pm » |
Salve community, sono 2 giorni che tento inutilmente senza successo, di utilizzare gli shift in ed out... incomincio: ho 2 cd4021 messi in cascata, con data > D2, latch > D3, clock > D4. a questi ci sono collegati: al primo cd4021 8 pulsanti, più le resistenze di pull down (10k) su ogni ingresso, e sul secondo 6 interruttori, più resistenze di pull down... in una subroutine che ho chiamato readshiftin(), dovrei vedere lo stato di ogni pulsante e interruttore, che se premuto (o chiuso), deve fare una determinata azione, modificare una variabile booleana, oppure incrementare una variabile intera, ecc... ma dopo una marea di codici che ho testato, non ho avuto successo... stessa cosa per i 74hc595 (sempre 2 in cascata) con data > D10, latch > D11, clock > D12. a questi ci sono collegati 16 leds ed un transistor npn bc337 con resistenza di base da 150ohm. vorrei gestire i leds ed il transistor, in modo indipendente, ovvero cambiare una sola uscita, senza intaccare le altre... (con un array (byte), sarebbe semplice, ma non ci sono riuscito -.- in quanto nell'istruzione shiftout devi mettere una variabile byte, o una sola variabile dell'array) ho trovato qualche codice, ma anche qui non ho avuto fortuna...  chiedo cortesemente il vostro aiuto per risolvere questi problemi. Ciao! UP2
|
|
|
|
|
Logged
|
|
|
|
|
BZ (I)
Offline
Brattain Member
Karma: 161
Posts: 15680
+39 349 2158303
|
 |
« Reply #1 on: June 05, 2012, 02:40:54 pm » |
dacci il codice che hai provato
Comunque se metti 2 in cascata non puoi mettere i DATA in paralello ma devfi mettere Din in cascata col Dout Hai messo resistenze in serie a LED?
Ciao Uwe
|
|
|
|
« Last Edit: June 05, 2012, 02:47:10 pm by uwefed »
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 219
Posts: 16448
Don't know what I do
|
 |
« Reply #2 on: June 05, 2012, 03:01:49 pm » |
Per i 595 aiutati con questo tutorial: http://arduino.cc/en/Tutorial/ShiftOut
|
|
|
|
|
Logged
|
|
|
|
|
Marche
Offline
Edison Member
Karma: 25
Posts: 2056
|
 |
« Reply #3 on: June 05, 2012, 03:36:57 pm » |
Per i CD4021 invece guarda qua: http://www.arduino.cc/en/Tutorial/ShiftInRicorda comunque di mettere le resistenze di pulldown su tutti gli ingressi, anche di quelli che non usi
|
|
|
|
|
Logged
|
|
|
|
|
Catania
Offline
Sr. Member
Karma: 0
Posts: 346
|
 |
« Reply #4 on: June 05, 2012, 03:56:28 pm » |
vorrei gestire i leds ed il transistor, in modo indipendente, ovvero cambiare una sola uscita, senza intaccare le altre... (con un array (byte), sarebbe semplice, ma non ci sono riuscito -.- in quanto nell'istruzione shiftout devi mettere una variabile byte, o una sola variabile dell'array) Usa un unica variabile a 16 bit che rappresenta le singole uscite degli shift register, ad esempio: uint16_t PORTS = 0x0000;
Quando vuoi cambiare una uscita (senza intaccare le altre) usi la tecnica del bitwise. Ad esempio: PORTS |= (1 << 2); // ON - mette a "1" il bit n.2, che corrisponde alla terza uscita degli SR (uscite numerate da 1 a 16) PORTS &= ~(1 << 2); // OFF - mette a "0" il bit n.2, che corrisponde alla terza uscita degli SR (uscite numerate da 1 a 16)
Puoi più opportunamente definire delle costanti che rappresentino le uscite per una maggiore chiarezza di codice: #define LED0 0 #define LED1 1 .... #define BJT 15
Ad ogni modifica di PORTS invii la variabile agli SR con una routine tipo: void sendToShiftReg() { digitalWrite(SR_LATCH, LOW); shiftOut(SR_DATA, SR_CLOCK, MSBFIRST, highByte(PORTS)); shiftOut(SR_DATA, SR_CLOCK, MSBFIRST, lowByte(PORTS)); digitalWrite(SR_LATCH, HIGH); }
|
|
|
|
« Last Edit: June 05, 2012, 03:58:01 pm by dalubar »
|
Logged
|
|
|
|
|
San Pier Niceto (ME), Sicily
Offline
Newbie
Karma: 0
Posts: 48
Scopriamo arduino...
|
 |
« Reply #5 on: June 05, 2012, 04:10:55 pm » |
@uwe, leo e pelletta, ho usato le guide descritte sia per i collegamenti (uwe certamente ho collegato il din col dout, non hanno il data in comune, e certamente i diodi leds hanno ognuno una resistenza da 330ohm in serie), sia per i primi tests, ma poi ho creato codici di testa mia, basandomi su quel pò di teoria di elettronica digitale fatta quest'anno a scuola, anche se senza risultati... (ed ho anche scoperto, che le funzioni shiftin e shiftout, utilizzavano un codice con un ciclo molto simile a quello che avevo pensato io...) @dalubar: non ci ho capito molto su quello che hai scritto, e non ho capito soprattutto, come associare i define dei leds al codice riportato... ti chiederei, di essere un po più clemente, e spiegarmi meglio come fare, grazie ringrazio tutti per le risposte! P.S. il code lo posto domani, perchè c'è l'ho nell'altro pc... grazie ancora UP2
|
|
|
|
|
Logged
|
|
|
|
|
Torino
Offline
God Member
Karma: 2
Posts: 720
|
 |
« Reply #6 on: June 05, 2012, 04:16:48 pm » |
Ciao ragazzi scusate se mi intrometto ma la cosa interessa anche me, shiftOut(SR_DATA, SR_CLOCK, MSBFIRST, highByte(PORTS)); shiftOut(SR_DATA, SR_CLOCK, MSBFIRST, lowByte(PORTS)); nella prima riga dello shiftOut,con highByte(PORTS) si inviano gli otto bit più significativi che compongono la variabile unit_16 PORTS,di conseguenza con lowByte(PORTS) si inviano gli otto bit meno significativi,ho capito bene o dico una fesseria? Grazie
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 219
Posts: 16448
Don't know what I do
|
 |
« Reply #7 on: June 05, 2012, 04:19:27 pm » |
@ultra: si tratta di manipolazione diretta dei bit di una variabile. Se le cose ti sembrano difficili, lascia perdere per ora e cerca di far funzionare il circuito nel modo a te più congeniale e comprensibile. In un secondo tempo ti studierai i bit e la manipolazione degli stessi. http://arduino.cc/en/Reference/Bit
|
|
|
|
|
Logged
|
|
|
|
|
Catania
Offline
Sr. Member
Karma: 0
Posts: 346
|
 |
« Reply #8 on: June 05, 2012, 04:29:17 pm » |
non ci ho capito molto su quello che hai scritto  Allora, cerco di spiegarmi meglio. Il concetto è quello di associare ognuna delle 16 uscite degli Shift Register (SR) ad uno specifico bit di una variabile denominata PORTS. Supponendo che stai collegando 16 LED numerati da 1 a 16, allora potresti definire qualcosa di simile: #define LED1 0 #define LED2 1 #define LED3 2 ............ #define LED16 15
In questo modo, quando vuoi accendere (o spegnere) un particolare LED puoi usare direttamente il suo nome. Se il codice che ho postato ti sembra troppo complicato allora puoi usare le comode e semplici istruzioni bitSet() e bitClear(). Quindi, ad esempio, se vuoi accendere il led 5 puoi scrivere semplicemente: bitSet(PORTS, LED5);
mentre se vuoi spegnere il led 1: bitClear(PORTS, LED1);
Quando hai finito le modifiche invii PORTS agli SR con la funzione che ti ho scritto. Nota che nella natura intrinseca degli shift register, il bit inviato per PRIMO si trovera nell'ULTIMA uscita, ecco perchè si inviano prima i bit più significativi e poi quelli meno significativi. Sono stato più chiaro, adesso? 
|
|
|
|
|
Logged
|
|
|
|
|
San Pier Niceto (ME), Sicily
Offline
Newbie
Karma: 0
Posts: 48
Scopriamo arduino...
|
 |
« Reply #9 on: June 05, 2012, 11:47:24 pm » |
@leo e dalubar, molte grazie, adesso ho capito tutto  @dalubar sapevo che il primo bit inviato va all'ultima uscita dell'ultimo shift =) comunque, resta il problema per gli shiftin, i codici che ho usato sono questi: code1 (basato su questo http://arduino.cc/en/Tutorial/ShftIn12) digitalWrite(latchin,1); delayMicroseconds(20); digitalWrite(latchin,0); shiftin1 = shiftIn(datain, clockin); shiftin2 = shiftIn(datain, clockin); for (int n=0; n<=7; n++) { if (shiftin1 & (1 << n) ){ switch(n){ case 0: block3=false; break; case 1: block2=false; break; case 2: block1=false; break; case 3: if (block3==false && manual==true){ if (start3 == true){ start3=false; }else{ start3=true; } }else { start3=false; } break; case 4: if (block2==false && manual==true){ if (start2 == true){ start2=false; }else{ start2=true; } }else { start2=false; } break; case 5: if (block1==false && manual==true){ if (start1 == true){ start1=false; }else{ start1=true; } }else { start1=false; } break; case 6: if (manual == true){ manual=false; }else{ manual=true; } break; } } } for (int n=0; n<=7; n++) { //so, when n is 3, it compares the bits //in switchVar1 and the binary number 00001000 //which will only return true if there is a //1 in that bit (ie that pin) from the shift //register. if (shiftin2 & (1 << n) ){ //print the value of the array location //Serial.println(note2sing[n]); } } delay(500); poi ho provato con questo: for (int x=15; x >=0; x--){ digitalWrite(clockin,LOW); if (digitalRead(datain)==HIGH) { switch(x){ case 0: block3=false; break; case 1: block2=false; break; case 2: block1=false; break; case 3: if (block3==false && manual==true){ if (start3 == true){ start3=false; }else{ start3=true; } }else { start3=false; } break; case 4: if (block2==false && manual==true){ if (start2 == true){ start2=false; }else{ start2=true; } }else { start2=false; } break; case 5: if (block1==false && manual==true){ if (start1 == true){ start1=false; }else{ start1=true; } }else { start1=false; } break; case 6: if (manual == true){ manual=false; }else{ manual=true; } break; } } } digitalWrite(clockin,HIGH); delay(200); e poi ho provato con un code basato su questo http://arduino.cc/en/Tutorial/ShftIn23, k però ho cancellato :/ e non ho avuto successo con nessuno u.u P.S. @pelletta, gli ingressi che non uso sono collegati a gnd ciao UP2
|
|
|
|
« Last Edit: June 05, 2012, 11:50:23 pm by Ultra Phonic 2 »
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 219
Posts: 16448
Don't know what I do
|
 |
« Reply #10 on: June 06, 2012, 02:21:18 am » |
Una domanda: ma ciò che leggi è ciò che devi fare? Ossia, c'è una corrispondenza fra gli ingressi e le uscite? Se è così potresti semplicemente spedire in uscita i 2 byte letti in ingresso per cui se ad esempio 1 bit in ingresso va alto, lo mandi in uscita per attivare il corrispondente dispositivo (led, relè ecc..).
|
|
|
|
|
Logged
|
|
|
|
|
San Pier Niceto (ME), Sicily
Offline
Newbie
Karma: 0
Posts: 48
Scopriamo arduino...
|
 |
« Reply #11 on: June 06, 2012, 02:40:51 am » |
c'è una corrispondenza, ma i button mi servono anche per altro... comunque, finalmente sono riuscito a far funzionare gli shiftin, anche se non mi spiego 2 cose 1) perchè l'ingresso 6 (piedino n°15) del 4021, ha come indice 0? l'ingresso 7 (piedino 1) che indice avrà? 2) perchè cliccando i pulsanti, a volte è come se non li clicchi, ovvero non viene registrato il passaggio di stato? ecco il code: boolean getBit(byte myVarIn, byte whatBit) { boolean bitState; bitState = myVarIn & (1 << whatBit); return bitState; } void readshiftin() { digitalWrite(latchin,1); delayMicroseconds(20); digitalWrite(latchin,0); shiftin1 = shiftIn(datain, clockin); shiftin2 = shiftIn(datain, clockin); if (getBit(shiftin1, 6)) { block3=false; } if (getBit(shiftin1, 5)) { block2=false; } if (getBit(shiftin1, 4)) { block1=false; } if (getBit(shiftin1, 3)) { if (block3==false && manual==true){ if (start3 == true){ start3=false; }else{ start3=true; } }else { start3=false; } } if (getBit(shiftin1, 2)) { if (block2==false && manual==true){ if (start2 == true){ start2=false; }else{ start2=true; } }else { start2=false; } } if (getBit(shiftin1, 1)) { if (block1==false && manual==true){ if (start1 == true){ start1=false; }else{ start1=true; } }else { start1=false; } } if (getBit(shiftin1, 0)) { if (manual == true){ manual=false; start1=false; start2=false; start3=false; digitalWrite(m1, LOW); digitalWrite(m2, LOW); digitalWrite(m3, LOW); }else{ manual=true; } } delay(20); } ciao UP2
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 219
Posts: 16448
Don't know what I do
|
 |
« Reply #12 on: June 06, 2012, 02:57:48 am » |
c'è una corrispondenza, ma i button mi servono anche per altro...
comunque, finalmente sono riuscito a far funzionare gli shiftin, anche se non mi spiego 2 cose 1) perchè l'ingresso 6 (piedino n°15) del 4021, ha come indice 0? l'ingresso 7 (piedino 1) che indice avrà?
Il piedino 15 è denominato P7, non è il 6° ingresso, è l'7°, dato che la numerazione va da P1 a P8. Se parliamo di "posizione" del bit che lo indica, allora è il 6° bit. 2) perchè cliccando i pulsanti, a volte è come se non li clicchi, ovvero non viene registrato il passaggio di stato?
Probabilmente è un problema di bounce, cioè di "rimbalzo" elettrico del pulsantino. Prova effettuando 2 letture distanziate di 30 ms e poi prendi per buone solo quelle che in entrambi i casi sono risultate HIGH.
|
|
|
|
|
Logged
|
|
|
|
|
San Pier Niceto (ME), Sicily
Offline
Newbie
Karma: 0
Posts: 48
Scopriamo arduino...
|
 |
« Reply #13 on: June 06, 2012, 04:31:05 am » |
@leo, anch'io credo sia un problema di bounce, grazie della risposta, proverò...
per quanto riguarda il cd4021 il p7 nella funzione getbit, ha come indice 0, il p6 ha indice 1, il p1 ha indice 6, il p8 che indice avrà? 7? non ho provato perchè in entrambi gli shift l'ho cortocircuitato col gnd, in quanto non lo uso, ma era per un chiarimento...
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 219
Posts: 16448
Don't know what I do
|
 |
« Reply #14 on: June 06, 2012, 07:34:02 am » |
Non ho usato i 4021 ma mi pare un problema di cablaggio, perché generalmente i pin nei registri a scorrimento corrispondono ai bit interni.
|
|
|
|
|
Logged
|
|
|
|
|
|