ECE4160/5160-MAE 4190/5190: Fast Robots course, offered at Cornell University in Spring 2023
This project is maintained by CEI-lab
The purpose 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.
Add a command GET_TEMP_5s which sends an array of five timestamped internal die temperature readings using a string array, taken once per second for five seconds. For example, you could send temperatures in pairs as “T:06050|C:28.545|T:07082|C:28.537” (and so on until) five timestamped temeratures are sent. Remember the characteristic size limit! Add processing code to your Python notification handler.
Add a command GET_TEMP_5s_RAPID which sends an array of five seconds worth of rapidly sampled temperature data. You should try to send at least fifty temperature points. Remember the characteristic size limit, and add processing code to your Python notification handler.
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.
Include screenshots of relevant results (i.e. messages received in Jupyter Notebook, serial terminal print of messages received by Artemis).