[Documentation] [TitleIndex] [WordIndex

(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

MBED Oscilloscope

Description: In this tutorial, we will be making a poor man's oscilloscope using the MBED's ADC (analog to digital converter) and rqt_plot.

Keywords: MBED, rosserial, serial, ADC

Tutorial Level: BEGINNER

  Show EOL distros: 

In this tutorial, we will be making a poor man's oscilloscope using the MBED's ADC (analog to digital converter) and rqt_plot. We will set up a publisher which will forward the analog values from each of the mbed's 6 ADC pins to ROS using rosserial. This will be a relatively bad oscilloscope (very low sampling frequency and resolution), but it will be perfect for many quick and dirty setups.

Custom Message

This code uses a custom message type, the ADC.msg. This message has uint16 field for each of the analog input pins on the standard mbed.

uint16 adc0
uint16 adc1
uint16 adc2
uint16 adc3
uint16 adc4
uint16 adc5

This message is a part of the rosserial_mbed package and has been added to your ros_lib library.

The Code

The code for this tutorial is fairly straight forward. The code registers a Adc msg publisher, initializes the node handle, and then tries to publish as many Adc messages as possible.

   1 /*
   2  * rosserial ADC Example
   3  *
   4  * This is a poor man's Oscilloscope.  It does not have the sampling
   5  * rate or accuracy of a commerical scope, but it is great to get
   6  * an analog value into ROS in a pinch.
   7  */
   9 #include "mbed.h"
  10 #include <ros.h>
  11 #include <rosserial_mbed/Adc.h>
  13 #if defined(TARGET_LPC1768)
  14 PinName adc0 = p15;
  15 PinName adc1 = p16;
  16 PinName adc2 = p17;
  17 PinName adc3 = p18;
  18 PinName adc4 = p19;
  19 PinName adc5 = p20;
  20 #elif defined(TARGET_KL25Z) || defined(TARGET_NUCLEO_F401RE)
  21 PinName adc0 = A0;
  22 PinName adc1 = A1;
  23 PinName adc2 = A2;
  24 PinName adc3 = A3;
  25 PinName adc4 = A4;
  26 PinName adc5 = A5;
  27 #else
  28 #error "You need to specify the pins for the adcs"
  29 #endif
  31 ros::NodeHandle nh;
  33 rosserial_mbed::Adc adc_msg;
  34 ros::Publisher p("adc", &adc_msg);
  37 //We average the analog reading to elminate some of the noise
  38 int averageAnalog(PinName pin) {
  39     int v=0;
  40     for (int i=0; i<4; i++) v+= AnalogIn(pin).read_u16();
  41     return v/4;
  42 }
  44 long adc_timer;
  46 int main() {
  47     nh.initNode();
  49     nh.advertise(p);
  51     while (1) {
  52         adc_msg.adc0 = averageAnalog(adc0);
  53         adc_msg.adc1 = averageAnalog(adc1);
  54         adc_msg.adc2 = averageAnalog(adc2);
  55         adc_msg.adc3 = averageAnalog(adc3);
  56         adc_msg.adc4 = averageAnalog(adc4);
  57         adc_msg.adc5 = averageAnalog(adc5);
  59         p.publish(&adc_msg);
  61         nh.spinOnce();
  62     }
  63 }

Running the Oscilloscope


rosrun rosserial_python serial_node.py _port:=/dev/ttyACM0

rosrun rosserial_python serial_node.py /dev/ttyACM0

rqt_plot adc/adc0

Now, you should see the raw analog value on adc0 displayed in rqt_plot. Try connecting ADC0 to ground, 5V, and 3.3V on your MBED and observing the value. Also notice that when you don't have anything connected to the ADC, it is a floating analog input and its value will oscillate randomly.

For example, look at the below output where the ADC0 input is switched between 5V and gnd. There are wild oscillations during the transition.


2020-02-22 13:11