10. Sensor Development Basics Courses

10.1 Fan Module

10.1.1 Getting Ready

Prepare a fan module and connect it to GPIO pins 7 and 8 on the Raspberry Pi expansion board using a 4-Pin cable. The wiring should appear as shown in the diagram below.

Note

Please do not insert forcefully because 4PIN cable uses anti-reverse plugging design.

10.1.2 Module Usage

No additional motor driver board is required to use the fan module. Its rotation direction and speed can be controlled programmatically. Additionally, the module is compatible with LEGO series components, enabling more creative DIY designs.

10.1.3 Operation Steps

(1) Click icon in the upper left corner to open a new terminal window. Then enter the following command and press Enter to navigate to the game directory.

cd /home/pi/TonyPi/Extend/sensor_course/sensor_example/

(2) Enter the command below, and then press Enter to start the game.

python3 fan_control.py

(3) If want to close this program, press “Ctrl+C”. You can try multiple time if fail to close.

10.1.4 Project Outcome

The fan starts spinning when the program runs and automatically stops when the program is closed.

10.1.5 Program Analysis

Source Code

In this project, the fan is controlled using two GPIO ports. When one GPIO port is set to high and the other to low, the fan begins to rotate.

The source code of the program is located in: /home/pi/TonyPi/Extend/sensor_course/sensor_example/fan_control.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/python3
# coding=utf8
# 4.拓展课程学习\7.拓展课程之传感器基础开发课程\第1课 风扇模块实验(4.Advanced Lessons\7.Sensor Development Course\Lesson1 Fan Module)
import time
import gpiod

## 初始化引脚模式(initial pin mode)
chip = gpiod.Chip("gpiochip4")
fanPin1 = chip.get_line(8)
fanPin1.request(consumer="pin1", type=gpiod.LINE_REQ_DIR_OUT)

fanPin2 = chip.get_line(7)
fanPin2.request(consumer="pin2", type=gpiod.LINE_REQ_DIR_OUT)

# initial
def init():
    start = False
    set_fan(0)
    print("Fan Control Init")
    
#fan control
def set_fan(start):
               
    if start == 1:
        ## 开启风扇, 顺时针(turn on the fan, clockwise)
        fanPin1.set_value(1)  # 设置引脚输出高电平(set pin output high voltage)
        fanPin2.set_value(0)  # 设置引脚输出低电平(set pin output low voltage)
    else:
        ## 关闭风扇(turn off the fan)
        fanPin1.set_value(0)  # 设置引脚输出低电平(set pin output low voltage)
        fanPin2.set_value(0)  # 设置引脚输出低电平(set pin output low voltage)

if __name__ == '__main__':
    while True:
        try:
            set_fan(1)
        except KeyboardInterrupt:
            set_fan(0)
            break
  • GPIO Pin Control

(1) chip.get_line(pin_number): Get GPIO (pin).

 8
 9
10
chip = gpiod.Chip("gpiochip4")
fanPin1 = chip.get_line(8)
fanPin2 = chip.get_line(7)

(2) fanPin1.set_value(): Set the voltage level of GPIO pin.

28
29
fanPin1.set_value(1)  # 设置引脚输出高电平(set pin output high voltage)
fanPin2.set_value(0)  # 设置引脚输出低电平(set pin output low voltage)

(3) In the example, the encoding method used is digital logic level encoding.

(4) High level (usually 1) and low level (usually 0).

(5) In the code, the fanPin1.set_value() functions is used to set the logic level state of the GPIO line.

(6) fanPin1.set_value(1): Set No.8 GPIO pin to high voltage level

(7) fanPin2.set_value(0): Set No.7 GPIO pin to low voltage level

(8) fanPin1.set_value(0): Set No.8 GPIO pin to low voltage level

(9) fanPin2.set_value(0): Set No.7 GPIO pin to low voltage level

32
33
fanPin1.set_value(0)  # 设置引脚输出低电平(set pin output low voltage)
fanPin2.set_value(0)  # 设置引脚输出低电平(set pin output low voltage)

10.2 Touch Sensor

10.2.1 Preparation

Prepare a touch sensor and connect it to the GPIO21 and GPIO22 ports on the Raspberry Pi expansion board using a 4-Pin cable. The wiring should appear as shown in the figure below.

Note

Do not insert the 4-pin cable with force. It features an anti-reverse design to prevent incorrect connections.

10.2.2 Module Usage

The touch sensor operates based on the principle of capacitive sensing. When a human body or metal touches the sensor’s gold-plated contact surface, the sensor detects the contact. Additionally, the sensor can sense touches through materials like plastic or paper of certain thicknesses. The sensitivity depends on the size of the contact area and the thickness of the covering material.

This sensor is ideal for switch control applications, such as light switches or doorbell buttons. Moreover, it is compatible with the LEGO series, enabling more creative DIY designs.

10.2.3 Operation Steps

(1) Click in the upper left corner to open the terminal. Enter command and press Enter to go to the directory of game.

cd /home/pi/TonyPi/Extend/sensor_course/sensor_example/

(2) Enter the command below, and then press Enter to start the game.

python3 touch_buzzer.py

(3) If you want to close this program, press “Ctrl+C”. You can try multiple time if fail to close.

10.2.4 Project Outcome

After the program starts, touch the sensor’s metal plate. The buzzer will sound once upon detecting the touch.

10.2.5 Working Principle

Source Code

When the sensor detects a touch, it outputs a high level; otherwise, it outputs a low level. You can determine the sensor’s current status by monitoring the I/O port’s level changes.

The program source code is located at: /home/pi/TonyPi/Extend/sensor_course/sensor_example/touch_buzzer.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/python3
# coding=utf8
# 4.拓展课程学习\7.拓展课程之传感器基础开发课程\第2课 触摸传感器实验(4.Advanced Lessons\7.Sensor Development Course\Lesson2 Touch Sensor Module)
import os
import sys
import time
import gpiod
import hiwonder.ros_robot_controller_sdk as rrc


board = rrc.Board()
    
st = 0

chip = gpiod.Chip('gpiochip4')
touch = chip.get_line(22)
touch.request(consumer="touch", type=gpiod.LINE_REQ_DIR_IN, flags=gpiod.LINE_REQ_FLAG_BIAS_PULL_UP)

if __name__ == '__main__':
    while True:
        state = touch.get_value()   #读取引脚数字值(read pin numerical value)
        if not state:
            if st :            #这里做一个判断,防止反复响(make a judgement to prevent repeated ringing here)
                st = 0
                board.set_buzzer(1900, 0.1, 0.9, 1) # 以1900Hz的频率,持续响0.1秒,关闭0.9秒,重复1次(at a frequency of 1900Hz, sound for 0.1 seconds, then pause for 0.9 seconds, repeat once)
        else:
            st = 1
            board.set_buzzer(1000, 0.0, 0.0, 1) # 关闭(close)

    board.set_buzzer(1000, 0.0, 0.0, 1) # 关闭(close)
  • Touch Detection and Control

(1) Connect the touch sensor to GPIO pin No. 22. The sensor is controlled via gpiochip4, and its pin is configured as input mode.

15
16
17
chip = gpiod.Chip('gpiochip4')
touch = chip.get_line(22)
touch.request(consumer="touch", type=gpiod.LINE_REQ_DIR_IN, flags=gpiod.LINE_REQ_FLAG_BIAS_PULL_UP)

(2) Initialize an rrc.Board() object and a gpiod.Chip object.

11
12
13
board = rrc.Board()
    
st = 0

(3) The program then enters an infinite loop to continuously monitor the touch sensor’s state.

19
20
21
if __name__ == '__main__':
    while True:
        state = touch.get_value()   #读取引脚数字值(read pin numerical value)

(4) Within the loop, the program reads the digital value of the pin using touch.get_value(), which indicates whether the sensor is currently touched. If the sensor is touched (state is low level) and the previous state was untouched (st == 1), the following actions occur:

22
23
24
25
        if not state:
            if st :            #这里做一个判断,防止反复响(make a judgement to prevent repeated ringing here)
                st = 0
                board.set_buzzer(1900, 0.1, 0.9, 1) # 以1900Hz的频率,持续响0.1秒,关闭0.9秒,重复1次(at a frequency of 1900Hz, sound for 0.1 seconds, then pause for 0.9 seconds, repeat once)

(5) Update st to 0 to mark that the touch event has been handled.

(6) Use the board.set_buzzer() function to activate the buzzer at 1900 Hz for 0.1 seconds, followed by a 0.9-second pause, repeating once.

(7) Introduce a 1-second delay to prevent multiple triggers from the same touch event.

(8) If the sensor is not touched (state is high level), set st back to 1 to indicate the idle state.

26
27
28
        else:
            st = 1
            board.set_buzzer(1000, 0.0, 0.0, 1) # 关闭(close)

(9) At the end of each loop iteration, board.set_buzzer() is called to turn off the buzzer, ensuring it remains silent when no touch is detected.

30
    board.set_buzzer(1000, 0.0, 0.0, 1) # 关闭(close)

10.3 Temperature and Humidity Sensor

10.3.1 Preparation

Prepare a temperature and humidity sensor module along with a dot matrix display module. Connect both modules to the Raspberry Pi expansion board using 4-pin cables as illustrated in the diagram below.

Note

The 4-pin cable features an anti-reverse design—please do not force it in.

10.3.2 Operation Overview

The source code for this program can be found at: /home/pi/TonyPi/Extend/sensor_course/sensor_example/temperature_detection.py

The temperature and humidity sensor module (AHT10) communicates with the Raspberry Pi via the I2C interface, while the dot matrix display module connects through the GPIO interface. The sensor converts the ambient temperature and humidity into digital signals, which the control board reads and processes. The processed temperature and humidity data are then displayed on the dot matrix module.

10.3.3 Operation Steps

Note

The input commands are case-sensitive, and keywords can be auto-completed using the Tab key.

(1) Power on the TonyPi robot and connect to the Raspberry Pi desktop remotely via VNC.

(2) Click the icon at the top-left corner of the system desktop to open the Terminator terminal.

(3) Enter the following command and press Enter to navigate to the program directory:

cd /home/pi/TonyPi/Extend/sensor_course/sensor_example/

(4) Open a new terminal window, enter the following command, and press Enter to run the program:

python3 temperature_detection.py

(5) To exit the program, press “Ctrl+C” in the terminal window. If the program does not close immediately, please try pressing it repeatedly.

10.3.4 Program Outcome

Once the program is running, the terminal will display the temperature and humidity readings from the sensor module, while the dot matrix module simultaneously shows the current temperature and humidity values.

10.3.5 Program Overview

Source Code

  • Initialization

11
12
13
14
15
16
17
18
class AHT10:
    CONFIG = [0x08, 0x00]
    MEASURE = [0x33, 0x00]

    def __init__(self, bus=1, addr=0x38):
        self.bus = smbus.SMBus(bus)
        self.addr = addr
        time.sleep(0.2)

The sensor communicates with the Raspberry Pi via the I2C bus.

  • Retrieving Temperature and Humidity Data

20
21
22
23
24
25
26
27
28
29
30
    def getData(self):
        byte = self.bus.read_byte(self.addr)
        self.bus.write_i2c_block_data(self.addr, 0xAC, self.MEASURE)
        time.sleep(0.5)
        data = self.bus.read_i2c_block_data(self.addr, 0x00)
        temp = ((data[3] & 0x0F) << 16) | (data[4] << 8) | data[5]
        ctemp = ((temp*200) / 1048576) - 50
        hum = ((data[1] << 16) | (data[2] << 8) | data[3]) >> 4
        chum = int(hum * 100 / 1048576)
        
        return (ctemp, chum)

(1) self.bus.read_byte(self.addr): Reads the status byte from the sensor.

(2) self.bus.write_i2c_block_data(self.addr, 0xAC, self.MEASURE): Sends a measurement command to initiate data collection.

(3) data = self.bus.read_i2c_block_data(self.addr, 0x00): Reads 6 bytes of measurement data from the sensor.

  • Device Setup

33
34
35
36
if __name__ == '__main__':
    aht10 = AHT10()
    display = TM1640(dio=22, clk=24)
    display.clear()

Initializes the AHT10 sensor instance (aht10) and the TM1640 LED display module (display), then clears any existing content from the display.

  • Data Display Loop

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    while True:
        # 提取温度(extraction temperature)
        tempture = str(round(aht10.getData()[0], 1))

        # 提取出三个数字(Extract three numbers)
        num1, num2, num3 = tempture[0], tempture[1], tempture[3]

        display.display_buf = render_number(num1, num2, ".", num3)
        display.update_display()

        time.sleep(2)

        #提取湿度(Extract humidity)
        humidity = str(round(aht10.getData()[1], 1))

        # 提取出两个数字(Extract two numbers)
        num1, num2 = humidity[0], humidity[1]

        display.display_buf = render_number(num1, num2, "%", "%")
        
        time.sleep(2)

Display Temperature: The temperature is read and rounded to one decimal place. The integer and fractional digits are extracted and passed to the render_number function to generate the display output. The result is shown on the screen for 2 seconds.

Display Humidity: The humidity is read and similarly rounded. The integer digit is extracted, a percentage symbol is appended using the render_number function, and the result is displayed for 2 seconds.

10.4 Ultrasonic Sensor

10.4.1 Preparation

Prepare an ultrasonic sensor and connect it to any available I²C port on the Raspberry Pi expansion board using a 4-pin cable. The wiring setup is shown below:

Note

Do not force the 4-Pin cable into the connector; it is designed to prevent incorrect insertion.

10.4.2 Module Usage

In this lesson, the distance measurement chip of the ultrasonic sensor integrates an ultrasonic transmitter, receiver, and digital signal processing circuit. The module communicates via I²C ports, allowing the measured distance to be read efficiently through I²C communication.

Additionally, the ultrasonic probe includes two integrated RGB lights. These lights not only support adjustable brightness but also allow color customization by modifying the parameters of the red (R), green (G), and blue (B) channels.

10.4.3 Operation Steps

(1) Click in the upper left corner to open the terminal. Enter the following command and press Enter to navigate to the directory of the game program.

cd /home/pi/TonyPi/Extend/sensor_course/sensor_example/

(2) Enter the command below, and then press Enter to start the game.

python3 sonar_rgbd.py

(3) If want to close this program, press “Ctrl+C”. You can try multiple time if fail to close.

10.4.4 Project Outcome

Once the program starts, place an obstacle in front of the ultrasonic sensor. The terminal will display the measured distance, and the RGB light will illuminate in a color corresponding to that distance. The color-distance mapping is as follows:

Distance < 100 mm: Red
100 mm ≤ Distance < 150 mm: Green
150 mm ≤ Distance < 200 mm: Blue
Distance ≥ 200 mm: White

10.4.5 Function Extension

  • Modify the Measured Distance

We can adjust the distance ranges that correspond to each RGB light color. For example, you can change the range for the blue light from “150.0 < distance ≤ 200.0” to “150.0 < distance ≤ 250.0”, and update the range for the white light from “distance > 200” to “distance > 250”. Please follow the steps below to make these modifications:

(1) Launch a terminal, and then enter the following command to come to the directory of the game programmings.

cd /home/pi/TonyPi/Extend/sensor_course/sensor_example/

(2) Enter the following command, and then press Enter to start the game.

vim sonar_rgbd.py

(3) Find the code shown in the figure below.

(4) Press “i” key on keyboard to enter the edit mode.

(5) Modify data as the figure shown below:

(6) After modification, press “Esc” and enter “:wq” (please note that the colon is in front of wq), and then press Enter to save the modified content.

:wq
  • Customize RGB Color

Similarly, we can change the RGB light color. Take changing the color of RGB light from white to orange as example. The specific operation step is as follow:

(1) Please refer to “Modify the Measured Distance” to open game program file.

(2) Find the code as the figure shown below in the opening interface.

(3) Modify the value of RGB to change the light color. setRGB(1,(255,255,255)) and setRGB(0,(255,255,255)) are modified to setRGB(1,(255, 127,0)) and setRGB(0,(255, 127,0)), as the figure shown below:

RGB value refers to the red, green and blue components in a certain color. Theoretically, the three primary colors which are red, green and blue can be mixed in different proportion to make any color. The closer of the RGB value of a color, the closer it is to gray or black and white, and the larger the value, the whiter it is, and vice verse, the darker it is.

For example, the value of B is the largest in RGB (150, 152, 183), which means the color contains more blue color, so it can be identified as a grayish blue.

(4) After modification, press “Esc” and enter “:wq” (please note that the colon is in front of wq), and then press Enter to save the modified content.

:wq

10.4.6 Program Analysis

Source Code

Firstly, set the distance measurement. Then control the on and off of the RGB light by changing the high and low levels. Finally, control the displayed light color by changing the value of each color component.

The source code of program is located in: /home/pi/TonyPi/Extend/sensor_course/sensor_example/sonar_rgbd.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/python3
# coding=utf8
# 4.拓展课程学习\7.拓展课程之传感器基础开发课程\第4课 超声波模块实验(4.Advanced Lessons\7.Sensor Development Course\Lesson4 Ultrasonic Module)
import os
import sys
import time
import hiwonder.Sonar as Sonar

if sys.version_info.major == 2:
    print('Please run this program with python3!')
    sys.exit(0)

s = Sonar.Sonar()
s.setRGBMode(0)    #设置灯的模式,0为彩灯模式,1为呼吸灯模式(set the light mode, 0 is color light mode, 1 is breathing light mode)
s.setRGB(1, (35,205,55))
s.setRGB(0, (235,205,55))
s.startSymphony()

if __name__ == "__main__":
    while True:
        time.sleep(1)
        if s.getDistance() != 99999:
            print("Distance:", s.getDistance() , "mm")
            distance = s.getDistance()
            
            if 0.0 <= distance <= 100.0:
                s.setRGBMode(0)
                s.setRGB(1, (255,0,0))  #两边RGB设置为红色(set both RGB to red)
                s.setRGB(0, (255,0,0))
                
            if 100.0 < distance <= 150.0:
                s.setRGBMode(0)
                s.setRGB(1, (0,255,0))  #两边RGB设置为绿色(set both RGB to green)
                s.setRGB(0, (0,255,0))
                
            if 150.0 < distance <= 200.0:
                s.setRGBMode(0)
                s.setRGB(1, (0,0,255))  #两边RGB设置为蓝色(set both RGB to blue)
                s.setRGB(0, (0,0,255))
                
            if distance > 200.0:
                s.setRGBMode(0)      
                s.setRGB(1, (255,255,255)) # 两边RGB设置为白色(set both RGB to white)
                s.setRGB(0, (255,255,255))
  • Sensor Initialization and Control

(1) The Sonar module is imported first, and a Sonar.Sonar object is created to control the ultrasonic sensor and RGB light.

15
16
17
18
19
s = Sonar.Sonar()
s.setRGBMode(0)    #设置灯的模式,0为彩灯模式,1为呼吸灯模式(set the light mode, 0 is color light mode, 1 is breathing light mode)
s.setRGB(1, (35,205,55))
s.setRGB(0, (235,205,55))
s.startSymphony()

(2) The setRGBMode() function is used to set the mode of the light to color light mode (0), and the setRGB() function is used to set the colors of the two lights. Specifically, setRGB(1, (35,205,55)) sets the first light to green, and the second light to yellow.

(3) The startSymphony() function is used to start the mode.

(4) In the main loop, the program executes every 1 second.

21
22
23
24
        time.sleep(1)
        if s.getDistance() != 99999:
            print("Distance:", s.getDistance() , "mm")
            distance = s.getDistance()

(5) Get distance and process: By calling the getDistance() function, obtain the distance measured by the ultrasonic sensor and store it in the distance variable.

(6) Set the color of the lights based on the distance: Use the setRGB() function to set the colors of the two lights based on the distance measurement and the following conditional statements.

(7) If the distance is between 0.0 and 100.0, set the colors of the two lights to red.

28
29
30
31
            if 0.0 <= distance <= 100.0:
                s.setRGBMode(0)
                s.setRGB(1, (255,0,0))  #两边RGB设置为红色(set both RGB to red)
                s.setRGB(0, (255,0,0))

(8) If the distance is between 100.0 and 150.0, set the colors of the two lights to green.

33
34
35
36
            if 100.0 < distance <= 150.0:
                s.setRGBMode(0)
                s.setRGB(1, (0,255,0))  #两边RGB设置为绿色(set both RGB to green)
                s.setRGB(0, (0,255,0))

(9) If the distance is between 150.0 and 200.0, set the colors of the two lights to blue.

38
39
40
41
            if 150.0 < distance <= 200.0:
                s.setRGBMode(0)
                s.setRGB(1, (0,0,255))  #两边RGB设置为蓝色(set both RGB to blue)
                s.setRGB(0, (0,0,255))

(10) If the distance is greater than 200.0, set the colors of the two lights to white.

43
44
45
46
            if distance > 200.0:
                s.setRGBMode(0)      
                s.setRGB(1, (255,255,255)) # 两边RGB设置为白色(set both RGB to white)
                s.setRGB(0, (255,255,255))

10.5 Dot Matrix Module

10.5.1 Preparation

Prepare a dot matrix module and connect it to any available GPIO port on the Raspberry Pi expansion board using a 4-Pin cable. The wiring setup is shown below:

Note

Avoid applying force when inserting the 4-pin cable—its anti-reverse design ensures correct orientation.

10.5.2 Module Usage

The dot matrix module used in this lesson is composed of two red 8×8 LED dot matrix screens. The dot matrix screen can be controlled by driving the control chip. It features high display brightness, no flash during display and simple wiring, and can display number, text, pattern and other contents.

10.5.3 Operation Steps

(1) Open the terminal and input the following command. Press Enter to come to the directory of the game program.

cd /home/pi/TonyPi/Extend/sensor_course/sensor_example/

(2) Enter the following command, and then press Enter to start the game.

python3 lattice_display.py

(3) If want to close this program, press “Ctrl+C”. You can try multiple time if fail to close.

10.5.4 Project Outcome

After the program is started, the dot matrix screen will display the text “Hello”. When the program is closed, the screen will turn off completely.

10.5.5 Function Extension

The default content displayed in this section of the program is “Hello” in dot matrix. If you want to modify the displayed text, for example, changing it to “Love”, you can follow these steps:

Before making modifications, we need to obtain the address symbols of the letters in the dot matrix display. Here, we can use modulus software to obtain them.

(1) Double-click to open the modulus software located in the same directory as this section.

(2) First, click on “New Image”, then in the popup settings box, set the size parameters of the dot matrix module to “16*8”. Once set, click “OK” to confirm.

(3) Click “Simulated Animation” and “Enlarge Grid Points” in turn to enlarge the dot matrix simulation area on the right side.

(4) Next, use the mouse to click and draw the displayed content in the right area.

(5) After finishing the drawing, click on “Modulation Mode” and then “51 Format” in turn to obtain the address symbols.

(6) Open terminal and input the following command. Press Enter to locate to the content of the game program.

cd /home/pi/TonyPi/Extend/sensor_course/sensor_example/

(7) Input the command below and press Enter to open game program file.

vim lattice_display.py

(8) Locate the following code in the interface.

(9) Press “i” key on the keyboard to proceed to the edition mode.

(10) Replace the default address symbols in the program with the address symbols obtained from the modulus software, as shown in the following image:

(11) After completing the modifications, press the “Esc” key once, then type “:wq” (note the colon before wq), and press Enter to save the changes.

:wq

10.5.6 Working Principle

Source Code

In this project, we control the display module of the dot matrix module through a set of hexadecimal data. A set of data contains 16 data in total, and each data control one column of the LED screen.

The source code of program is located in: /home/pi/TonyPi/Extend/sensor_course/sensor_example/lattice_display.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/python3
# coding=utf8
# 4.拓展课程学习\7.拓展课程之传感器基础开发课程\第5课 点阵模块实验(4.Advanced Lessons\7.Sensor Development Course\Lesson5 Dot Matrix Module)
import time
from hiwonder import dot_matrix_sensor

dms = dot_matrix_sensor.TM1640(dio=7, clk=8)
if __name__ == "__main__":

    while True:
        try:
            dms.display_buf=(0x7f, 0x08, 0x7f, 0x00, 0x7c, 0x54, 0x5c, 0x00,
                              0x7c, 0x40, 0x00,0x7c, 0x40, 0x38, 0x44, 0x38)
            dms.update_display()
            time.sleep(5)
        except KeyboardInterrupt:
            dms.display_buf = [0]*16
            dms.update_display()
            break
  • Display Control and Configuration

dms = dot_matrix_sensor.TM1640(dio=7, clk=8): Creates an instance of the dot matrix sensor object named dms, with the data pin (dio) assigned to GPIO 7 and the clock pin (clk) to GPIO 8.

7
dms = dot_matrix_sensor.TM1640(dio=7, clk=8)

dms.display_buf = (0x7f, 0x08, 0x7f, 0x00, 0x7c, 0x54, 0x5c, 0x00, 0x7c, 0x40, 0x00, 0x7c, 0x40, 0x38, 0x44, 0x38): Sets the display buffer with a sequence of hexadecimal values that correspond to a specific pattern to be shown on the dot matrix display.

12
13
            dms.display_buf=(0x7f, 0x08, 0x7f, 0x00, 0x7c, 0x54, 0x5c, 0x00,
                              0x7c, 0x40, 0x00,0x7c, 0x40, 0x38, 0x44, 0x38)

dms.update_display(): Updates the display to reflect the contents of the current display buffer.

14
            dms.update_display()

except KeyboardInterrupt: Captures a keyboard interrupt event (such as pressing Ctrl+C) to allow the program to exit cleanly.

16
17
18
19
        except KeyboardInterrupt:
            dms.display_buf = [0]*16
            dms.update_display()
            break

dms.display_buf = [0]*16: Clears the display buffer by setting all 16 positions to 0.

dms.update_display(): Refreshes the display to show the cleared (blank) screen.

10.6 Light Sensor

10.6.1 Preparation

Prepare a light sensor and connect it to any one of GPIO ports on Raspberry Pi expansion board through 4PIN cable. The wiring effect is as follow:

Note

Please do not insert forcefully because 4PIN cable uses anti-reverse plugging design.

10.6.2 Module Usage

The light sensor mainly includes a QTH23C (photodiode) and LM358chi (voltage comparator).

We can set a threshold by adjusting the potentiometer on sensor. When the external brightness is greater than the threshold, LED1 on module will light up and the signal terminal OUT will output a low level.

When the external brightness is less than the threshold, LED1 on module will light off and the signal terminal OUT will output a high level.

10.6.3 Operation Steps

(1) Click the icon on the upper left corner of the desktop to open the command line terminal.

cd /home/pi/TonyPi/Extend/sensor_course/sensor_example/

(2) Input the command below and press Enter to go to the directory of game program.

python3 photo_sensitive_control.py

(3) If want to close this program, press “Ctrl+C”. You can try multiple time if fail to close.

10.6.4 Project Outcome

After the program is started, the buzzer will sound once when the external brightness is higher than the threshold set by the light sensor.

10.6.5 Working Principle

Source Code

When the external brightness is higher than the threshold set by the module, the signal terminal OUT outputs a low level, otherwise it output a high level. We can judge the current status of the sensor according to the level change of the signal terminal OUT.

The source code of the program is located in: /home/pi/TonyPi/Extend/sensor_course/sensor_example/photo_sensitive_control.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/python3
# coding=utf8
# 4.拓展课程学习\7.拓展课程之传感器基础开发课程\第6课 光线传感器模块实验(4.Advanced Lessons\7.Sensor Development Course\Lesson6 Light Sensor Module)
import os
import sys
import time
import gpiod
import hiwonder.ros_robot_controller_sdk as rrc

if sys.version_info.major == 2:
    print('Please run this program with python3!')
    sys.exit(0)


board = rrc.Board()
    
st = 0

chip = gpiod.Chip('gpiochip4')
light = chip.get_line(24)
light.request(consumer="light", type=gpiod.LINE_REQ_DIR_IN, flags=gpiod.LINE_REQ_FLAG_BIAS_PULL_UP)

if __name__ == "__main__":
    while True:
        state = light.get_value()  #读取引脚数字值(read pin numerical value)
        print(state)
        if not state:
            if st :            #这里做一个判断,防止反复响(make a judgement to prevent repeated ringing here)
                st = 0
                board.set_buzzer(1900, 0.1, 0.9, 1) # 以1900Hz的频率,持续响0.1秒,关闭0.9秒,重复1次(at a frequency of 1900Hz, sound for 0.1 seconds, then pause for 0.9 seconds, repeat once)
                time.sleep(1)
                
        else:
            st = 1
            board.set_buzzer(1000, 0.0, 0.0, 1) # 关闭(close)
            
        board.set_buzzer(1000, 0.0, 0.0, 1) # 关闭(close)
  • Light Detection and Control Logic

① The program initializes a variable st and sets its value to 0.

17
st = 0

② It creates a GPIO object using gpiod.Chip('gpiochip4'), then obtains GPIO pin 7 with get_line(7). The pin is configured as an input using the request() method.

19
20
21
chip = gpiod.Chip('gpiochip4')
light = chip.get_line(24)
light.request(consumer="light", type=gpiod.LINE_REQ_DIR_IN, flags=gpiod.LINE_REQ_FLAG_BIAS_PULL_UP)

③ The program enters an infinite loop, continuously performing the following steps:

23
24
25
if __name__ == "__main__":
    while True:
        state = light.get_value()  #读取引脚数字值(read pin numerical value)

④ Reads the pin state using light.get_value() to retrieve the digital signal (0 or 1) from GPIO pin 7.

⑤ Checks the pin state: if the value is 0 (LOW) and the variable st is true (non-zero), it proceeds with the following actions:

27
28
29
30
31
        if not state:
            if st :            #这里做一个判断,防止反复响(make a judgement to prevent repeated ringing here)
                st = 0
                board.set_buzzer(1900, 0.1, 0.9, 1) # 以1900Hz的频率,持续响0.1秒,关闭0.9秒,重复1次(at a frequency of 1900Hz, sound for 0.1 seconds, then pause for 0.9 seconds, repeat once)
                time.sleep(1)

⑥ Sets st to 0, indicating that a trigger has already been handled.

⑦ Calls board.set_buzzer(1900, 0.1, 0.9, 1) to activate the buzzer at 1900 Hz for 0.1 seconds, pause for 0.9 seconds, and repeat once.

⑧ Introduces a 1-second delay.

⑨ If the pin state is 1 (HIGH), it performs the following actions:

33
34
35
        else:
            st = 1
            board.set_buzzer(1000, 0.0, 0.0, 1) # 关闭(close)

⑩ Sets st to 1, indicating that the pin is currently in a HIGH state.

⑪ Calls board.set_buzzer(1000, 0.0, 0.0, 1) to ensure the buzzer is turned off.

⑫ Regardless of the pin state, the program finally calls board.set_buzzer(1000, 0.0, 0.0, 1) to confirm the buzzer remains off.

37
        board.set_buzzer(1000, 0.0, 0.0, 1) # 关闭(close)