Unlike I2C or 1-Wire communication protocols, in most cases SPI requires the use of four wires. In some configurations it can use just three wires, but using four is the most common. Here are the pins to look out for on your Pico:

SCK: Serial Clock (synchronises data transmission and is generated by the master, which toggles it up and down, driving bits being sent and received)
MOSI:  Master Output Slave Input (used to send data from master to slave device, for example from Pico to a temperature sensor)
MISO: Master Input Slave Output (used to send data from slave to master device, for example from sensor to Pico)
SS: Slave Select (This identifies which peripheral on the SPI bus that the Pico will be communicating with. In other words, it tells the particular slave device to go 'active' and receive transmission from the master device, or to go to sleep. These lines run from the processor to each slave device, it is also known as chip select, CS)

00:00
So how does SPI communication work? First, the master device transmits a timing signal across the clock line (SCK). This allows the slave device to sample the transmitted signals correctly. 

To initiate the communication, the master brings the chip select (CS) line of the slave device it wants to communicate with, to a LOW voltage. The master then sends data across the MOSI line. The slave device responds by sending data across the MISO line.

When sending anything through SPI, the first thing that is sent is called the control byte. This contains the seven bit register address that we want to write to, or read from as well as a read/write bit in bit number 7, or Most Significant Bit (MSB). 
A 0 indicates a write, 1 indicates read request. After control byte, the data is sent. When communication is complete, the master device brings the chip select pin back to a high voltage signalling the end of the communication.

00:00
Unlike the I2C protocol, SPI only allows one master device and supports communication with multiple slave devices through the use of an additional chip-select line to each slave device. 
00:00
To use any SPI device with your Pico, you can use any of the GPIO ports labelled SPI in the pinout diagram highlighted in red here.
The MOSI, MISO and SCK must be connected to the same SPI master (the Pico) in other words. The CS can be connected to any GPIO pin.
00:00
A shift register is a form of sequential logic, composed of a group of flip-flops. 

A flip-flop is a circuit that has two states, you can also think of it as a basic storage element that can store a binary digit. 

In this guide, we will use an 8-bit shift register, the 74HC595 integrated circuit. By using it, you can control 8 outputs by only using 3 digital pins on the Pico. 

00:00
Here is the pinout diagram for this Shift Register: 
Q0 to Q7 (Pins 1-7, and 15) are Output Pins 
Pin 8 - GND (Ground) 
Pin 9 - Serial Out
Pin 10 - Master Reclear, active low It will clear the shift register when pulled LOW.
Pin 11 - Shift register clock pin It will shift the register when pulled HIGH.
Pin 12 - Storage register clock pin (latch pin) For the pattern of bits to be output by the shift register, it needs to be pulled HIGH
Pin 13 - Output enable, active low Enables output when pulled LOW, disables output when pulled HIGH.
Pin 14 - Serial data input
Pin 16 - VCC (Positive supply voltage)


00:00
These chips communicate through Serial Peripheral Interface (SPI) protocol. You can even chain them together! Let's say you had three of these shift registers. You can put three in a row, with the serial output of one, plugged into the serial input of the other. This can result in 24 digital outputs altogether. You can chain even more of these together! This makes it easy to control a lot of outputs such as LEDs from just 3 digital pins.
00:00
Connect the Raspberry Pi Pico to the breadboard. 
00:00
Insert the shift register to the breadboard, making sure that the little notch on the shift register IC is facing the bottom left corner. You should also see the chip number 74HC595N displayed upright as shown.

00:00
Now insert eight 3mm LEDs to the breadboard.
00:00
Connect a 330 ohm resistor from the negative lead of each LED, to the negative rail on breadboard.
00:00
Then connect each positive leg of the first four LEDs to pins 1 to 4 on the shift register.
00:00
Next connect each positive lead of the next four LEDs to pins 5,6,7, and 15 on the shift register. Connect pin 8 to GND on Pico.
00:00
Connect pin 16 of shift register to VSYS on Pico.
00:00
Connect Pin 14 to GPIO0 on Pico
00:00
Connect Pin 13 to GND on Pico
00:00
Connect Pin 12 of shift register to GPIO2 on Pico
00:00
Finally, make sure Pin 10 of the shift register is connected to VSYS.
00:00
Define the following up at the top of the sketch. These are the latch, clock, and data pins which we've connected to GPIO 2, 1 and 0 respectively on the Pico.
00:00
Next create a variable called leds which stores the byte data type. A byte represents numbers using eight bits.

According to the Arduino.cc documentation, a byte stores an 8-bit unsigned number, from 0 to 255.



00:00
Next, in void setup(), initialise the pin modes to be OUTPUT for the latchPin, clockPin, and dataPin.
00:00
In void loop, you can set all LEDs to be turned off initially by setting the value of leds variable to 0.
00:00
Then add a delay of 500 milliseconds right after this code. So that there is a half second delay before the next LED is lit later on.
00:00
The for loop counts from 0 to 7. The bitSet function sets the bit that controls the particular LED in the variable leds.

This method allows us to set individual bits of the byte to '1' by specifying its position.

That is to say, with each increment, we are also setting the bit to the left of the previous one to 1 every time. 

00:00
Next use the digitalWrite command to set the latchPin to LOW. 

This is because the bits have been set, so it's time to write to the latchPin to indicate that data is about to be sent. 

00:00
Once this is complete, the shiftOut() method is used. 

Its first two parameters are dataPin and clockPin,

Its third parameter tells the method in which order to shift out the bits; it can be either LSBFIRST (least significant bit first) or MSBFIRST (most significant bit first). The least significant bit is the right-most bit, and the most significant bit is the left-most bit. 

Its fourth parameter is the byte which contains the bits that we actually want to shift to the shift register. 
00:00
With that done, next write HIGH to the latch pin to indicate that all the data has been sent. 

00:00
Finally, add a delay of half a second or 500 milliseconds. Upload the code to the Pico with the Arduino IDE and the LEDs should now light up one after another, all while using just 3 GPIO pins!

00:00
main.py
xxx
Terminal
screen /dev/tty.usbmodem0000000000001 115200
>>> led = Pin(25, Pin.OUT)
>>> from machine import Pin
Breadboard
Breadboard
Mark
© 2023 Chick Commerce Pty Ltd