Pages: [1] 2   Go Down
Author Topic: Shifting IN e Shifting OUT [Sto impazzendo!]  (Read 1035 times)
0 Members and 1 Guest are viewing this topic.
San Pier Niceto (ME), Sicily
Offline Offline
Newbie
*
Karma: 0
Posts: 48
Scopriamo arduino...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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... smiley-sad

chiedo cortesemente il vostro aiuto per risolvere questi problemi.

Ciao!
UP2
Logged

BZ (I)
Offline Offline
Brattain Member
*****
Karma: 258
Posts: 21502
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22658
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Per i 595 aiutati con questo tutorial:
http://arduino.cc/en/Tutorial/ShiftOut
Logged


Marche
Offline Offline
Edison Member
*
Karma: 33
Posts: 2265
azioni semplici per risultati complessi
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Per i CD4021 invece guarda qua:
http://www.arduino.cc/en/Tutorial/ShiftIn

Ricorda comunque di mettere le resistenze di pulldown su tutti gli ingressi, anche di quelli che non usi
Logged

Catania
Offline Offline
Sr. Member
****
Karma: 0
Posts: 346
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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:
Code:
uint16_t PORTS        = 0x0000;

Quando vuoi cambiare una uscita (senza intaccare le altre) usi la tecnica del bitwise.
Ad esempio:
Code:
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:
Code:
#define LED0   0
#define LED1   1
....
#define BJT    15

Ad ogni modifica di PORTS invii la variabile agli SR con una routine tipo:
Code:
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 Offline
Newbie
*
Karma: 0
Posts: 48
Scopriamo arduino...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@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! smiley

P.S. il code lo posto domani, perchè c'è l'ho nell'altro pc...

grazie ancora
UP2
Logged

Torino
Offline Offline
God Member
*****
Karma: 3
Posts: 766
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao ragazzi scusate se mi intrometto ma la cosa interessa anche me,
Quote
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

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22658
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@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.  smiley-wink
http://arduino.cc/en/Reference/Bit
Logged


Catania
Offline Offline
Sr. Member
****
Karma: 0
Posts: 346
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
non ci ho capito molto su quello che hai scritto
smiley-lol
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:
Code:
#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:
Code:
  bitSet(PORTS, LED5);
mentre se vuoi spegnere il led 1:
Code:
  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?  smiley-yell

Logged

San Pier Niceto (ME), Sicily
Offline Offline
Newbie
*
Karma: 0
Posts: 48
Scopriamo arduino...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@leo e dalubar, molte grazie, adesso ho capito tutto smiley
@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)
Code:
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:
Code:
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

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22658
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Newbie
*
Karma: 0
Posts: 48
Scopriamo arduino...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
boolean getBit(byte myVarIn, byte whatBit) {
  boolean bitState;
  bitState = myVarIn & (1 << whatBit);
  return bitState;
}
Code:
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

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22658
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Quote
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 Offline
Newbie
*
Karma: 0
Posts: 48
Scopriamo arduino...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@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

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22658
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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


Pages: [1] 2   Go Up
Jump to: