ECE4160/5160-MAE 4190/5190: Fast Robots course, offered at Cornell University in Spring 2024
This project is maintained by FastRobotsCornell
The purpose of this part of the lab is for you to setup and become familiar with the Arduino IDE and the Artemis board. After this lab, you should be comfortable programming your board, using the board LED, reading/writing serial messages over USB, and using the onboard temperature sensor and Pulse Density Microphone.
(These will be handed out during lab 1 - note if you decide to drop the class please give these back to a TA.)
Install the Arduino IDE on your computer. Please use the latest versions of ArduinoIDE and Sparkfun Appollo3 support software. Update them if necessary. If you have any issues, please contact the TA team. While we only guarantee TA support on the lab computers this semester, you can likely do all Arduino-related tasks on your own computer which will save everyone time!
Check out the Artemis description, features, and helpful forums here:
Finally, please skim the lab instructions in order to be prepared for what to do in your section!
For all of the following tasks, think about how you will document that your code works. We cannot grade “I did this..”. Instead, you can choose to upload photos, screenshots of the serial monitor, screen-recordings, videos of the board, and/or grab the data from the serial monitor and plot them in a graph. As always, feel free to check last years solutions for examples.
The purpose of part two of this lab is to establish communication between your computer and the Artemis board through the Bluetooth stack. We will be using Python inside a Jupyter notebook on the computer end and the Arduino programming language on the Artemis side. We will also establish a framework for sending data via Bluetooth that will be useful in future labs.
Please read up on this fantastic summary of Bluetooth Low Energy (BLE).
You will need to install Python 3 and pip. If you already have them installed, please make sure you have the latest releases (Python >= 3.9 and pip >= 21.0).
Some Windows users may need to use `python` instead of `python3`
python3 --version
python3 -m pip --version
Minimum Requirements: Linux kernel 4.15+ and bluez 5.48+
Simply use your package manager to install python3 and pip :).
Minimum Requirements: Windows 10
Recommended OS: macOS 12.0
It may work with (some) older versions. If you have issues with older versions, contact the teaching team. We will try out best to help you.
python3
.A virtual environment is a Python environment such that the Python interpreter, libraries and scripts installed into it are isolated from those installed in other virtual environments, and (by default) any libraries installed in a “system” Python, i.e., one which is installed as part of your operating system.
Run the following commands in a Command Line Interface (CLI):
python3 -m pip install --user virtualenv
Place all your Python scripts and Jupyter notebooks within this directory.
python3 -m venv FastRobots_ble
venv will create a virtual Python installation in the newly created FastRobots_ble directory.
For any lab using Python scripts (or Jupyter notebooks), you will first need to activate your virtual environment.
This will only work from the project folder (the one containing the FastRobots_ble folder).
source FastRobots_ble/bin/activate
.\FastRobots_ble\Scripts\activate
source FastRobots_ble/bin/activate
deactivate
Your CLI prompt should no longer display the prefix.
Your CLI prompt should now have the prefix (FastRobots_ble).
pip install numpy pyyaml colorama nest_asyncio bleak jupyterlab
NOTE: In Windows, you may see an error while installing some of these packages. Follow the download link in the error message to download and install (the unnecessarily huge) C++ build tools.
ble_python
directory into your project directory.ble_robot-1.1
├── ble_arduino
| ├── ble_arduino.ino - Arduino code that will be compiled and run on the Artemis board
| ├── BLECStringCharacteristic.h - class definition used to send and receive data
| ├── EString.h - class definition for Extended String used to easily manipulate character arrays
| └── RobotCommand.h - class definition used to extract values of different data types from the robot command string sent to the Artemis board
└── ble_python
├── __init__.py
├── base_ble.py
├── ble.py
├── cmd_types.py - definition of command type mappings to integers
├── connections.yaml - assigning UUIDs to different data to send/receive
├── demo.ipynb - main Jupyter Notebook to run commands
├── logs
| ├── __init__.py
└── utils.py
We will be using Jupyter notebooks to write Python code. Before you can open a Jupyter notebook, you need to start the Jupyter server. If the Jupyter server is stopped, you will not be able to run/open/modify any Jupyter notebooks.
The Jupyter server can only access notebooks from the directory it was started in.
jupyter lab
macOS users may have to use
Jupyter lab
(capital J).
If no window opens up, click on the URL displayed in the CLI.
You will be writing most of your Python code using this browser window on Jupyter notebooks. For students proficient in Python, you may choose to write some of your modules in Python script files and import them into your Jupyter notebook.
If you are new to JupyterLab, please go through the Introduction to JupyterLab tutorial (available under the Tutorials page).
Please read through the codebase (in particular, the demo.ipynb
Jupyter notebook) to understand the different functions that you will be using in this lab.
Install ArduinoBLE from the library manager (Tools -> Manage Libraries…) in the Arduino IDE.
Make sure you change the serial baud rate to 115200 bps.
The Python and Artemis packages provide you with the base code necessary to establish a communication channel between your computer and the Artemis board through BLE.
Though a characteristic value can be up to 512 bytes long (according to the Bluetooth Core Specification), the ArduinoBLE library limits the maximum size to 255 bytes. We are using a more conservative size limitation of 150 bytes. The provided Python codebase throws an error if you attempt to send data that is larger than the member variable ArtemisBLEController.max_write_length (150 bytes). On the Arduino side, the macro MAX_MSG_SIZE (defined in EString.h) is used to set the character array sizes used in various classes.
This is a summary of the code running on your Artemis, found in the ble_arduino.ino
file.
from uuid import uuid4
uuid4()
ble_arduino.ino
to see how to use BLEService for our purposes, or this page for more examplesble_arduino.ino
, or here for all the characteristicswriteValue( value );
– value to transmit to your computer; ensure that the data type matches the characteristic type you use
* For receiving characteristics:written();
– returns 1 if value has been written to this UUID by another BLE devicevalue();
and valueWritten();
– returns a uint8 array containing the BLE characteristic value, and the length of the uint8 array; used in set_cmd_string()
function in RobotCommand.hble_arduino.ino
.RobotCommand robot_cmd(":|");
where “:|” is the delimiterset_cmd_string( value, valueWritten );
– set the command string from the characteristic value received for the RobotCommand object instantiatedget_command_type( cmd_type );
– returns 1 if successful; sets cmd_type
as the integer value sent by the other deviceget_next_value( val );
– returns 1 if successful; extracts the next value from the command string and assigns it to val
; ensure that the type of val is what is expected (by ensuring you handle cmd_type
properly in case statements in handle_command()
)handle_command()
in ble_arduino.ino
for an example on how to use EStringclear();
– empties the contents of the character arrayappend();
– append a float, double, int, character array, or string literal to the EStringc_str();
– returns the character arrayhandle_command()
** End of Prelab **
artemis_address: 'C0:C2:8A:89:98:08'
A valid MAC address is a 12 digit hexadecimal number, often represented as 6 pairs of hexadecimal digits separated by colons. If the Artemis board displays a MAC address that is lesser than 12 digits, left pad the appropriate pairs with 0s. For example, if the displayed MAC address is
C0:C2:8A:89:98:8
, update the configuration file(connection.yaml) withartemis_address: 'C0:C2:8A:89:98:08'
from uuid import uuid4
uuid4()
#define BLE_UUID_TEST_SERVICE "9A48ECBA-2E92-082F-C079-9E75AAE428B1"
ble_service: '9a48ecba-2e92-082f-c079-9e75aae428b1'
if IS_ATLEAST_MAC_OS_12:
to
if True:
Run through all the cells before you begin to work on the lab tasks.
In order to test your robot’s sensors more effectively, it is critical to have a working wireless debugging system. The following tasks will ensure that you can receive timestamped messages from the Artemis board.
For example, the computer sends the string value “HiHello” to the Artemis board using the ECHO command, and the computer receives the augmented string “Robot says -> HiHello :)” from a read GATT characteristic.
Add a command GET_TIME_MILLIS which makes the robot reply write a string such as “T:123456” to the string characteristic.
Setup a notification handler in Python to receive the string value (the BLEStringCharactersitic in Arduino) from the Artemis board. In the callback function, extract the time from the string.
Write a loop that gets the current time in milliseconds and sends it to your laptop to be received and processed by the notification handler. Collect these values for a few seconds and use the time stamps to determine how fast messages can be sent. What is the effective data transfer rate of this method?
Now create an array that can store time stamps. This array should be defined globally so that other functions can access it if need be. In the loop, rather than send each time stamp, place each time stamp into the array. (Note: you’ll need some extra logic to determine when your array is full so you don’t “over fill” the array.) Then add a command SEND_TIME_DATA which loops the array and sends each data point as a string to your laptop to be processed. (You can store these values in a list in python to determine if all the data was sent over.)
Add a second array that is the same size as the time stamp array. Use this array to store temperature readings. Each element in both arrays should correspond, e.e., the first time stamp was recorded at the same time as the first temperature reading. Then add a command GET_TEMP_READINGS that loops through both arrays concurrently and sends each temperature reading with a time stamp. The notification handler should parse these strings and add populate the data into two lists.
Perform an analysis on the communication performance.
TIP: Use the notification handler for this. If you find a better way, include your approach in the write-up.
Effective Data Rate And Overhead: Send a message from the computer and receive a reply from the Artemis board. Note the respective times for each event, calculate the data rate for 5-byte replies and 120-byte replies. Do many short packets introduce a lot of overhead? Do larger replies help to reduce overhead? You may also test additional reply sizes. Please include at least one plot to support your write-up.
Reliability: What happens when you send data at a higher rate from the robot to the computer? Does the computer read all the data published (without missing anything) from the Artemis board? Include your answer in the write-up.
Word Limit: < 1000 words
We understand that some of the sections in your webpage will overlap with the instructions in the lab handout. That is okay as long as there is no blatant copying and pasting. Paraphrase instructions in a way that shows you understand and have executed them.
This is not a strict requirement, but may be helpful in understanding what should be included in your webpage. It also helps with the flow of your report to show your understanding to the lab graders.
Please also include code snippets (consider using GitHub Gists) in appropriate sections if you included any written code. Do not copy and paste all your code. Include only relevant functions used for each task. Points will be deducted for pasting all of your code in the lab report. Also consider adding pseudocode snippets if large amounts of code are needed to explain your lab.