14. Networking and communications¶
Our Homework this week:¶
Our assignment this week is to:
Group assignment:¶
Send a message between two projects
Individual assignment:¶
Design, build, and connect wired or wireless node(s) with network or bus addresses
Learning outcomes¶
Demonstrate workflows used in network design Implement and interpret networking protocols and/or communication protocols
Have you answered these questions?¶
Linked to the group assignment page and reflected what you learned individually of the group assignment. Documented your project. Documented what you have learned from implementing networking and/or communication protocols. Explained the programming process/es you used. Outlined problems and how you fixed them. Included design files (or linked to where they are located if you are using a board you have designed and fabricated earlier) and original code.
Research¶
Networking is the process of communicating between two or more independent electronic devices. This connection can be wireless or wired. There are a lot of reasons you might want to communicate between multiple devices wirelessly. You might want to be able to sense something happening in one location and use that data to generate a display or other output in another location, for example. Networks can be set up in many different ways. When you want to get different devices talking to one another, there are some common questions that need to be resolved. For example, how can you be certain that the device that is reading messages is reading them at them at the same speed they are being sent? How can you both send and receive data between two devices – will there be separate pins dedicated to each task? If there are multiple devices on a network, how do we know which devices are trying to communicate with one another? These and other questions have led, over time, to the creation of different standardized methods for hooking up networks. The method used to connect devices on a network is called a protocol. There are three main network protocols to discuss: UART, SPI, and I2C. Each protocol has its own strengths and weaknesses, which I will address in more detail below. Much of the information I outline here was gleaned from tutorials I discovered on the circuitbasics website on UART, SPI, and I2C network protocols.
But first, a quick note about vocabulary:
Over time, the language used to describe the relationships between devices in a network has evolved. When these relationships were first defined, unfortunately the primary device in the network was called the ‘master’ and secondary devices in the network were called ‘slaves’. I mention this here both because you will sometimes see this language still in use and also because many acronyms you will come across are derived from this vocabulary. Thankfully, many people are using new terminology to describe the relationship between devices on a network. Unfortunately, there is not yet an agreed upon new standard. This can cause some confusion. I have seen people use main and secondary, manager and staff, and controller and peripheral, to describe the same relationship, to name a few. I will use main and secondary because it retains the first letter in each category which is useful for some of the acronyms you will see – such as MISO and MOSI – but it does not try to define the relationship between electronic devices in terms of human relationships. While the tutorials I linked to above use some outdated language, I found them to be very well written and easy to understand. One thing I found particularly useful is that the author defines the acronyms he uses. He also includes very helpful diagrams to illustrate the concepts he describes. This makes the content much easier to understand.
Below is a quick glossary of acronyms and important terms. I discuss these terms in more detail subsequently; this is intended as a quick reference guide:
Network Protocols:
UART - Universal Asynchronous Receiver Transmitter
SPI - Serial Peripheral Interface
I2C - Inter Integrated Circuit
Each of these protocols has its own set of acronyms that describe the different pins that connect the main and secondary devices:
UART Acronyms: TX - transmit RX - receive
SPI Acronums: MISO - Main in Secondary Out MOSI - Main out secondary in SCLK - Serial Clock CS/SS - Chip / secondary select
I2C Acronyms SCK - Serial clock SDA - Serial data
Now, let’s explore each of these protocols in turn.
Serial Peripheral Interface
SPI stands for Serial Peripheral Interface. Many of the sensors you use with your Arduino use the SPI protocol. The nRF24L01 chip that is often used for wireless communication between two Arduinos also uses SPI.
The SPI protocol requires four connection points. These include the seemingly inscrutable acronyms: MOSI, MISO, SCLK, and SS/CS. Let’s look at each of these in turn:
- MOSI stands for main out, secondary in. The communication through this port is as described: it leaves the main device (the microcontroller, for example) and goes into the secondary device (the sensor, for example).
- The MISO connection works in reverse! The acronym stands for main in, secondary out, and the connection allows the secondary device to send data to the main device.
These two separate lines for sending and receiving data in the SPI protocol makes it possible to send and receive data simultaneously using the SPI protocol.
-
SCLK is the port for the clock. The clock synchronizes the communication between the main and secondary devices. This ensures that the speed at which the main device is sending data is synchronized with the speed at which the secondary device is sampling incoming bits.
-
SS/CS is the secondary select or chip select port. The SS/CS connection has two purposes: the secondary select function on this port allows the main device to route data to a specifically selected secondary device. The chip select signal on this port allows you to enable a particular chip on the device. Sometimes, the main device will have multiple SS/CS ports, but when there is only one, you can daisy chain the secondary devices to enable the correct selection by the main device.
Some main devices might have multipe SS/CS ports, which would allow you to connect several different secondary devices to the main device in parallel. If there is only one SS/CS port, then multiple secondary devices can be connected by daisy chaining them together. From the description on the Circuit Basics site, I was not clear as to whether the daisy chained secondary devices can be controlled independently, or whether they would all receive the same exact communication from the main device, so I summarized what I understood and explained my confusion to ChatGPT, and received the following clarification:
“In this configuration, each device on the chain can be identified by its position in the chain, rather than by a unique SS/CS signal. The main device can select which device it wants to communicate with by sending a series of clock pulses to the chain, which shifts a “chip select” bit through each device until the desired device is selected. However, because all devices receive the same communication signal, any communication to one device will also be received by all other devices on the chain.”
SPI Data Transmission Process:
- The main sends out a clock signal along the SCLK line.
- The main changes the SS/CS line to low voltage, activating the secondary device.
- The main then starts transmitting data along the MOSI line
- If a response is required, the secondary device then transmits data back to the main along the MISO line.
Benefits and Disadvantages:
One of the main benefits of the SPI protocol is that it allows you to share a continuous stream of data between devices, and to do so at great speed and in both directions - sending and receiving. You can only have one main device but you can theoretically have an infinite number of secondary devices. The main downside of the SPI protocol is the number of wires required to connect devices to the network. As networks get larger, this can easily begin to become cumbersome. Another disadvantage is that there is no acknowledgment of the receipt of data and also no way to check whether the data has been compromised.
Universal Asynchronous Receiver-Transmitter - aka UART
As the name suggests, the UART protocol is asynchronous. UARTs use two pins to transmit data in serial: TX or the transmit pin and RX, aka the receive pin. Data can be sent in parallel, with each of many pins being dedicated to receiving and sending a single bit, or in series, with dedicated pins sending many bits in sequence. UART is interesting because it refers to an actual integrated circuit that collects information from the main device in parallel, converts it to serial, and then sends it via a TX pin to an RX pin in the receiving UART. The receiving UART then converts the data back into parallel data to send it on to the secondary device for interpretation. As its name suggests, UART is also asynchronous. There are only two wires connecting the communicating UARTs. There is no clock pin. Each device instead uses its own preset Baud Rate (measured in bits per second or bps) to determine the speed at which data is sent/sampled (though the devices must have baud rates that are set to within 10% of each other). To enable this asynchronous communication, rather than sending a continuous stream of data as with the SPI protocol, UART devices send start and stop bits from the main device to the secondary device to tell the secondary device when to start listening. The line is held high by default with a pull up resistor. When the main device changes the line to low, the receiving device knows it is time to start listening. It listens until it receives the stop bit.
UARTs can use one additional specialized bit called the parity bit that is designed to help to double check the accuracy of the data being sent. As with all other bits, the parity bit is a 1 or a 0. It is set to 1 if the total number of ones in the data being sent is odd and set to 0 if the total number of ones in the data being sent is even. On the receiving side, the UART can check whether it has received an even or odd number of ones and then check whether the parity bit is as expected. If the parity bit does not accurately represent the data that was received, the system knows that the data received might have been corrupted by electromagnetic interference or in some other manner.
I2C
I2C is a communication protocol that requires only two transmittion lines: SDA (serial data) and SCK (serial clock). The serial clock line synchronizes the rate at which data is sent and the rate at which it is sampled. The serial data line is for both transmitting and receiving data. An I2C protocol can support any number of main and secondary devices. Because there are only two lines used for communication in I2C, several tasks that have dedicated lines in the SPI protocol need to instead be incorporated into the message formatting in I2C. To support this message formatting, rather than sending a continuous stream of data, I2C communication is sent in packets or messages that are framed with start and stop bits that let secondary devices know when to start and stop listening. In addition, devices on an I2C network need:
- To know which device is being addressed
- To understand whether the main device is sending or requesting data
- To acknowledge whether the data has been received or not.
- The data being transmitted
This information is shared in each message sent in the I2C protocol in a specific format. Each message is structured as follows:
- Start condition and stop condition: The start and stop conditions tell the secondary device to listen and to stop listening to the main device. The start and stop condition are both created by sequential changes in the voltage status of the SDA and SCL lines. By default, the SDA line is kept at a high voltage with a pullup resistor to VCC which keeps the signal high by default (rather than allowing it to float). The start condition is created when the SDA line changes from high to low voltage BEFORE the SCL line makes the same change. The stop condition, on the other hand, occurs when the SDA line changes from low to high voltage AFTER the SCL line does the same. I asked ChatGPT to review my explanation and it added a few clarifications, which I will summarize: Put another way, the start condition occurs when the main decices pulls the SDA line low while the SCL line is high and the stop condition occurs when the main decices releases the SDA line and lets it go high while the SCL line is also high. For the start or stop condition to register, they must last at least one clock cycle (the time between two consecutive pulses of a clock).
- Address: a 7 or 10 bit address that is unique to each secondary device. In this portion of the message, the main device specifies the address of the secondary device to which it would like to communicate.
- Read/write bit: The read/write bit tells the secondary device whether the main device is writing data to the secondary device (write bit) or is requesting data to read from the secondary device. If the secondary device receives a read bit, it will send the data that has been requested back to the main device within the data frame of the same message. Write mode is represented with a zero and read mode is represented with a 1. I was originally confused and thought that the write bit was the one that was requesting data back from the secondary device. But think of it from the perspective of the main device communicating to the secondary device and it is easier to recall which is which: the main device is saying “hey secondary, I am writing data to you,” or “hey secondary, I want to read your data.”
- Ack/Nack bit - each part of the message requires an acknowledgment from the receiving device. If the message frame is successfully received, an ack bit is returned to the sender.
- First data frame - After the start condition opens the line of communication, the desired secondary device is addressed, and the read/write status has been specified, the first packet of data is sent from the main device to the secondary device (if a write bit was sent) or from the secondary device to the main (if a read bit was sent).
- Ack/Nack bit - the receiving device acknowledges receipt
- Second data frame - the next set of data is communicated
- Ack/Nack bit - the receiving device acknowledges receipt
The message concludes with a stop condition.
suggestions for editing from chatgpt¶
Overall, the explanation is clear and accurate. Here are a few suggestions to improve it further:
In the first bullet point, I suggest adding that the SCL line should be high during the entire start or stop condition, as this is an important aspect of the I2C protocol. In the second bullet point, it might be worth mentioning that the address is transmitted in the first byte of the message frame. In the third bullet point, you might want to clarify that the main device sends the write bit or read bit to the secondary device after transmitting the address. This will help emphasize the sequence of events in an I2C message. In the fifth and seventh bullet points, I suggest clarifying that the first and second data frames refer to the actual data being transmitted in the message. In the sixth and eighth bullet points, you might want to mention that the ack/nack bit is sent by the receiving device to signal whether it has successfully received the data frame. Lastly, you could consider adding a brief explanation of why the stop condition is important in the I2C protocol. The stop condition signals the end of the message and allows other devices on the bus to start transmitting their own messages. Overall, great job on the explanation!
Common Troubeshooting Issues¶
Common troubleshooting issues when working with wireless networks:
- Issues with power
- Distance
- Physical proximity
I2C link: https://learn.sparkfun.com/tutorials/i2c/all#res
NRF24L01¶
https://howtomechatronics.com/tutorials/arduino/arduino-wireless-communication-nrf24l01-tutorial/
This tutorial is very helpful. However, I will say that I have not had reliable success with the NRF24L01 modules I bought online without using a separate board to help regulate the power. (Adding a capacitor across VCC and ground did not help me.)
https://www.instructables.com/Arduino-and-NRF24L01/ https://www.amazon.com/Socket-Adapter-NRF24L01-Wireless-Module/dp/B00NJCB7FS/ref=sr_1_6?crid=QDNMKBVFN1SV&keywords=nrf24L01+wireless+board+power&qid=1681593566&sprefix=nrf24l01+wireless+board+power%2Caps%2C86&sr=8-6
From last year:¶
My students and I have been working on a networking project in short spurts since this past fall. Our project involves connecting several collections of homemade sensors at three different locations in a single room wirelessly to a single board that is connected to a computer. The serial data received from the different locations in the room is routed to an audio programming language, Max MSP, to trigger the playback of sounds.
We started with the nRF24L01+ module, but had difficulty getting consistent results without latency across any kind of distance. We subsequently purchased this module and used the two different types together. This seems to have worked reasonably well.
Useful links¶
Code Example¶
Use the three backticks to separate code.
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
Gallery¶
Video¶
From Vimeo¶
Sound Waves from George Gally (Radarboy) on Vimeo.