In this video, I show how to decode a single-byte UART communication between my computer and my Arduino Uno.
I do this using my Rigol 2072A bench-top oscilloscope, and a Loto Instruments OSC482 “virtual” or “PC” oscilloscope.
Using either scope, decoding this kind of communication is a matter of configuring the instrument with the parameters of the UART signal you want it to decode, and turning on the decoding function.
Because UART configuration varies wildly (baud rate, polarity, bits per byte, stop and start bits, and even vs. odd error detection), to decode it can be a frustrating experience unless you know these parameters for the communication you are trying to decode.
For my Arduino, I had to spend some time looking at the communication waveform to get some clues about the signal, and doing some Googling to figure out the rest, before I could configure the decoder.
This is much easier in other protocols, like I2C and SPI, which are more standardized.
Anyway, once you configure the decoder, you can simply capture a byte (or a byte packet) transmission and receipt and decode it.
The trigger function on both the Rigol and the Loto Instruments scopes work well. A trigger is a mechanism that can identify a signal that I am interested in decoding (or just examining), and the scope will capture this signal when it appears in the probes.
In this video, I show how the two scopes decode the UART communication, and how I use the trigger to capture the bytes “flowing” in the TX and RX lines. Of course, the Rigol 2072A is a much more expensive instrument compared to the OSC482 and has more trigger and decoding options. But, the OSC482 also did a good job, and I particularly enjoyed the ease of use (always a good thing when you are learning how to use a new instrument).
For my experiment, I used two simple programs.
One, an Arduino sketch that receives a byte from the computer and sends it back.
Second, a Processing sketch that takes a byte from the keyboard sends it to the Arduino and displays the bounced byte back on the screen.
You can see these programs below.
Arduino Sketch:
// Use with matching Processing sketch
byte incomingByte = 0; // for incoming serial data
// the setup routine runs once when you press reset:
void setup() {
Serial.begin(9600,SERIAL_8N1);
}
void loop() {
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
Serial.write(incomingByte); // This is the data we'll send to the PC. We'll include it in a single packet.
// Serial.write(0x0A); // Use hex 0A as the packet end. This can be picked up by the Rigol.
// Alternative packet end bytes are 0x20 (space), 0x0D (CR), 0x0A (LF), FF, and 0x00 (NULL)
}
}
The Processing program:
import processing.serial.*;
Serial myPort; // The serial port
int whichKey = -1; // Variable to hold keystoke values
int inByte = -1; // Incoming serial data
void setup() {
size(400, 300);
// create a font with the third font available to the system:
PFont myFont = createFont(PFont.list()[2], 14);
textFont(myFont);
// List all the available serial ports:
printArray(Serial.list());
// I know that the first port in the serial list on my mac
// is always my FTDI adaptor, so I open Serial.list()[0].
// In Windows, this usually opens COM1.
// Open whatever port is the one you're using.
String portName = Serial.list()[5];
myPort = new Serial(this, portName, 9600);
}
void draw() {
background(0);
text("Last Received (hex): " + hex(inByte), 10, 100);
text("Last Received (dec): " + inByte, 10, 120);
text("Last Received (char): " + char(inByte), 10, 140);
text("Last Sent (hex): " + hex(whichKey), 10, 160);
text("Last Sent (dec): " + whichKey, 10, 180);
text("Last Sent (char): " + char(whichKey), 10, 200);
}
void serialEvent(Serial myPort) {
inByte = myPort.read();
}
void keyPressed() {
// Send the keystroke out:
myPort.write(key);
whichKey = key;
}
I am considering creating a course dedicated to the oscilloscope. This video is an example of what this course might look like. What would you like to learn from such a course?
Feel free to post your ideas below.