NOTE: The project is found at Github
Session 2¶
Starting up¶
Just like in the previous session, start by downloading the virtual machine. If you are using the same computer, you can simply open the one you created earlier.
The virtual machine can be found through its Lovelace link.
Next, clone or download Github's course repository again.
The virtual machine can be found through its Lovelace link.
Next, clone or download Github's course repository again.
There have been some updates since Session 1, so if you previously forked the repository, remember to click the Sync fork button before cloning it.
If this operation is giving problems, i would suggest creating a new fork of the repo, and continue with that.
After setting up the virtual machine, please fill the attendance form.
JTKJ HAT¶
This time, you have received a box containing the board’s HAT (Hardware Attached on TOP), a custom-designed and fabricated board created at the Center for Ubiquitous Computing (UBICOMP) for this course. The HAT includes the Raspberry Pi Pico that you worked with during the previous session. We have also included an LCD display that you should attach to the HAT. All information about the device has already been presented during the lectures and in section 8 (peripherals) of the Lovelace documentation.
IMPORTANT NOTE: This is a self-fabricated board. We could not add yet any protection to it, so be careful when you handle it and transport it. When you transport it remove the LCD and put all the parts ALWAYS in the box. Do not put lot of pressure on the board. Please, always handle it with care.
In addition to the hardware, we have created an SDK for the board. The SDK can be found in the
/libs/TKHAT folder of the repository, and you are asked to make some small modifications to it during the exercise. The documentation for each function can be found in the header file: /libs/TKHAT/include/tkjhat/sdk.h. The documentation is also automatically generated in the /libs/TKHAT/docs/out folder and replicated on the Github repo’s documentation page.Exercise 0 Hello HAT¶
Like we have done in the previos session, we would like to start with a simple project that would help you to understand the structure of a program using the HAT.
Let's first explore the TKJHAT SDK documentation. Yes, you have to open it and have a look. The topics section on the left organizes the information according to the different sensors, actuators, or their groups. In the files section, the sdk.h file contains the information about all the functions that we use. As explained in the Lovelace peripherals section, for every sensor connected to the I2C bus there are at least two functions that need to be used.
init_xxconfigures the sensor and, in some cases, powers it on to start measurements. It must be called before using the sensor.xx_read_yyyis used to request data from the sensor. The function takes different parameters depending on the type of sensor in question.
OOkay, explore the documentation a bit and check which sensors/actuators are available and how they can be used. In the near future, we will provide more examples on how to use different sensors.
Now, open the Hello HAT application located at
/examples/hello_hat with the target hello_hat. Explore the CMakeLists.txt (especially the target_link_libraries section, which shows which libraries are needed) and main.c.In this example, we have different tasks: one toggles the LED, the second emits a periodic 440 Hz beep on the buzzer, and a third shows a counter on the display.
Please compile and flash the code to the Pico as you did last time. Remember to make sure the device is properly recognized by the virtual machine, both when you put it in BOOTSEL mode and in normal mode. Finally, check that the device runs and behaves as expected. Please, note that you need to open the serial monitor in order to make your system work
Exercise 1 - Button and LED¶
Ok, from now on, we are working on the main target (located at the root:
src/main.c). The name of the main target is hat_app. Open and explore the files.This file contains some basic code and many comments indicating what you need to implement. Yes, this time you will write code, not just follow instructions. All the code you need to add has already been explained in the course material. That is why it is very important that you have read the material beforehand.
Each section to be implemented is introduced by a comment BEFORE the part you need to write. The comment starts with
Exercise X, where X is the exercise number (1 to 4). Do not modify any other code unless instructed in this tutorial.Let's start with the instructions for Exercise 1. In this task, we will use the button included in the Pico extension board to turn the board’s LED on or off. To achieve this, we need to do the following:
- Initialize the pins in the
mainfunction with the correct settings (in this case, we need to initialize the pins associated with the button and the red LED, not the RGB LED). - Create an interrupt handler for the button.
* Change the state of the LED inside the handler (using the
toggle_led function). - Assign the interrupt handler to the button.
All the necessary information to complete this exercise can be found in the sections Input and Output, Interruptions, and of course the TKJHAT SDK.
The buttons do not have a dedicated function for reading their values, but you should associate an interrupt with them. The TKJHAT SDK provides suitable functions to toggle the LEDs. The Lovelace section Interruptions explains how to create interrupts.
Exercise 2 - Reading sensor data¶
In this exercise, we will use the I2C bus in our program to read ambient light values from the VEML6030 sensor integrated into the TKJ HAT. To make the results easier to see, we will print these values to the terminal window of our development environment.
In addition to modifying
main.c, this time we will also make a small edit to the SDK. We need to partially implement the function veml6030_read_light() in libs/TKJHAT/src/sdk.c.So, STEP 1: implement the function
veml6030_read_light in libs/TKJHAT/src/sdk.c:- Review the I2C section in the serial communication chapter in Pico. You will find a similar example there, but with a temperature sensor.
- Create the data structures required for communicating with the sensor. The chapter Peripheral devices will help you with this.
- Define a
txBufferandrxBufferto send and receive data. Use appropriate sizes and initial values. In this case, we are reading from register 0x04 (VEML6030_ALS_REG). See the veml6030 datasheet for more information, although the information in Peripheral devices should be sufficient. - Perform the required
i2c_write_blockingandi2c_read_blockingcalls to read the sensor value. - When you receive the data in
rxBuffer, apply the necessary bitwise operations and multiplication to obtain the luminance value. The code contains instructions. Store the result in the variableluxVal_uncorrected.
STEP 2 implementing the
sensor_task function, which reads data from the sensor using the previous function you have implemented and print the result in the terminal. In task
sensor_task- Initialize the light sensor with function
init_veml6030(Header fileveml6030.hinsensors-library) - Read data from the sensor with function
veml6030_read_lightin infinite loop - Print the data to terminal window
Exercise 3 - State machine¶
In this exercise you need to implement the state machine depicted in the diagram below.
So, every time a new measurement is acquired from the sensor in
sensor_task, the state of the program is changed to DATA_READY and the value read is transferred via a global variable to print_task. The print_task would print the value in the terminal, so you would need to remove the printing from the sensor_task.You would need to add the missing states in the enumeration
state. A global state variable and a variable to store the measurement value are provided in the code.In the task, it could be beneficial to decrease the sleep period of
print_task, for example to 500 milliseconds.When you finish this task you have completed the exercise. If you want you can continue with the voluntary task, that will help to integrate the usb-serial-debug library in your code.
Add both the
main.c and the sdk.c in the following return box. If needed .zip them first. Exercise 4 - Using usb-serial-debug (VOLUNTARY)¶
This task is not mandatory
In this task, the idea is to use the usb-serial-debug library to communicate with the device. The idea is that the
print_task use this library and the TinyUSB library to send both debug messages and data to two different terminal ports. We are replicating the example hello_dual_cdc you tested in Session 1. The
print_task:- Uses the usb_serial_print to print the text
Lux:xxxfor each sample taken, where xxx represents the luminance value. - Use the TinyUSB
tud_cdc_n_writefunction to send each sample in new line with csv format:timestamp,luminance.
You should have some initialization in the main. In addition you should do small modification to the CMakeLists.txt
- The
pico_enable_stdio_usbshould be set to 0 (We are using our own library for sending debug code). - You should include
usb_serial_debugto the libraries linked intarget_link_libraries
To conclude¶
Now we can blink a led in Pico's extension board, read sensor data and communicate with rest of the world by the means of serial communications!