Skip to content

Commit 568b4f8

Browse files
committed
Touch panel.
1 parent ee524b5 commit 568b4f8

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@
1212
- [Exercise: toggle LED with interrupt](./led_with_interrupt.md)
1313
- [PWM](./pwm.md)
1414
- [Exercise: LED breathing effect](./pwm_led_breathing.md)
15+
- [Touch panel](./touch_panel.md)

src/touch_panel.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Touch panel
2+
3+
In this workshop we'll learn how to set up and use the capacitive touch sensor on our board.
4+
5+
The board manufacturer tells us that the capacitive panel driver IC is AXS5106L.
6+
Typically, in embedded systems development, we would download the part datasheet and start writing a driver for it.
7+
Unfortunately, this chip is one of the obscure Chinese parts and has very little information on it.
8+
9+
Fortunately though, the board manufacturer provides a sample C code and someone already ported that to Rust.
10+
The library we'll be using today is [axs5106l](https://github.com/toto04/axs5106l).
11+
12+
Let's go ahead and add it to our project:
13+
14+
```sh
15+
cargo add axs5106l
16+
```
17+
18+
## Configuration
19+
20+
Hopefully by now you know how to find the documentation and follow the examples, so in this workshop you'll
21+
write most of the code yourself.
22+
23+
Refer to the [`esp_hal`][1] documentation and the [Hardware information][2] page to configure I2C master
24+
peripheral with a 50 kHz clock.
25+
26+
<details>
27+
<summary><strong>Solution</strong></summary>
28+
29+
First, let's import `I2c`. In the example below, we choose not to import `Config` to make it easier to understand
30+
which "Config" we're referring to.
31+
32+
```rust
33+
use esp_hal::i2c::master::I2c;
34+
```
35+
36+
Then, configure the I2C peripheral as below. You can place this just above the PWM configuration section from
37+
the previous workshop.
38+
39+
```rust
40+
let i2c_config = esp_hal::i2c::master::Config::default()
41+
.with_frequency(Rate::from_khz(50));
42+
let i2c = I2c::new(peripherals.I2C0, i2c_config)
43+
.unwrap()
44+
.with_sda(peripherals.GPIO18)
45+
.with_scl(peripherals.GPIO19);
46+
```
47+
</details>
48+
49+
Next, we'll need to configure the touch driver reset GPIO, as it is required by the library.
50+
You can find the pin number in the schematics.
51+
52+
<details>
53+
<summary><strong>Solution</strong></summary>
54+
55+
```rust
56+
let touch_driver_reset_pin = Output::new(
57+
peripherals.GPIO20,
58+
esp_hal::gpio::Level::Low,
59+
OutputConfig::default(),
60+
);
61+
```
62+
</details>
63+
64+
And finally, create the instance of the touch driver and initialize it.
65+
66+
<details>
67+
<summary><strong>Solution</strong></summary>
68+
69+
```rust
70+
let mut touch_driver = axs5106l::Axs5106l::new(
71+
i2c,
72+
touch_driver_reset_pin,
73+
172,
74+
320,
75+
axs5106l::Rotation::Rotate0,
76+
);
77+
78+
touch_driver.init(&mut delay).expect("failed to initialize the touch driver");
79+
```
80+
</details>
81+
82+
## Reading the data
83+
84+
The last part of the puzzle is to read out the data and print it out to the terminal.
85+
86+
<details>
87+
<summary><strong>Solution</strong></summary>
88+
89+
The `get_touch_data()` function returns an Option wrapped in a Result. The Option indicates that there may not be
90+
any data available (no touch event), while the Result is used to express any communication errors.
91+
92+
We can use the `match` statement to handle this in a simple way:
93+
94+
```rust
95+
match touch_driver.get_touch_data() {
96+
Ok(Some(data)) => info!("{data:?}"),
97+
Ok(None) => (),
98+
Err(err) => error!("error reading touch data: {err:?}"),
99+
}
100+
```
101+
</details>
102+
103+
## Exercise
104+
105+
For the final exercise, use the touch panel as a makeshift slider control to set the LED brightness.
106+
107+
<details>
108+
<summary><strong>Solution</strong></summary>
109+
110+
```rust
111+
const MAX_PWM_VALUE: u32 = 255;
112+
const MAX_DISPLAY_Y: u32 = 320;
113+
114+
loop {
115+
match touch_driver.get_touch_data() {
116+
Ok(Some(data)) => {
117+
let brightness = (MAX_PWM_VALUE * data.points[0].y as u32 / MAX_DISPLAY_Y) as u16;
118+
info!("y={}, brightness={}", data.points[0].y, brightness);
119+
led.set_timestamp(brightness);
120+
}
121+
Ok(None) => (),
122+
Err(err) => error!("error reading touch data: {err:?}"),
123+
}
124+
125+
delay.delay_millis(20);
126+
}
127+
```
128+
</details>
129+
130+
[1]: https://docs.espressif.com/projects/rust/esp-hal/1.0.0-rc.0/esp32c6/esp_hal/i2c/master/struct.I2c.html
131+
[2]: setup/hardware.md

0 commit comments

Comments
 (0)