ShiftIn met shift registers

Projecten die niet passen in bovenstaande onderwerpen
Berichten: 5
Geregistreerd: 23 Nov 2015, 20:02

ShiftIn met shift registers

Berichtdoor ITGuy1990 » 23 Nov 2015, 21:03

Beste allemaal,

Situatieomschrijving
--------------------------------------------------------------------------------------------------------------------------------------
Ik heb een gaatjesbord met daarop 27 knoppen. Deze zitten aangesloten op 4 CD4021BE PiSo shift registers.

Aangesloten volgens het pinout diagram hieronder:
Afbeelding

Aansluiting van de knoppen:
De eerste 8 knoppen heb ik op deze pinnen aangesloten van het eerste shift register: P1-1, P1-2, P1-3, P1-4, P1-5, P1-6, P1-7 en P1-8. De tweede 8 knoppen heb ik op dezelfde pinnen aangesloten van het 2de register. De derde 8 knoppen heb ik op dezelfde pinnen aangesloten op het 3de register. En de laaste 2 knoppen heb ik aangesloten op P1-1 en P1-2 en P1-3 op het laatste register.
Alle P1 aansluitingen zijn tevens aan de GND gekoppeld met een 10K weerstand (pulldown) om verkeerde waarden te voorkomen.

Aansluiting van shift registers
De 4de shift register is aangesloten met Q8 (serial out) naar de Serial In van de 3de. De 3de is op dezelfde manier gekoppeld aan de 2de. En de 2de is op dezelfde manier gekoppeld naar de 1ste. De eerste is met Q8 verbonden aan de arduino pin A1.
Respectievelijk zijn de clockpin (10) en de parallel/serial control / latch (9) van elk shift register verbonden met de arduino op pinnen A2 en A3.
En uiteraard is elk shift register gevoed met een + en een - op de shift register pinnen 16 en 8.

De code
-----------------------------------------------------------------------------------------------------------------------------------
cpp code
/*
Dit is een test programma dat via de serial monitor weergeeft welke knoppen aangeklikt werden op het toetsenbord.
*/
int dataPin = A1;
int clockPin = A2;
int latchPin = A3;

byte register_vier;
byte register_drie;
byte register_twee;
byte register_een;
String registers;

void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, INPUT);

Serial.begin(9600);
Serial.println("Keyboard teststarted");
}

void loop() {
//zet de latchpin aan zodat de shiftregisters in parallel modus komen te staan en kijken naar de status van de knoppen
digitalWrite(latchPin, 1);
//wacht even totdat de data is opgehaald. 0,000 020 seconden. Gemiddelde menselijke reactietijd na prikkel is ongeveer 0.2 seconden ()
delayMicroseconds(40);
//zet de latchpin uit zodat de shiftregisters de knopstatussen serieel door kunnen gaan geven
digitalWrite(latchPin, 0);

//haal de status van de knoppen uit de shift registers.
register_vier = shiftIn(dataPin, clockPin, MSBFIRST);
register_drie = shiftIn(dataPin, clockPin, MSBFIRST);
register_twee = shiftIn(dataPin, clockPin, MSBFIRST);
register_een = shiftIn(dataPin, clockPin, MSBFIRST);

//maak er een string van met een - tussen de waarden van de shift registers
registers += String(register_een, DEC);
registers += "-";
registers += String(register_twee, DEC);
registers += "-";
registers += String(register_drie, DEC);
registers += "-";
registers += String(register_vier, DEC);

Serial.print(register_vier, DEC);
Serial.print("-");
Serial.print(register_drie, DEC);
Serial.print("-");
Serial.print(register_twee, DEC);
Serial.print("-");
Serial.println(register_een, DEC);
delay(250); //even wachten
}


Het probleem
Wanneer ik om de beurt de eerste 8 knoppen aanklik (aangesloten op shift register 1) is dit de output in de serial monitor
2-0-0-0 //knop 1
4-0-0-0 //knop 2
8-0-0-0 //knop 3
16-0-0-0 //knop 4
32-0-0-0 //knop 5
64-0-0-0 //knop 6
128-0-0-0 //knop 7
0-0-0-0 //knop 8

Bij de volgende knoppen heb je hetzelde probleem. Alleen uiteraard bij volgende shift registers:

//shift register 2
0-2-0-0 //knop 9
0-4-0-0 //knop 10
0-8-0-0 //knop 11
0-16-0-0 //knop 12
0-32-0-0 //knop 13
0-64-0-0 //knop 14
0-128-0-0 //knop 15
1-0-0-0 //knop 16 <<<<< aandacht aan deze bizarre situatie hier

//shift register 3
0-0-2-0 //knop 17
0-0-4-0 //knop 18
0-0-8-0 //knop 19
0-0-16-0 //knop 20
0-0-32-0 //knop 21
0-0-64-0 //knop 22
0-0-128-0 //knop 23
0-1-0-0 //knop 24 <<<<< aandacht aan deze bizarre situatie hier

//shift register 4
0-0-0-2 //knop 25
0-0-0-4 //knop 26
0-0-0-8 //knop 27

De vraag
------------------------------------------------------------------------------------------------------------------------------------
Als je kijkt naar de output op de serial monitor dan zie je dat de registers bij 2 beginnen te tellen en niet bij 1. Hoe kan dat?
En als je kijkt naar knop 16 en 24 dan is de output ook niet zoals je in de eerste instantie zou verwachten.
Het lijkt erop dat de registers op de een of andere manier al "verschoven" zijn voordat ik iets deed? Ik begrijp niet zo goed wat hier aan de hand is maar mijn doel is om de arduino te laten reageren op de input van deze knoppen. Met elke knop wil ik iets anders doen in arduino. Misschien met een switch case ofzo maar daar denk ik nog over na.
Je ziet hierboven decimale waarden omdat ik dat voor nu even makkelijker vind lezen dan de binaire weergave. Vind dat maar lastig omdat deze geen leading zero's weergeeft.

Advertisement

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: ShiftIn met shift registers

Berichtdoor nicoverduin » 23 Nov 2015, 21:21

Je schuift toch maar 1 bit tegelijk in. Niet 8 bits tegelijkertijd?
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Berichten: 5
Geregistreerd: 23 Nov 2015, 20:02

Re: ShiftIn met shift registers

Berichtdoor ITGuy1990 » 23 Nov 2015, 21:54

Nee,

Een hele byte.
zo simpel is het niet. ShiftIn doet het shiften voor je. Die doet een hele byte returnen. Je hoeft shift in maar 1 keer aan te roepen om 1 shift register uit te kunnen lezen.

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: ShiftIn met shift registers

Berichtdoor nicoverduin » 23 Nov 2015, 23:34

En je clock pin als eerst LOW zetten als eerste in de loop?
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Berichten: 5
Geregistreerd: 23 Nov 2015, 20:02

Re: ShiftIn met shift registers

Berichtdoor ITGuy1990 » 24 Nov 2015, 01:01

Dat werkt jammer genoeg ook niet. Heb de IDE nog geupdated naar de laatste versie en de sketch opnieuw geupload. Werkt ook niet. Heb de shiftin functie zoals hij hier gedefineerd staat eens toegevoegd onder aan de code, maar dat maakt ook geen verschil.

#edit 1:
Het is toch volgens mij een bug in de code van arduino zelf. De oplossing zat hem zoals je zei wel in de clockpin. Alleen moet deze HIGH of 1 zijn in het begin van de loop. Dus wat andere mensen mogen doen als ze dit probleem ook ondervinden is onderstaande shiftIn functie handmatig in hun code zetten + voordat ze shiftIn aanroepen deze code gebruiken:

Code: Alles selecteren
digitalWrite(clockPin, 1); // << dit is de fix.
  //zet de latchpin aan zodat de shiftregisters in parallel modus komen te staan en kijken naar de status van de knoppen
  digitalWrite(latchPin, 1);
  //wacht even totdat de data is opgehaald. 0,000 020 seconden. Gemiddelde menselijke reactietijd na prikkel is ongeveer 0.2 seconden ()
  delayMicroseconds(40);
  //zet de latchpin uit zodat de shiftregisters de knopstatussen serieel door kunnen gaan geven
  digitalWrite(latchPin, 0);


Mijn code zit nu in zijn totaliteit zo in elkaar:
Code: Alles selecteren
/*************
Dit is een test programma dat via de serial monitor weergeeft welke knoppen aangeklikt werden op het toetsenbord.
*/
int dataPin = A1;
int clockPin = A2;
int latchPin = A3;

unsigned int register_vier;
unsigned int register_drie;
unsigned int register_twee;
unsigned int register_een;
String registers;

void setup() {               
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, INPUT);
  digitalWrite(clockPin, 0);
 
  Serial.begin(9600);
  Serial.println("Keyboard test started"); 
}

void loop() {
  digitalWrite(clockPin, 1); // << dit is de fix.
  //zet de latchpin aan zodat de shiftregisters in parallel modus komen te staan en kijken naar de status van de knoppen
  digitalWrite(latchPin, 1);
  //wacht even totdat de data is opgehaald. 0,000 020 seconden. Gemiddelde menselijke reactietijd na prikkel is ongeveer 0.2 seconden ()
  delayMicroseconds(40);
  //zet de latchpin uit zodat de shiftregisters de knopstatussen serieel door kunnen gaan geven
  digitalWrite(latchPin, 0);
 
  //haal de status van de knoppen uit de shift registers.
  register_vier = shiftIn(dataPin, clockPin, MSBFIRST);
  register_drie = shiftIn(dataPin, clockPin, MSBFIRST);
  register_twee = shiftIn(dataPin, clockPin, MSBFIRST);
  register_een  = shiftIn(dataPin, clockPin, MSBFIRST);
 
  //maak er een string van met een - tussen de waarden van de shift registers
  registers += String(register_een, DEC);
  registers += "-";
  registers += String(register_twee, DEC);
  registers += "-";
  registers += String(register_drie, DEC);
  registers += "-";
  registers += String(register_vier, DEC);
 
  Serial.print(register_vier, DEC);
  Serial.print("-");
  Serial.print(register_drie, DEC);
  Serial.print("-");
  Serial.print(register_twee, DEC);
  Serial.print("-");
  Serial.println(register_een, DEC);
  delay(250); //even wachten
}

byte shiftIn(int myDataPin, int myClockPin) {
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);
//we will be holding the clock pin high 8 times (0,..,7) at the
//end of each time through the for loop

//at the begining of each loop when we set the clock low, it will
//be doing the necessary low to high drop to cause the shift
//register's DataPin to change state based on the value
//of the next bit in its serial information flow.
//The register transmits the information about the pins from pin 7 to pin 0
//so that is why our function counts down
  for (i=7; i>=0; i--)
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(0.2);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      //set the bit to 0 no matter what
      myDataIn = myDataIn | (1 << i);
    }
    else {
      //turn it off -- only necessary for debuging
     //print statement since myDataIn starts as 0
      pinState = 0;
    }

    //Debuging print statements
    //Serial.print(pinState);
    //Serial.print("     ");
    //Serial.println (dataIn, BIN);

    digitalWrite(myClockPin, 1);

  }
  //debuging print statements whitespace
  //Serial.println();
  //Serial.println(myDataIn, BIN);
  return myDataIn;
}


Ik ga de datasheet van het piso shift register er nog even op naslaan om te ontdekken waarom dat de clockpin high moet zijn voordat je gaat shiftInnen

Berichten: 5
Geregistreerd: 23 Nov 2015, 20:02

Re: ShiftIn met shift registers

Berichtdoor ITGuy1990 » 24 Nov 2015, 02:31

Ik snap het nog niet helemaal. Als ik kijk in de datasheet dan zie ik positive edge triggerd staan. Dus wanneer de clock van 0 naar 1 gaat en het register in serial mode staat (latchpin op 0) wordt de data in de registers verschoven als ik het goed begrijp. Op de een of andere manier wordt er dus eerst in paralelmodus de status van de inputs opgehaald en dan 2 x de clock van 0 naar 1 geplaatst. waar zie ik niet.
Als je pinMode(pin, OUTPUT); doet, gaat die pin dan op 1 / high? Kan dit er iets mee te maken hebben?

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: ShiftIn met shift registers

Berichtdoor nicoverduin » 24 Nov 2015, 08:38

Als ik het web bekijk ben je niet de enige. Wel een link die interessant kan zijn van Nick Gammon: http://www.gammon.com.au/forum/?id=11518
Om gebruik te maken van SPI
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Terug naar Overige projecten

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 31 gasten