User Tools

Site Tools


amc2020:group_n:sn74hc595n

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
amc2020:group_n:sn74hc595n [2020/07/18 19:05] jonas001amc2020:group_n:sn74hc595n [2021/08/24 17:35] (current) – external edit 127.0.0.1
Line 1: Line 1:
 +<html>
 +  <left>
 +    <a href="https://wiki.eolab.de/doku.php?id=amc2020:group_n:start"; onmouseover="style.color='green'";>
 +      <span style="color:#2E71B8"; onmouseover="style.color='green'"; onmouseout="style.color='#2E71B8'";>
 +        &#8617 Back to the main page
 +      </span>
 +    </a>
 +  </left>
 +</html>
 +
 ====== SN74HC595(N) Shift Register ====== ====== SN74HC595(N) Shift Register ======
  
Line 12: Line 22:
 | **//Figure 1//**  SN74HC595(N) Shift Register and pinout.  | | **//Figure 1//**  SN74HC595(N) Shift Register and pinout.  |
  
-===== Working Principle =====+===== 2. Working Principle =====
  
 The MCU issues a clock signal (SRCLK) to the shift register and sends the data (SER) bitwise in 8-bit groups to the shift register (figure 2). If afterwards another byte is sent, the shift register outputs the first byte through the serial output pin (QH’), which may be connected to another shift register receiving the data. So, the shift register always stores the latest byte and if it receives a new byte, it shifts the old one to the next shift register.  The MCU issues a clock signal (SRCLK) to the shift register and sends the data (SER) bitwise in 8-bit groups to the shift register (figure 2). If afterwards another byte is sent, the shift register outputs the first byte through the serial output pin (QH’), which may be connected to another shift register receiving the data. So, the shift register always stores the latest byte and if it receives a new byte, it shifts the old one to the next shift register. 
Line 23: Line 33:
 | **//Figure 2//**  SN74HC595(N) pinout diagram (left) and logic diagram (right), there are different names and abbreviations for the pins depending on the source; the labels in the logic diagram are the official ones from the datasheet (also see table 2).  | | **//Figure 2//**  SN74HC595(N) pinout diagram (left) and logic diagram (right), there are different names and abbreviations for the pins depending on the source; the labels in the logic diagram are the official ones from the datasheet (also see table 2).  |
  
 +===== 3. Technical Specifications and Setup of the Module =====
 +
 +The ESP32 can supply 3.3 V, which is in the recommended operating range of the SN74HC595 (table 1). The shift register consumes a maximum of 80 μA which occurs at a supply voltage of 6 V while the shift register is actively used; that means during data transmission or transfer from shift register to storage register. Normally the module consumes much less current. The DHT-22 alone consumes 50 μA during idle state continuously which is much higher than the current in the idle shift register. The more sensors are connected to the shift register, the higher the efficiency of the sensor/shift register combination and the more energy can be saved. 
 +
 +It is important to note that the continuous output current should be limited to a maximum of 70 mA. As the voltage drops when more current is drawn, the current should be limited to about 5 mA per pin. As both the DHT-22 and the DS18B20 only use about 1.5 mA during measuring, this is not an issue.
 + 
 +An overview over the pins and what they do can be found in table 2. When setting up the module the notch helps orienting the shift register in the right direction. The pins were connected the following way:
 +
 +  * VDD to 3.3V
 +  * GND to GND
 +  * OE to GND
 +  * SRCLR to 3.3V
 +  * SRCLK to GPIO 4
 +  * RCLK to GPIO 2
 +  * SER to GPIO 0
 +
 +Furthermore, a small ceramic capacitor (104 pF) was added between VDD and GND with the legs of the capacitor as close to the pin as possible to reduce the inductance of the wire as much as possible. As mentioned before, the shift register draws most current in very short pulses when the data are shifted, or the byte is transferred to the storage register. In this situation it can be advantageous to have a small capacitor which can supply additional current to keep the voltage from dropping too low.
 +
 +The parallel outputs can be connected to any device operated at 3.3 V which draws less than 5 mA. To test the working principle of the shift register, the outputs can be connected to red LEDs with a sufficient resistor in series:
 +
 +$$R=\frac{V_{DD}-U_F}{I_{LED}}=\mathrm{\frac{3.3V-1.7V}{0.005A}=320\Omega}$$
 +
 +The next bigger resistor (usually 330Ω) should be used. After testing, in the real application, the VDD pin of the DHT-22 and the VDD pins of the DS18B20s were connected to the output pins QB and QC. The power for the sensors was thus supplied through the output pins of the shift register.
 +
 +^ **//Table 1 //** SN74HC595(N) specifications ^^
 +^ Module                 ^ SN74HC595(N) Shift Register  ^
 +| Supply Voltage VDD     | 2 – 6 V                      |
 +| Operating Temperature  | -40 – 125 °C                 |
 +| Power consumption      | 80 μA (max at 6V)            | 
 +
 +Further information can be found in the {{https://www.ti.com/lit/ds/symlink/sn74hc595.pdf?ts=1595095743394&ref_url=https%253A%252F%252Fwww.google.de%252F|SN74HC595 datasheet}}.
 +
 +^ **//Table 2 //** SN74HC595(N) pin overview and description  ^^^^
 +^ Pin  ^ Label  ^ Alternative Labels  ^ Description                          ^
 +| 1    | QB     | Q2                  | Parallel Output 2                    |
 +| 2    | QC     | Q3                  | Parallel Output 3                    |
 +| 3    | QD     | Q4                  | Parallel Output 4                    |
 +| 4    | QE     | Q5                  | Parallel Output 5                    |
 +| 5    | QF     | Q6                  | Parallel Output 6                    |
 +| 6    | QG     | Q7                  | Parallel Output 7                    |
 +| 7    | QH     | Q8                  | Parallel Output 8                    |
 +| 8    | GND    | -                   | Ground (0 V)                         |
 +| 9    | QH’    | Q8’                 | Serial Data Output                   |
 +| 10   | SRCLR  | MR                  | Shift Register Clear / Master Reset  |
 +| 11   | SRCLK  | Clock / SHCP        | Shift Register Clock                 |
 +| 12   | RCLK   | Latch / STCP        | Storage Register Clock               |
 +| 13   | OE     | -                   | Output Enable                        |
 +| 14   | SER    | Data / DS           | Serial Data Input                    |
 +| 15   | QA     | Q1                  | Parallel Output 1                    |
 +| 16   | VDD    | -                   | Power Supply (3.3V)                  |
 +
 +===== 4. The Code =====
 +
 +The following code is to test the function of the shift register with LEDs to see if it is working properly.
 +To see the sketch working, the shift register needs to be connected as described above and red LEDs have to be connected with a 330Ω resistor in series to the pins QA, QB and QC.
 +
 +==== 4.1 Code for the Shift Register =====
 +
 +<file c++ ShiftRegisterFunction.ino>
 +//ESP32 74HC595 Shift Register Test with LEDs
 +
 +//ESP32 PINS
 +const int LATCHPIN = 2;                                       //1
 +const int CLOCKPIN = 4;
 +const int DATAPIN = 0;
 +
 +byte sensor_numbers[9] = {                                    //2
 +  B00000000,  //all off
 +  B00000001,  //Pin 1
 +  B00000010,  //Pin 2
 +  B00000100,  //Pin 3
 +  B00001000,  //Pin 4
 +  B00010000,  //Pin 5
 +  B00100000,  //Pin 6
 +  B01000000,  //Pin 7
 +  B10000000,  //Pin 8
 +};
 +
 +void setup() {
 +  pinMode(LATCHPIN ,OUTPUT);                                  //3
 +  pinMode(CLOCKPIN ,OUTPUT);
 +  pinMode(DATAPIN ,OUTPUT);
 +}
 +
 +void loop() {
 +  powerSwitch(0);                                             //4
 +  delay(1000);
 +  powerSwitch(1);
 +  delay(1000);
 +  powerSwitch(2);
 +  delay(1000);
 +  powerSwitch(3);
 +  delay(1000);
 +}
 +
 +//Power Supply Function
 +void powerSwitch(byte pin){                                   //5
 +  digitalWrite(LATCHPIN, LOW);                                //6
 +  shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, sensor_numbers[pin]); //7
 +  digitalWrite(LATCHPIN, HIGH);                               //8
 +}
 +</file>
 +
 +===== 4.2. Explanation of the Code =====
 +
 +  - The GPIO for latch, clock and data input were chosen as described before.
 +  - The array sensor_numbers is used to configure different configurations for which pins should be high. the pattern of 0s and 1s in the binary numbers directly shows which pins are powered and which are not. A 1 means that it is switched on, a 0 means it is switched off. The most significant bit refers to pin QH/Q8 and the least significant bit refers to QA/Q1. Any combination of pins to be powered can be chosen by adjusting the binary numbers in the array accordingly. The elements in an array are zero indexed, so the first element has the index 0, the second has index 1 and so on. Here the elements were chosen such that the index 0 put all outputs low and the index 1 to 8 put only the corresponding pin high.
 +  - The shift register receives latch, data and clock as input, so the GPIOs need to be configured as outputs.
 +  - Here the function powerSwitch(), defined at the bottom, is used to switch off all pins and then switch on pin 1, then pin 2, then pin 3 in 1 second intervals and repeat.
 +  - The function powerSwitch() expects a byte type number as argument which represents the parallel output pin to be switched on.
 +  - Putting the latch pin at a low voltage level results in the storage register not being actualized while the new byte is shifted into the shift register; this prevents a disturbance of the output pins.
 +  - The function shiftOut() is already included in the Arduino library and is used for shift registers. As argument, it expects the data pin, the clock pin, the bit order and a value. The pins are given in the int variables in (1). The bit order defines in in which order the bits are shifted out. It can be either MSBFIRST, so the most significant bit is shifted out first, or LSBFIRST, so the least significant bit is shifted out first. When MSBFIRST is chosen, the MSB is pin QH/Q8 and the LSB is pin QA/Q8. Using LSBFIRST switches the order around. The value needs to below or equal to 255 because the function can only shift out data byte-wise. Here the element with the index given in the powerSwitch() argument from the array sensor_number initialized in (2)  is used as value.
 +  - Giving a high signal on the latch pin transmits the fully shifted out byte to the storage register which adjusts the three-state outputs accordingly causing the LEDs/sensors to be turned on.
 +
 +===== 4.3 Combining the Sketches =====
 +
 +This code can be combined with the code from the DHT-22 and the DS18B20s such that the sensors are only powered when they are supposed to measure and are switched off again afterwards.
 +
 +The sensors and the shift register need to be connected like explained in their pages, respectively. Additionally, the VDD pin of the DHT-22 must be connected to QB of the shift register and the VDD of both DS18B20s must be connected to QC. Furthermore, if a red LED with a 330Ω resistor in series is connected to QA, it indicates when the sensors finish their measurements with a short blink (figure 3).
 +
 +^{{:amc2020:group_n:esp32_all_sensors_breadboard.png?direct&800|Figure 3}}^
 +|**//Figure 3//** ESP32 connected with DHT-22, DS18B20 and SN74HC595.|
 +
 +==== 4.3.1 The Code combined ====
 +
 +The individual sections of the code are explained in detail in the pages of the [[amc2020:group_n:dht22|DHT-22]] and the [[amc2020:group_n:ds18b20|DS18B20]], respectively.
 +
 +<file c++ ESP32_Sensors_Combined.ino>
 +//ESP32 + DHT-22 + DS18B20 + 74HC595(n) Test
 +
 +//The code in this sketch is explained in detail in the DHT-22, the DS18B20 and the SN74HC595N pages
 +//and just combines the different codes.
 +
 +/*========================================================================================================
 + * DHT-22
 + *========================================================================================================
 +*/
 +//Definitions and Pins
 +#define DHTTYPE DHT22         //define the DHT-xx sensor
 +const int DHTPIN = 15;        //define the Data Pin (GPIO 2)
 +
 +//Libraries & Objects
 +#include <DHT.h>
 +
 +DHT dht(DHTPIN, DHTTYPE);     //Represents sensor
 +
 +//Variables
 +float dht22AirTem = 0;        //takes up new readings + final average
 +float dht22AirTemSum = 0;     //takes up the sum of readings for averaging
 +String dht22Temperature = ""; //gives back Temperature as a String for MQTT Transmission
 +
 +float dht22RelHum = 0;        //takes up new readings + final average
 +float dht22RelHumSum = 0;     //takes up the sum of readings for averaging
 +String dht22Humidity = "";    //gives back Humidity as a String for MQTT Transmission
 +
 +const uint8_t AveragingNumberDHT22 = 5; //Number of measurements to be averaged
 +
 +/*========================================================================================================
 + * DS18B20 
 + *========================================================================================================
 +*/
 +//Definitions and Pins
 +const int ONE_WIRE_BUS = 14;      //=GPIO 14 of the ESP32 as 1-Wire Bus
 +
 +//Libraries and Objects
 +#include <OneWire.h>            //Library for the 1-Wire protocol
 +#include <DallasTemperature.h>  //Library for sending commands and receiving data
 +
 +DeviceAddress bottomSensorAddress = {0x28,0xC4,0xA0,0x51,0x38,0x19,0x01,0xC2};    //Address bottom sensor (sensor 1, Tape)
 +DeviceAddress surfaceSensorAddress = {0x28,0x0B,0xDB,0x60,0x38,0x19,0x01,0xA3};   //Address surface sensor (sensor 2, w/o Tape)
 +OneWire oneWire(ONE_WIRE_BUS);          //Object representing the 1-Wire bus
 +DallasTemperature DS18B20(&oneWire);  //Object representing the sensors
 +
 +//Variables
 +float bottomTem = 0.00;         //for Temperature readings
 +String bottomTemperature = "";  //for the Sring to be sent using MQTT
 +
 +float surfaceTem = 0.00;
 +String surfaceTemperature = "";
 +
 +const uint8_t AveragingNumberDS18B20 = 5; //Number of measurements to be averaged
 +
 +int RESOLUTION = 12;      //Resolution of the sensor
 +int TCONV = 750;          //Conversion time for resolution = 12
 +int delayTime = (TCONV/pow(2, (12-RESOLUTION))) + 10; //Necessary delay time after measuring to get new values, depending on resolution
 +
 +/*========================================================================================================
 + * Shift Register
 + *========================================================================================================
 +*/
 +//Shift Register Pins
 +const int LATCHPIN = 2;
 +const int CLOCKPIN = 4;
 +const int DATAPIN = 0;
 +
 +//Shift Register Pin Array
 +byte sensor_numbers[9] = {
 +  B00000000,  //all off
 +  B00000001,  //Pin 1
 +  B00000010,  //Pin 2
 +  B00000100,  //Pin 3
 +  B00001000,  //Pin 4
 +  B00010000,  //Pin 5
 +  B00100000,  //Pin 6
 +  B01000000,  //Pin 7
 +  B10000000,  //Pin 8
 +};
 +
 +/*========================================================================================================
 + * Setup
 + *========================================================================================================
 +*/
 +
 +void setup() {
 +  pinMode(LATCHPIN ,OUTPUT);
 +  pinMode(CLOCKPIN ,OUTPUT);
 +  pinMode(DATAPIN ,OUTPUT);
 +  
 +  Serial.begin(115200);
 +  delay(5000);
 +  Serial.println("Measurement is starting ...");
 +  Serial.println("==============================");
 +  Serial.println(delayTime);
 +}
 +
 +/*========================================================================================================
 + * Loop
 + *========================================================================================================
 +*/
 +
 +void loop() {
 +  Serial.println("Measuring ...");
 +  powerSwitch(2); //Turn DHT-22 ON
 +  measureDHTTemHum(AveragingNumberDHT22);
 +  powerSwitch(1); //LED Blink
 +  delay(200);
 +  powerSwitch(3); //Turn DS18B20s ON
 +  measureDS18B20Tem(AveragingNumberDS18B20);
 +  powerSwitch(1); //LED Blink
 +  delay(200);
 +  Serial.println("DHT-22 Measurement Results: ");
 +  Serial.println("Temperature:       " + dht22Temperature + " °C");
 +  Serial.println("Relative Humidity: " + dht22Humidity + " %");
 +  Serial.println("DS18B20 Measurement Results: ");
 +  Serial.println("Sensor 1 (Bottom) Measurement:  " + bottomTemperature + " °C");
 +  Serial.println("Sensor 2 (Surface) Measurement: " + surfaceTemperature + " °C");
 +  Serial.println("========================================");
 +}
 +
 +/*========================================================================================================
 + * Sensor and Shift Register Functions
 + *========================================================================================================
 +*/
 +
 +//DS18B20 Measurement function
 +void measureDS18B20Tem (const uint8_t AveragingNumber){
 +  DS18B20.begin();
 +  bottomTem = 0;
 +  surfaceTem = 0;
 +  bottomTemperature = "";
 +  surfaceTemperature = "";
 +
 +  for(byte i = 0; i < AveragingNumber; i++)
 +  {
 +    DS18B20.requestTemperatures();
 +    delay(delayTime);
 +    bottomTem += DS18B20.getTempC(bottomSensorAddress);
 +    surfaceTem += DS18B20.getTempC(surfaceSensorAddress);
 +  }
 +  bottomTem /= AveragingNumber;
 +  surfaceTem /= AveragingNumber;
 +
 +  if(bottomTem<10)
 +    bottomTemperature = "0";
 +  bottomTemperature += bottomTem;
 +
 +  if(surfaceTem<10)
 +    surfaceTemperature = "0";
 +  surfaceTemperature += surfaceTem;
 +}
 +
 +//DHT22 Measurement function
 +void measureDHTTemHum (const uint8_t AveragingNumber)
 +{
 +  dht.begin();                                          //activate Sensor
 +  delay(1000);                                          //to prevent unstable status (see Datasheet)
 +  dht22AirTemSum = 0;
 +  dht22RelHumSum = 0;
 +  dht22Temperature = "";
 +  dht22Humidity = "";
 +  for (byte i = 0; i < AveragingNumber; i++)            //take n measurements for both
 +  {
 +    do {                                                //execute this at least once
 +      dht22AirTem = dht.readTemperature();              //measure Temperature
 +      dht22RelHum = dht.readHumidity();                 //measure Humidity
 +      if (!isnan(dht22AirTem) && !isnan(dht22RelHum))   //if results are valid, add them to the sum
 +      {
 +        dht22AirTemSum += dht22AirTem;
 +        dht22RelHumSum += dht22RelHum;
 +      }
 +      else
 +        delay(2000);                                    //if measurement is invalid, it has to be repeated. Sensor must not heat up
 +    } while (isnan(dht22AirTem) || isnan(dht22RelHum)); //if results were invalid, repeat the loop
 +    if (i < (AveragingNumber - 1))                      //after the last measurement, there is no delay needed anymore
 +      delay(2000);
 +  }
 +  dht22AirTem = dht22AirTemSum / AveragingNumber;       //averaging the measurements to get more accurate results
 +  if(dht22AirTem<10)                                    //if the Temperature is below 10°C, add a 0 to the front of the String
 +    dht22Temperature = '0';
 +  dht22Temperature = dht22Temperature + dht22AirTem;
 +  
 +  dht22RelHum = dht22RelHumSum / AveragingNumber;
 +  if(dht22RelHum<10)
 +    dht22Humidity = '0';
 +  dht22Humidity = dht22Humidity + dht22RelHum;
 +}
 +
 +//Shift Register Power Switch
 +void powerSwitch(byte pin){
 +  digitalWrite(LATCHPIN, LOW);
 +  shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, sensor_numbers[pin]);
 +  digitalWrite(LATCHPIN, HIGH);
 +}
 +</file>
 +
 +==== 4.3.2 Results ====
 +
 +The results of the sensor measurements are printed to the serial monitor:
 +
 +<code>
 +18:42:13.297 -> Measurement is starting ...
 +18:42:13.297 -> ==============================
 +18:42:13.330 -> Measuring ...
 +18:42:27.159 -> DHT-22 Measurement Results: 
 +18:42:27.159 -> Temperature:       27.72 °C
 +18:42:27.159 -> Relative Humidity: 46.22 %
 +18:42:27.159 -> DS18B20 Measurement Results: 
 +18:42:27.159 -> Sensor 1 (Bottom) Measurement:  27.85 °C
 +18:42:27.159 -> Sensor 2 (Surface) Measurement: 27.42 °C
 +18:42:27.159 -> ========================================
 +18:42:27.159 -> Measuring ...
 +18:42:44.147 -> DHT-22 Measurement Results: 
 +18:42:44.147 -> Temperature:       27.80 °C
 +18:42:44.147 -> Relative Humidity: 45.06 %
 +18:42:44.147 -> DS18B20 Measurement Results: 
 +18:42:44.147 -> Sensor 1 (Bottom) Measurement:  27.87 °C
 +18:42:44.147 -> Sensor 2 (Surface) Measurement: 27.54 °C
 +18:42:44.147 -> ========================================
 +
 +</code>
 +
 +During this test, all sensors were in equilibrium, measuring the room temperature during a rather hot summer day, and all results are close together, indicating that the sensors are working properly.
 +
 +<html>
 +  <center>
 +    <span>
 +    <a href="javascript:self.scrollTo(0,0)"; onmouseover="style.color='green'";>
 +      <span style="color:#2E71B8"; onmouseover="style.color='green'"; onmouseout="style.color='#2E71B8'";>
 +        Back to the top &#10548
 +      </span>
 +    </a>
 +    </span>
 +  </center>
 +</html>
amc2020/group_n/sn74hc595n.1595091907.txt.gz · Last modified: 2021/08/24 17:34 (external edit)