Lab1 - The Artemis board and Bluetooth
Published:
Objective
The purpose of this lab is to setup and become familiar with the Arduino IDE and the Artemis board, by programming the board, using the board LED, reading/writing serial messages over USB, and using the onboard temperature sensor and Pulse Density Microphone.
Keywords
BLE, Data Transfer
Prelab Setup
After we uploaded the ble_arduino.ino into our Artemis, the MAC address of our Artemis was automatically printed it out because of the Setup() function.
When we updated our Artemis MAC address in the connection.yml file, we can connect our computer with the Artemis by bluetooth. We can send the commands from our computer in the Python file by using the bluetooth as the bridge to our board. The connection is shown:
Lab Tasks
Task 1 - ECHO Command
This task required sending an ECHO command with a string value from the computer to the board and receiving the augmented string. For the Artemis, I implemented a command case named ECHO. First, checked whether the string length exceeds the maximum length limit, and then appended the extra words to the string, and sent back finally.
On the computer, after the command code was loaded for the board, ran the ECHO command in the demo.ipynb and got the echo output:
Task 2 - GET_TIME_MILLIS Command
This task required the implementation of the command GET_TIME_MILLIS and receiving the time string from the board. I created a case command GET_TIME_MILLIS, and implemented it by concatenating the strings together and used the writeValue() function to send the completer string back to the computer.
And ran the command in demo.ipynb and get the return output:
Task 3 - Setup of Notification Handler by Asynchronous Function
The task required implementing an asynchronous function in our demo.ipynb to serve as the notification handler to receive string values from the board. First defined an empty global array variable time_stamps to store the time stamps. Second, we got the string messages from the board and strip the first two elements which should be “T:” here. Then, we appended the pure time value into the time_stamps array. We “started” the handler and tested it by sending “PONG” and a time string, and got the expected striped output.
Task 4 - Transfer Time Data within Each Iteration
The task required continuously sending the millisecond timestamp and getting received by the handler and estimating the data transfer rate. Here, I defined a case for Artemis called SEND_TIME_STAMPS to continuously send messages for 4000ms:
Then, I received the data and stored them after the handler function processed those data. And based on the number of collected data and the time duration, calculated the data rate:
Task 5 - Transfer Time Data by Stroing first and Sending back next
This task required us to store the time stamps first and after all the stamps were collected, then send those time stamps back one by one. This task was different with Task 4 which was generating one stamp and sent back immediately. For this task, I defined a global variable in ble_arduino.ino as char timeStamps[50]* and I recorded 50 stamps in total. I also added a case command named ADD_TIME_STAMPS to create dynamic string arrays and store the stamps. Also, I used timeStamps_new_status to record whether the array had elements inside to avoid overwritten.
Then, we defined SEND_TIME_DATA to loop over the timeStamps array to send back the stamps. Meanwhile, deleted all the dynamic memory to avoid memory leak. I got the same time values from both the board output and our computer output, where our computer already processed the data to keep the numerical value and store them into time_stamps list.
Task 6 - Transfer Time and Temperature Data by Stroing first and Sending back next
This task required us to simultaneously record temperature and time readings, and store them first and then send them back one by one correspondingly. I added a case named ADD_TEMP_STAMPS to simultaneously record temperature and time. Inside the case, I first reset two lists to make them synchronous, and then stored 50 groups of data.
After I stored the data, I inplemented another case GET_TEMP_READINGS to send the data groups back to the computer. Among each data group, I used “|
” as the delimiter.
In the demo.ipynb, I modified my notification handler into time_temp_notification_handler() which could parse strings and populate the data into two lists time_stamps and temp_stamps.
which showed that both the two lists got the 50 corresponding data groups.
Task 7 - Comparison of Two Data Transfer Methods
Based on the time stamps, I used the first one and the last one time readings to get the time duration (unit: ms). Then, I used the duration to calculate the record rate. Although there were some repeating data records, I think they all should be counted into “how fast” the second method can record data because our board indeed recorded them during the period. After calculation, the limit speed should be around 2273Hz.
Assume we only count the data memory from the stored arrays in our board, which in this way should be time_stamps and temp_stamps. One char variable takes up 1 byte, and one float variable takes up 4 bytes. In this way, we can estimate the limit groups of stored data to be around 76800. But in practice, definitely we can store fewer data groups.
As for sending each reading immediately, this method is simple, and suitable for real-time data transfer. However, it is less power-efficient, and tends to miss collecting data because of the BLE transmitting speed which should not be negligible. As for collecting readings and sending in bulk, this method is more power-efficient because it reduces the number of times the radio needs to be active to send data. Also, it can collect more data in higher precision with higher sampling rate. However, it cannot be used in real-time data transmission, and it should consider the problem from data overwritten. If we only need to collect data from a period of time, and use them to analyse something, then the second method should be used.