13. Networking and Communications¶
Objectives¶
- Group Assignment: Send a message between two projects.
- Design, build, and connect wired or wireless node(s) with network or bus addresses
Group assignment¶
During Electronics production week, Jason and I already connected two of our own boards and communicated between them using UART. We also made more progress on our group assignment page.
Making a network board¶
For my network, I wanted to make a board that is able to communicate using a single master on the bus and a lot of slaves. I want all the communication to happen in “human-readable format”, meaning using ASCII characters mainly. Also, for simplicity purposes, I intend to use an asynchronous communication protocol and a single data wire. Obviously, I will need addresses to choose which slave I communicate to, and I will have framing data (start of frame and end of frame).
I chose to use ATSAMD11C as the main microcontroller. The nodes can be anything, but in order to only make a single board, they will be SAMD11C as well, but it could work with almost any controller like an ATTiny for example.
The idea is to use the UART protocol (RX and TX pins) but to make it a full network bus, I’ll share the RX between all the nodes, and the TXs will be connected with the RXs through a diode at each node, in order for them to be able to pull the signal low when they want to send a message. I end up with a single wire: RX between all the nodes (and a shared GND obviously). Note that each board can be powered separately but they can also share the power line.
The good news is also that, as indicated in the datasheet of the SAMD11C, the UART protocol is already completely implemented, features start and stop bit, parity bit and the idle state is high. So, by default, TX will not make the diode conducting, which is exactly what we want.
The design¶
The design itself is relatively straightforward, here are the main components:
- An ATSAMD11C
- A 3.3V regulator
- A USB copper connector
- A pull-up resistor on RX (for the master only)
- A diode between RX and TX (cathode on TX)
- A few LEDs and current limiting resistors connected to GPIOs so that I have a visual feedback of the communication
- A 4x connector for Programmation through SWD
- Connectors for RX, TX, 3.3V, 5V, GND.
The Altium schematic is shown below and is available in the design files.
I connected everything in Altium, added a ground plane and my board is basically ready. In practice, there is no connection between two ground planes so I’ll have to a add small wire to link them as it would be very space-inefficient to try to connect them with traces or to use a jumper.
Making the board¶
I had some trouble with the CNC engraver and the copper plates that were not perfectly plane so I ended up using chemical etching to make the board. It went flawlessly and the result is extremely good.
Obviously, I still need to cut it to make the right shape then, especially for the USB connector so I used a rolling saw.
Time to solder everything, nothing complicated, especially with the magnifying glass, and I made sure to well tin the USB connector.
Programming the SAMD¶
To program the SAMD, I intended to use my own programmer but I think it did not hold up together over time as copper turned green and I wasn’t able to program my new board. So I had to rely on a commercial CMSIS-DAP programmer. It worked perfectly, I only needed to connect SWDIO, SWCLK, and GND to my board.
I loaded the sam_ba bootloader so I can use the Arduino IDE to program my board, which will initially ease up the process.
I started by checking that everything on my board worked correctly by lighting up the LEDs. Good thing I did because one was not perfectly soldered and wouldn’t light up reliably so I needed to correct that soldering a bit!
The third LED does not blink
I then tried to send data over the UART and directly read it. Note that using the ArduinoSAMDCore for Mattairtech, you can use the RX2, TX2 Serial which is the second UART channel on the SAMD by using “Serial2” command. The USB, if selected in the config, will be available on “Serial” or “SerialUSB”. However, there is currently a bug (not yet reported ?) that makes the SerialUSB also communicate on the RX1, TX1 (so UART channel1). One of my LEDs being soldered on the TX1 pin would blink whenever I try to print on the SerialUSB. I tried multiple things to disconnect it (Serial config, using “Serial1.end()”, pinMode, …) but couldn’t make it happen.
Here is the code to make the LEDs blink and communicate over the bus and reading it back.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
Adding some framing¶
Even though I’m using the UART protocol which already features start bit, stop bit, … I will add “start of frame” and “end of frame” characters in my message to be able to detect the start and the end of a message on the bus.
To do so, I chose to use the 0x02 and 0x03 characters which are already set as start of text and end of text in the ASCII encoding.
In the code, I simply check whether there is data in the Serial2 buffer and if so, I read until I reach the start of a frame. I then check the address and if the message is for this node, I process it, otherwise, I read the buffer until I read the end of the frame before starting the cycle again.
Data format¶
To communicate order between the master and the nodes, I chose a very simple encoding. Since I only want to switch on or off some LEDs, I use a pair cmd/param. The cmd variable indicates which LED to switch state, and the param variable indicates whether it should be turned on or off. For example, to light up the LED2, I type ‘21’.
The addresses are encoded as alphabetical values. The master being ‘a’ and all the nodes being ‘b’, ‘c’, … up to ‘z’.
Communicating¶
Testing this idea proved to be very efficient and I could turn all the LEDs on and off on the slave by sending ‘11’, ‘21’, ‘31’, ‘10’, ‘20’, ‘30’ in a loop. You can also slightly see the green LED blink on the master each time it communicates on the SerialUSB.
Giving order through the SerialUSB¶
Now that it is working automatically, the final step is to incorporate the possibility to specifically give the order to switch on or off an LED through the SerialUSB terminal. There is however another bug where the Serials will get confused if you try sending data over UART right after reading incoming data on the USB buffer, and it will send ‘0x00’ over the UART. I couldn’t find the exact reason and it seems this bug has not yet been reported. The only solution is to add a small delay (300ms works) between the read of the USB buffer and sending the data over UART.
Here is the final result and the code
This code works for both the master and the slaves. You only need to comment or uncomment the first line.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
|
Update Week 13:¶
I updated the design with a third node (a second slave) with address ‘b’.
I forgot to add at least two 3.3V pins on my design so I had to connect my first slave to the 3.3V pin, and the second one to the 5V pin, both from the master (in a “star” configuration). In a perfect design, the 3.3V supply from one node would propagate to the next one.
Also, I initially had some issues making it work, because when I soldered my boards, I added all the 4.7kOhms pull-up resistors on all the boards. That made the communication line very pulled up and the communication was altered. I then realized it, unsoldered every 4.7k on the slave boards (as it should be, just didn’t think of it when soldering) and it finally worked flawlessly.
Making the LEDs subsequently blink
Commanding the indivual LEDs through the network
New code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
|