2.12/2.120 Intro to Robotics
Spring 20261
Table of Contents
Estimated time of completion: 5 min
Clone this repository and run robot/blink_test.cpp. You should see the onboard LED change colors!
Forget how to clone?
Please refer to the instructions from Lab 1.
Refer to the pinout diagram here when choosing pins for sensors, motors, and encoders.
The pin numbers in code are usually defined either in include/pinout.h or through #define statements at the beginning of the test code. In this lab, you are free to use any pins as long as they are the right type and you update the code to match your chosen pins.
Feel free to clarify with the staff if you are unsure what the labels mean! A printout of this diagram has also been provided to you.
Estimated time of completion: 45 min
In this section, you will wire and code each sensor by following Adafruit tutorials. The instructions are intentionally vague to prepare you in case you use other sensors for the final project! Don't be afraid to ask the lab staff any questions you might have.
Please keep the sensors on the breadboard as you move through this section.
Wire the potentiometer onto your breadboard. Refer to this Adafruit page as an example.
Fill in test_sensors/pot_test.cpp with test code to read your potentiometer and print the readings to the serial monitor. Refer to this Adafruit page as an example, but remember NOT to specify a baud rate in Serial.begin() (also for all code in the rest of the lab). Additionally, you must add #include <Arduino.h> to the beginning of your file. Upload the code to the ESP32 and see if the readings change when you turn the dial.
Wire the button, LED, and resistor onto your breadboard. Refer to this Adafruit page as an example. You only need one button.
Fill in test_sensors/button_test.cpp with test code to read your button, print something to the serial monitor, and turn on the LED when the button is toggled. For this lab, we will be using the Bounce2 library to filter out undesired state changes (debouncing).
How do I import a library in PlatformIO?
-
Click the PIO Icon on the left side of the screen.
-
Go to
PIO Home/Libraries. -
Search for and click the
Bounce2library. -
Click the "Add to Project" button. Don't click Add in the pop up! Instead, copy the text in the topmost textbox.
-
Exit out of the pop up by clicking the X or the "Cancel" button.
-
Navigate back to see your files and directories by clicking the topmost icon on the left side of the screen.
-
Open the
platformio.inifile, likely the second to the last file, aboveREADME.md. -
Paste the text you copied under the
TODO, in thelib_depssection of[env]. -
Save the file. You should see PlatformIO reprocess the imported libraries.
Where do I find demo code?
-
Navigate back to the
Bounce2library in the PlatformIO "PIO Home" tab. -
You can select an example from the dropdown. For the button, we will use
bounce_basic. -
Copy the code into
test_sensors/button_test.cpp. -
Modify the code to also print a message to the Serial port whenever the button is pressed.
Wire the ToF sensor onto your breadboard. We will be using the I2C protocol.
If you are using the VL6180X, refer to this Adafruit page as an example.
If you are using the VL53L0X, refer to this Adafruit page as an example.
Fill in test_sensors/tof_test.cpp with test code to read your time-of-flight sensor and print the readings to the serial monitor. Similar to the button, you will have to import the ToF library and refer to the demo code.
If you are using the VL6180X, refer to this Adafruit page as an example. The name of the library is Adafruit_VL6180X, and the demo code is called vl6180x.
If you are using the VL53L0X, refer to this Adafruit page as an example. The name of the library is Adafruit_VL53L0X, and the demo code is called vl53l0x.
Wire the IMU onto your breadboard. Refer to this Adafruit page as an example. We will use the SPI protocol. SPI MISO is equivalent to SPI MI and SPI MOSI is equivalent to SPI MO.
Do not connect multiple wires to the same microcontroller pin. If a pin is taken by a previous sensor, connect to another pin and update your code to reflect this.
Fill in test_sensors/imu_test.cpp with test code to read your IMU and print the readings to the serial monitor. We have already imported the IMU library for you. However, you will still have to look it up to refer to the demo code. The name of the library is Adafruit BNO08x, and the demo code is called quaternion_yaw_pitch_roll.
Some (but not all) necessary changes:
- Comment out line 17
#define BNO08X_RESET -1and uncomment line 15#define BNO08X_RESET 5 - Comment out line 52
if (!bno08x.begin_I2C()) {and uncomment line 54if (!bno08x.begin_SPI(BNO08X_CS, BNO08X_INT)) {
| ✅ CHECKOFF 1 ✅ |
|---|
| Demonstrate your potentiometer, button, ToF, and IMU sensors to a TA or LA. |
Estimated time of completion: 15 min
Push and hold either of the M1A and M1B buttons on the motor driver to see the wheel spin. Then, wire up the motor and run test_code/motor_drive_test.cpp. The wheel should spin in different directions with varied speeds.
Wire up the encoder and run test_code/encoder_test.cpp. Open the Serial Monitor and confirm that both the direction and the magnitude make sense.
We now want to use one of the sensors to dictate a variable involved in test_code/motor_position_control.cpp. For example, you can use the potentiometer reading to be setpoint. Running test_code/motor_position_control.cpp as is should make the motor oscillate back and forth.
Incorporate sensor reading code from the tests in the previous section into test_code/motor_position_control.cpp. You may have to map or convert your sensor reading into reasonable values for the variable you choose.
You are free to use any sensor you want. You can even use multiple sensors! Consider sensor/s that you think will be useful for the final project.
Getting an insanely large control effort??
If your control effort looks like it's 100 digits long, comment out any delay calls in the loop function. The delay might be messing with the timing of EVERY_N_MICROS.
| ✅ CHECKOFF 2 ✅ |
|---|
Demonstrate your new test_code/motor_position_control.cpp to a TA or LA. |
| ✅ CHECKOFF Clean Up ✅ |
|---|
| Clean up and return your station to it's configuration from the start of lab. Show a TA or LA. If you do not clean up you will be deducted one checkoff. |
Estimated time of completion: now until the end of lab
The next two subsections are purposefully open-ended to encourage exploration. You are welcome to do either, both, or something completely different! (We have random sensors in the bin.) Again, consider doing something you think will be useful for the final project. You will demonstrate to the staff what you have made in the last 10-15 minutes of lab.
Upto now, we've only used wired communications. What happens if we want to control the mobile robot via joystick for the final project? Clearly, the joystick can't also be physically attached to the mobile robot. The microcontrollers we are using can communicate to each other via WiFi.
You first need to divide your setup into a sender and a receiver. In our case, the sender should be connected to your chosen sensor, while the receiver should be connected to the motor. Ask the staff for any necessary parts and rewire your setup.
Run get_mac.cpp on the receiver to get the MAC address of the receiver microcontroller. Then, replace broadcastAddress in wireless/esp_now_sender.cpp to be that MAC address. Run wireless/esp_now_sender.cpp on the sender and wireless/esp_now_receiver.cpp on the receiver. Keep the receiver connected to your machine and open the Serial Monitor.
Confirm that the data received, as printed on the Serial Monitor, is reasonable given the data sent. Hint: Refer to lines 60 to 63 in wireless/esp_now_sender.cpp to see what data is being sent.
Copy wireless/esp_now_sender.cpp to lab_code/sensor_sender.cpp and wireless/esp_now_receiver.cpp to lab_code/robot_receiver.cpp.
Then, modify the newly copied code so that the sender reads and sends sensor data, while the receiver parses this data and uses it to command the motor. Remember what you learned in previous labs about struct to define a message type. You may need to incorporate code from test_code/motor_position_control.cpp.
If you get stuck, refer to this tutorial or ask the staff for help!
Up to now, we've conducted all our validation tests by printing to the Serial Monitor. This requires constant wired connection to your machine, which isn't always ideal. For example, you might want to troubleshoot sensors on your mobile robot as it is moving! In some cases, it is more convenient to instead use a TFT display.
Ask the staff for a TFT display and wire it onto your breadboard using this Adafruit page as reference. If you did the wireless setup, wire the display to the sender. Or, if your breadboard is too crowded, ask the staff for another microcontroller and breadboard. Remember to validate the new microcontroller by first running robot/blink_test.cpp.
Import the Adafruit_HX8357 library and copy the example code into test_code/display_test.cpp. Run test_code/display_test.cpp to show text and shapes on your display.
Choose a sensor whose readings will be printed on the display. If you are using a new microcontroller and breadboard, rewire your chosen sensor on the new breadboard and revalidate it first using the test code you wrote in test_sensors/.
In lab_code/display_sensor.cpp, combine test_code/display_test.cpp and the test code you wrote in test_sensors/ to print sensor readings to the display instead of the Serial Monitor. You may find the implementation of testText() in test_code/display_test.cpp helpful.
| ✅ CHECKOFF X ✅ |
|---|
| Show your chosen mini-project to a TA or LA. |
Footnotes
-
Version 1 - 2024: Joseph Ntaimo, Jinger Chong, Josh Sohn
Version 2 - 2025: Roberto Bolli, Kaleb Blake ↩





