[SOLVED] would someone mind checking this shift register please.

I am trying to get a cd4021 to work using this sketch

int latchPin = 5;
int dataPin = 6;
int clockPin = 7;
int myinput;

void setup()
{
  Serial.begin(9600);

  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT); 
  pinMode(dataPin, INPUT);
}

void loop()
{
   digitalWrite(latchPin,1);
  //set it to 1 to collect parallel data, wait
  delayMicroseconds(20);
  //set it to 0 to transmit data serially  
  digitalWrite(latchPin,0);
  delayMicroseconds (20);
 myinput = shiftIn (dataPin, clockPin, MSBFIRST);
 delay (200);
 Serial.println(myinput,BIN);
 
}

I have tried it with three cd4021 and in each case the P8 input (pin 1) fails to work.
Before I confine all three chips to the bin would someone please confirm that I am in fact reading all 8 inputs into ‘myinput’ and not losing one for some reason.
Thanks,
Bob.

Why have you decided to use microseconds? Why have you not used millis? In fact all you have to write is delay();

P8 ?

|500x323

Let’s see a good in focus image of the wiring.


BTW, myinput can be ‘type’ byte.

matelot:
I have tried it with three cd4021 and in each case the P8 input (pin 1) fails to work.

What do you mean, “fails to work”? How are you confirming that? You are using different pin designations on the schematic, than the ones in the data sheet (the one that I have anyway…). That’s okay, but you have to clarify that here, as nobody can guess what your pins mean other than by looking at a data sheet. P8 in the data sheet would be D7 on your schematic, which is floating and not connected (bad idea with CMOS, by the way).

You have a serial print. Why not share the print results with us? It would help us understand what your problem is.

Thank you larryd, I have in fact connected all eight inputs to the resistor array now.

aarg,
having connected all eight inputs to the resistor array and adding the following in just before the Serial.println

   if (myinput<128)Serial.print('0');
    if (myinput<64)Serial.print('0');
    if (myinput<32)Serial.print('0');
    if (myinput<16)Serial.print('0');
    if (myinput<8)Serial.print('0');
    if (myinput<4)Serial.print('0');
    if (myinput<2)Serial.print('0');

so that the reading on the serial monitor has leading '0’s .
What I see is all '0’s unless I connect an input to 5v. All the inputs show a 1 on the serial monitor except P8 (pin 1) I have swapped wires and checked the pins in my bread board but don’t get a ‘1’ from P8 (pin 1).

Always show us ‘your’ schematic not a generic version.

Make ‘myinput’ ‘type’ byte

With all inputs HIGH,

What did Serial.println(myinput,BIN); print ?

With all inputs LOW,

What did Serial.println(myinput,BIN); print ?


Let’s see a good in focus image of your wiring.

Also please repost your entire code, since you changed it, and please supply an updated serial print from the same program (please, not a verbal description thereof...).

larryd: Always show us ‘your’ schematic not a generic version.

That is my schematic, I made it using Kidcad

larryd: Make ‘myinput’ ‘type’ byte

Done and there is no change

larryd: With all inputs HIGH,

What did Serial.println(myinput,BIN); print ?

With all inputs LOW,

What did Serial.println(myinput,BIN); print ?

I am only putting single lines high as the board is a bit cramped but if put bits 1 and 7 high I get 10000010 If I put bits 2 and 7 high I get 01000010 If I put bits 2 and 8 high I get 01000000 I get '1's with bits 4-6 high.


larryd: Let’s see a good in focus image of your wiring.

How do I put a photo on the screen?

int latchPin = 5;
int dataPin = 6;
int clockPin = 7;
byte myinput;

void setup()
{
  Serial.begin(9600);

  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT); 
  pinMode(dataPin, INPUT);
}

void loop()
{
   digitalWrite(latchPin,1);
  //set it to 1 to collect parallel data, wait
  delayMicroseconds(20);
  //set it to 0 to transmit data serially  
  digitalWrite(latchPin,0);
  delayMicroseconds (20);
 myinput = shiftIn (dataPin, clockPin, MSBFIRST);
  delayMicroseconds (20);
 delay (200);
    if (myinput<128)Serial.print('0');
    if (myinput<64)Serial.print('0');
    if (myinput<32)Serial.print('0');
    if (myinput<16)Serial.print('0');
    if (myinput<8)Serial.print('0');
    if (myinput<4)Serial.print('0');
    if (myinput<2)Serial.print('0');
 Serial.println(myinput,BIN);
 
}

How do I get a Serial print?

You can attach a .jpg file.

This link shows how to post images: https://forum.arduino.cc/index.php?topic=519037.0

We need to talk the same language.

I am only putting single lines high as the board is a bit cramped but if put bits 1 and 7 high I get 
12345678
10000010

If I put bits 2 and 7 high I get 
12345678
01000010

If I put bits 2 and 8 high I get 
12345678
01000000

Try a new wire for 8 (D7)

Sorry, I am trying to get a picture to show, I used to use shutterfly but the pictures don't show from there for some reason.

I have used different leads and even pushed one under pin 1 but it is pin 1 input above (p8) that looks as if it is not working on 3 of my cd4012's

You do know that a HIGH or LOW needs to be attached to these input pins,

i.e. P1 thru P8 cannot be left floating, they must be connected to either 5v or GND.


Try to attach an image and we can see what can be done from our end to get it displayed.

Maybe try a .png file.


Maybe try to link the image at the IMGUR web site.

As I said in post 5 all 8 pins are connected to the resistor network. I am just using 2 wires to connect two inputs to 5v to pull them high. The schematic, from kiCad shows the inputs as d0-d7 where as the drawing in post 12 shows them as p1 - p8 that is the reference I am using here.

Perchance do you have a 74HC165 ?

I do, I am going to try to wire one up tomorrow, it is way past my bed time so I am going to leave it there till tomorrow. Thanks for the replies I will be back once I have tried a 165.

Please try the two sketches below.

Instructions are at the top of the sketches.

The first sketch uses a ShiftIn function to read the shift register data.

The second uses SPI to read the shift register data.

Both sketches work here on a 74HC165 but I do not have a CD4021B.

Please try your CD4021B on both sketches and let me know what your results are.

You will have to comment the #define HC165 line (near the top of the sketch) to get your CD4021B to work with the sketches.


Uses Arduino pins 9, 12 and 13

//
//74HC165 and CD4021B Using SPI.ino
//
//Example of using SPI to read the inputs from a shift register

//*****************************************************************************
//uncomment your part number line, comment the other line  <------<<<<<
#define HC165
//#define CD4021

//*****************************************************************************
#ifdef  HC165
#define LOAD      LOW    //data is loaded on a LOW going level
#define nLOAD     HIGH

#else
#define LOAD      HIGH   //data is loaded on a HIGH going level
#define nLOAD     LOW

#endif

//*****************************************************************************
//74HC165
//pin 1  (/PL) goes to LATCH (D9)   LOW  loads the register  <------<<<<<
//pin 2  (CP)  goes to SCK   (D13)
//pin 9  (Q7)  goes to MISO  (D12)

//CD4021B
//pin 9  (PL)  goes to LATCH (D9)   HIGH loads the register  <------<<<<<
//pin 10 (CP)  goes to SCK   (D13)
//pin 3  (Q7)  goes to MISO  (D12)


#include <SPI.h>

const byte LATCH = 9;

int shiftRegisterInputs;

//*****************************************************************************
void setup ()
{
  SPI.begin ();
  Serial.begin (9600);

  pinMode (LATCH, OUTPUT);
  digitalWrite (LATCH, nLOAD);

}  //END of setup

//*****************************************************************************
void loop ()
{
  digitalWrite (LATCH, LOAD);
  digitalWrite (LATCH, nLOAD);

  shiftRegisterInputs = SPI.transfer (0);

  Serial.print("switchRegisterInputs = ");
  printBits(shiftRegisterInputs);

  delay (500);

}  //END of loop

//*****************************************************************************
//print in binary with leading zeros
void printBits(unsigned int var)
{
  for (unsigned int x = 0x80; x; x = x >> 1)
  {
    Serial.print(var & x ? 1 : 0);
  }

  //Or use:
  //  for (int x = 7; x >= 0; x--)
  //  {
  //    if ((var & 1 << x) != 0)
  //    {
  //      Serial.print(1);
  //    }
  //    else
  //    {
  //      Serial.print(0);
  //    }
  //  }

  Serial.print("\n");

} //END of   printBits()

Uses Arduino pins 9, 12 and 13

//
//74HC165 and CD4021B.ino
//
//Example of a shiftIn function to read the inputs from a shift register, however,
//SPI is a better way to get the same inputs.

//*****************************************************************************
//uncomment your part number line, comment the other line  <------<<<<<
#define HC165
//#define CD4021

//*****************************************************************************
#ifdef  HC165
#define LOAD      LOW    //data is loaded on a LOW going level
#define nLOAD     HIGH

#else
#define LOAD      HIGH   //data is loaded on a HIGH going level
#define nLOAD     LOW

#endif

//*****************************************************************************
//74HC165
//pin 1 (/PL)     LOW  loads the register  <------<<<<<
//pin 2 (CP)
//pin 9 (Q7)

//CD4021B
//pin 9  (PL)     HIGH loads the register  <------<<<<<
//pin 10 (CP)
//pin 3  (Q7)

int latchPin = 9;  //    PL
int dataPin  = 12; //    Q7
int clockPin = 13; //    CP

int switchRegisterInputs;

//                              s e t u p ( )
//*****************************************************************************
void setup()
{
  Serial.begin(9600);

  pinMode(latchPin, OUTPUT);
  digitalWrite(latchPin, nLOAD);

  pinMode(clockPin, OUTPUT);
  digitalWrite(clockPin, LOW);

  pinMode(dataPin, INPUT);
}

//                              l o o p ( )
//*****************************************************************************
void loop()
{
  digitalWrite(latchPin, LOAD);
  delayMicroseconds(2);

  digitalWrite(latchPin, nLOAD);
  delayMicroseconds(2);

  switchRegisterInputs = ShiftIn(dataPin, clockPin);

  Serial.print("switchRegisterInputs = ");
  printBits(switchRegisterInputs);

  delay (500);

} //END of loop()

//                            S h i f t I n ( )
//*****************************************************************************
byte ShiftIn(byte DataPin, byte ClockPin)
{
  byte temp   = 0;
  byte DataIn = 0;

  for (char i = 7; i >= 0; i--)
  {
    temp = digitalRead(DataPin);

    if (temp == HIGH)
    {
      DataIn = DataIn | (1 << i);
    }

    //advance to the next bit
    digitalWrite(ClockPin, HIGH);
    digitalWrite(ClockPin, LOW);
  }

  return DataIn;

} //END of ShiftIn()

//                           p r i n t B i t s ( )
//*****************************************************************************
//print in binary with leading zeros
void printBits(unsigned int var)
{
  for (unsigned int x = 0x80; x; x = x >> 1)
  {
    Serial.print(var & x ? 1 : 0);
  }

  //Or use:
  //  for (int x = 7; x >= 0; x--)
  //  {
  //    if ((var & 1 << x) != 0)
  //    {
  //      Serial.print(1);
  //    }
  //    else
  //    {
  //      Serial.print(0);
  //    }
  //  }

  Serial.print("\n");

} //END of   printBits()

Attached are the two sketches.

_74HC165_and_CD4021B_using_SPI.ino (2 KB)

_74HC165_and_CD4021B.ino (2.72 KB)

After tying the sketches in the above post, please try this sketch on your CD4021B and let us know if it works.

This sketch prints leading zeros.

Uses Arduino pins 9, 12 and 13

//_74HC165_and_CD4021B_Version2
//
//CD4021 or 74HC165  parallel in to serial out
// Version  1.00
//

//*****************************************************************************
//uncomment your part number line, comment the other line  <------<<<<<
#define HC165
//#define CD4021

//*****************************************************************************
//                             75HC165                CD4021
const byte latchPin = 9;   //    1 (LOW = LOAD)         9 (HIGH = LOAD)
const byte dataPin  = 12;  //    9                      3
const byte clockPin = 13;  //    2                     10

unsigned int switchVar1;

//                          s e t u p ( )
//*******************************************************************
void setup()
{
  Serial.begin(9600);

  pinMode(latchPin, OUTPUT);

  pinMode(clockPin, OUTPUT);
  digitalWrite(clockPin, 0);

  pinMode(dataPin, INPUT_PULLUP);

  digitalWrite(clockPin, 0);

} //END of setup()

//                           l o o p ( ) 
//*******************************************************************
void loop()
{
#ifndef CD4021                  //for 74HC165

  digitalWrite(latchPin, LOW);
  digitalWrite(latchPin, HIGH);
#endif

#ifdef CD4021                   //for CD4021
  digitalWrite(latchPin, HIGH);
  digitalWrite(latchPin, LOW);
#endif

  switchVar1 = shiftIn(dataPin, clockPin);
  Serial.print("Switchvar1 = ");
  printBits(switchVar1);

  delay(500);

} //END of loop()

//                        s h i f t I n ( )
//*******************************************************************
byte shiftIn(byte myDataPin, byte myClockPin)
{
  byte temp   = 0;
  byte DataIn = 0;

  for (int i = 7; i >= 0; i--)
  {
    temp = digitalRead(myDataPin);

    if (temp == HIGH)
    {
      DataIn = DataIn | (1 << i);
    }

    //advance to the next bit
    digitalWrite(myClockPin, 1);
    digitalWrite(myClockPin, 0);

  }

  return DataIn;
 
} //END of   shiftIn()

//                         p r i n t B i t s ( )
//*******************************************************************
//print in binary with leading zeros
void printBits(unsigned int var)
{
  for (unsigned int x = 0x80; x; x = x >> 1)
  {
    Serial.print(var & x ? 1 : 0);
  }

  //Or use:
  //  for (int x = 7; x >= 0; x--)
  //  {
  //    if ((var & 1 << x) != 0)
  //    {
  //      Serial.print(1);
  //    }
  //    else
  //    {
  //      Serial.print(0);
  //    }
  //  }

  Serial.print("\n");

} //END of   printBits()

Give this a shot (compiles on Nano):

int latchPin = 5;
int dataPin = 6;
int clockPin = 7;
int myinput;

void setup()
{
  Serial.begin(9600);

  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, INPUT);
}

void loop()
{
   digitalWrite(latchPin,1);
  //set it to 1 to collect parallel data, wait
  delayMicroseconds(20);
  //set it to 0 to transmit data serially 
  digitalWrite(latchPin,0);
  delayMicroseconds (20);
 myinput = shiftIn (dataPin, clockPin, MSBFIRST);
 delay (200);
 prntBits(myinput);
 
}

void prntBits(byte b)
{
  for(int i = 7; i >= 0; i--)
    Serial.print(bitRead(b,i));
  Serial.println();  
}

larryd,
Your program works my 4021’s (3 of them) correctly if I *define cd4021.

My program looks as if it moves everything to the left one element, if I close pin 15 (put 5v on p7 ) both element 1 and 8 go to ones, if I close pin 1 (put 5v on p8) there is no output on pin 1 of the monitor (it stays ‘0’) the other outputs I have closed still show 1’s (I have elements 3 and 5 closed).

int latchPin = 9;
int dataPin = 12;
int clockPin = 13;
byte myinput;

void setup()
{
  Serial.begin(9600);

  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT); 
  pinMode(dataPin, INPUT);
}

void loop()
{
   digitalWrite(latchPin,1);
  //set it to 1 to collect parallel data, wait
  delayMicroseconds(20);
  //set it to 0 to transmit data serially  
  digitalWrite(latchPin,0);
  delayMicroseconds (20);
 myinput = shiftIn (dataPin, clockPin, MSBFIRST);
  delayMicroseconds (20);
 delay (200);
    if (myinput<128)Serial.print('0');
    if (myinput<64)Serial.print('0');
    if (myinput<32)Serial.print('0');
    if (myinput<16)Serial.print('0');
    if (myinput<8)Serial.print('0');
    if (myinput<4)Serial.print('0');
    if (myinput<2)Serial.print('0');
 Serial.println(myinput,BIN);
 
}

jca34f your program (I altered the pins to 9,12 and 13 to the same as larryd’s) does the same as mine.

The 74ls165 is wired differently and you have to add a 0v to pin 15 (I think).

With your program set to *define hc165 all three of my 74ls156’s show eight 1’s no matter what I do. Sometimes it changes to eight 0’s but I don’t know why. I will keep testing.

I took all three of the 165’s from some old boards I had so they may be duff.