Lab 1B

Objective

Lab 1B sets up Bluetooth communication between the computer and Artemis board, enabling Python commands from the Jupyter server to control the board. It also establishes a data transmission framework for future labs.

MAC address and UUID printed in Arduino serial monitor after connecting
MAC address and UUID printed in Jupyter interface

Prelab

Setup

To set up my computer for Lab 1, I installed Python, created a virtual environment, and connected to the Jupyter server. To set up the Artemis Board, I first downloaded the provided codebase. I then updated the Artemis MAC Address and changed the BLEService UUID to ensure exclusive connection to my own board.

Codebase

The provided codebase sets up a Bluetooth Low Energy (BLE) communication channel between the computer and the Artemis board using the ArduinoBLE library on the Artemis and a Python interface on the computer via Jupyter Labs. In BLE communication, UUIDs differentiate data types, while BLE characteristics handle data transmission. Commands sent from the computer are processed by the RobotCommand class in ble_arduino.ino. The handle_command() function interprets these commands using a switch statement to execute corresponding actions. The EString class is used for handling character arrays, and BLECStringCharacteristic is used to send and receive string-based commands. When transmitting data, it is important to keep in mind that the maximum message size that can be sent via BLE is 150 bytes.

ECHO

I implemented the ECHO command, which is used to send a string from the computer to the Artemis board. The Artemis board then sends an augmented string back to the computer. For instance, if “yoooo” is sent, the message received will be “Robot says -> yoooo”.

SEND_THREE_FLOATS

I implemented the SEND_THREE_FLOATS command. It is used to send three floats to the Artemis board, which then extracts the three values.

Arduino code
Python interface
I had to update cmd_types.py in the codebase to include the new command.
I also had to add the new command to the enum types in the Arduino sketch.

GET_TIME_MILLIS

I implemented the GET_TIME_MILLIS command, to which the Artemis must reply by writing the current time in milliseconds to the string characteristic.

Notification callback function

Notification Handler

I set up a notification handler in Python, which will allow the computer to continuously collect data without needing to explicitly issue read commands.

Arduino code
Python interface. A total of 141 messages were received in 3s, indicating a data transfer rate of 47 messages/second.

GET_TIME_MILLIS_3S

I implemented the GET_TIME_MILLIS_3S command, which tells the Artemis to continuously write the current time in milliseconds to the string characteristic for 3 seconds. The notification handler receives and processes these messages. With this method, I was able to track the data transfer rate.

Arduino code
I made sure to initialize the array under global scope.
Python code
I realized that I had many repeated timestamps in my data. I post-processed my received messages and obtained counts for each timestamp. I suspect this may be due to the fact that I am using a for-loop to add timestamps to a global array before attempting to send the data, and the for-loop executes many times per millisecond.

SEND_TIME_DATA

My implementation of the SEND_TIME_DATA command tells the Artemis to first store timestamps in a global array, then loop through the array to send each entry to the laptop as a string. In the Python interface, I stored all the received messages in a list to check if all the data was sent. Since I was only sending one entry at a time (each timestamp was 4 bytes in size, well under the 150-byte limit), I did not have to worry about limiting my array size so I set it to 300.
However, it is important to note that my implementation would have looked very different if I were required to send the entire array of messages at once. Since the BLE protocol used in this lab sets a 150-byte limit on data that can be sent, my array size would be capped at 150.

Arduino code
Updated notification callback function to accomodate for two separate lists.
Received messages
The length of each list is 250, which is expected.

GET_TEMP_READINGS

My implementation of the GET_TEMP_READINGS command tells the Artemis to first store timestamps and temperatures in seaparte global arrays, then loop through both arrays simultaneously to send each entry to the laptop as a string. In the Python interface, I split the message into its time and temperature components, and stored each in a separate list.

Discussion

Lab 1B was very helpful for familiarizing myself with Bluetooth communication. It was also a good way to visualize real-time data collection, and offered a glimpse into the ideas of data transfer rate, which will be very important later on.