373 views|0 replies

141

Posts

4

Resources
The OP
 

【Digi-Jet Follow me Phase 3】Project Summary Report [Copy link]

 This post was last edited by Tristan_C on 2023-12-11 23:58

DigiKey Follow Me 3rd Project Summary Report



Task 1: Using the MicroPython system

The Seeed Studio XIAO ESP32C3 board requires the use of MicroPython for development, so Task 1 naturally requires the construction of a MicroPython system. The Thonny development tool is used here, which can be downloaded from the following path: https://thonny.org/ . Since it has been installed before in the development of other projects (such as RP2040), and the installation is simple, I will not repeat it here. After installation, open the software interface as shown below.
Next, let the Seeed Studio XIAO ESP32C3 board enter the burning state. There are two ways to enter:
  1. Press and hold the BOOT button on the board, then connect it to the PC via USB, then release the button
  2. First connect the board to the PC via a USB cable, then press and hold the BOOT button, then press and release the RESET button, then release the BOOT button
Here we use method 2, which is more convenient to operate. The buttons on the board are defined as shown below.
At this point, you can see in the lower right corner of Thonny that the board has been recognized. If it is not recognized correctly, you need to check whether the operation process and wiring are correct.
The device can also be found in the device manager
At this time, in the above discovered device list, click the configuration interpreter at the bottom.
You need to select the correct interpreter and port
Click the "Install or Update MicroPython (esptool)" button in the lower right corner and select the correct configuration item in the pop-up window. Click "Install" to start the installation
It should be noted that when installing the MicroPython system for the first time, it is best to check Erase all flash before installi in the above figure.
After the installation is complete, the prompt is as follows.
It can also be seen here that the Thonny environment is actually installed using the esptool recommended by Seeed's wiki. The official tutorial is as follows: https://wiki.seeedstudio.com/XIAO_ESP32C3_MicroPython/
Now reconnect the board to the PC and you can identify it on the Thoony development tool as follows. You can see the MicroPython version number and hardware information displayed. On the left, you can see the connected MicroPython device and the boot.py file on the device.
At this time, edit and input in the shell: print("Hello Digi-key"), and you can see the printed Hello Digi-key
This indicates that the MicroPython system is correctly burned onto the board.
Double-click the boot.py file on the left and edit print("Hello Digi-key")
Save and click the "Run current script" button in the figure below
You can see the printed content in the shell.
Using the Thonny development tool is indeed much more convenient than the step-by-step operation of esptool.

Task 2: Driving the OLED screen on the expansion board

This task requires the use of the extended version, and the specific docking method is as follows.
The task is to display text and graphics on the OLED of the expansion board. The OLED on the expansion board uses the SSD1306 driver chip. Therefore, you need to install the corresponding package first.
First, under the Tools menu bar, click the Manage Packages button
Type SSD1306 in the search bar and click the back button to search.
Click ssd1306 in the search results and click the install button below to install this package
Installation process
After successful installation, you can see the detailed installation information.
At this point in the MicriPython device on the left, you can see the ssd1306 package in lib.
Next, check the hardware. The OLED on the expansion board uses the I2C driver, and uses GPIO7 and GPIO6 as the SCL and SDA pins respectively as shown in the figure below.
Now you can start programming.
First, import the I2C and ssd1306 packages
Then specify the I2C pin. Then specify the width and length of the loed to display the text content.
Debug and run the current script program. The text displayed on the expansion board is as follows
Next, we can display several graphics on the OLED, including rectangles, circles and triangles. The circle has a separate function. Just input the position and radius.
The display effect is as follows
The complete code is as follows

import time
from machine import Pin, SoftI2C
import ssd1306
import math
from utime import sleep_ms
import framebuf

i2c = SoftI2C(scl=Pin(7), sda=Pin(6))  
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)

# 清空屏幕
oled.fill(0)
oled.show()

# 画一个简单的圆形
def draw_circle(x0, y0, r, color):
    x = r
    y = 0
    err = 0

    while x >= y:
        oled.pixel(x0 + x, y0 + y, color)
        oled.pixel(x0 + y, y0 + x, color)
        oled.pixel(x0 - y, y0 + x, color)
        oled.pixel(x0 - x, y0 + y, color)
        oled.pixel(x0 - x, y0 - y, color)
        oled.pixel(x0 - y, y0 - x, color)
        oled.pixel(x0 + y, y0 - x, color)
        oled.pixel(x0 + x, y0 - y, color)

        if err <= 0:
            y += 1
            err += 2*y + 1
        if err > 0:
            x -= 1
            err -= 2*x + 1

# 显示图形并切换
while True:
    # 显示矩形
    oled.rect(10, 10, 50, 30, 1)
    oled.show()
    sleep_ms(2000)

    # 清空屏幕
    oled.fill(0)
    oled.show()
    sleep_ms(200)

    # 显示圆形
    draw_circle(80, 40, 15, 1)
    oled.show()
    sleep_ms(2000)

    # 清空屏幕
    oled.fill(0)
    oled.show()
    sleep_ms(200)

    # 显示三角形
    oled.line(100, 10, 80, 40, 1)
    oled.line(80, 40, 120, 40, 1)
    oled.line(120, 40, 100, 10, 1)
    oled.show()
    sleep_ms(2000)

    # 清空屏幕
    oled.fill(0)
    oled.show()
    sleep_ms(200)

Task 3: Control the buzzer to play music

This task requires the use of the buzzer on the expansion board to achieve the effect of playing music. To play music, you usually need to use an external PWM module. MicroPython's audio processing capabilities on small embedded devices are relatively weak, so it usually only supports simple audio playback. The PWM pin used is A3 in the figure below.
That is the GPIO5 pin. When initializing, you need to specify the pin used by PWM.
Different notes are realized by controlling the frequency of PWM, and rhythm is controlled by delaying the notes. The following code implements a simplified version of the Happy Birthday song. The code first initializes the buzzer pin according to the aforementioned hardware. Then the frequency of each note is defined and placed in notes. Then the function of playing music is defined, in which the music output is realized according to the notes and the corresponding sleep delay. Then the notes and rhythm delay in the specific song are defined, so that the bronze drum can finally look up the notes table to play the music.
Here is a simple sheet of the Happy Birthday song, try to adjust it to play the buzzer
First define the frequency of each note
Then define the song content based on the musical notation and rhythm
According to the content, it is then output to the buzzer's PWM control note and delay control rhythm
Of course, we also add a little bit of display on the OLED in the previous task to show the playback content
Overall code
import machine
import time
from utime import sleep
from machine import Pin, SoftI2C
import ssd1306

i2c = SoftI2C(scl=Pin(7), sda=Pin(6))  
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)

# 清空屏幕
oled.fill(0)
oled.show()

oled.text("Play song", 10, 15)
oled.text("Happy birthday", 10, 40)
oled.show()  # 显示内容

# Buzzer settings
buzzer_pin = machine.Pin(5, machine.Pin.OUT)

# 定义音符和对应频率
notes = {'1': 523, '2': 587, '3': 659, '4': 698, '5': 784, '6': 880, '7': 988}

# 播放音乐的函数
def play_music(melody):
    for note, duration in melody:
        if note == 'R':  # R 表示休止符(rest)
            sleep(duration)
        else:
            buzzer_pwm.freq(notes[note])
            buzzer_pwm.duty(512)
            sleep(duration)
            buzzer_pwm.duty(0)
            sleep(0.1)  # 短暂的停顿

# 初始化PWM
buzzer_pwm = machine.PWM(buzzer_pin, freq=440, duty=0)  # 初始频率为440 Hz,初始占空比为0

# 播放"生日快乐"歌曲
happy_birthday_melody = [
    ('5', 0.5), ('5', 0.5), ('6', 1), ('5', 1), ('1', 1), ('7', 2), ('R', 0.5),
    ('5', 0.5), ('5', 0.5), ('6', 1), ('5', 1), ('2', 1), ('1', 2), ('R', 0.5),
    ('5', 0.5), ('5', 0.5), ('5', 1), ('3', 1), ('1', 1), ('7', 2), ('R', 0.5),
    ('4', 0.5), ('4', 0.5), ('3', 1), ('1', 1), ('2', 1), ('1', 2), ('R', 0.5),
]

play_music(happy_birthday_melody)

# 关闭PWM
buzzer_pwm.deinit()


See video introduction for playback effect

Task 4: Connect to WiFi network

This task makes use of the powerful network function of ESP32. In order to test WiFi, you need to install a signal-related antenna and connect it to the IPEX socket on the module.
With the current powerful ecosystem of ESP32, it is really easy. The official also provides a reference for connecting to a specified AP, as follows:
The wifi_ssid and wifi_password need to be changed to the corresponding WiFi name and password. After running, it will start scanning the WiFi network.
After the scan is completed, it starts to connect to the network where the wifi_ssid defined previously is located, and outputs the following prompt.
The corresponding device can also be seen on the router
Next, we use the NTP service to update the local time to test network connectivity
The code uses ntptime.settime() to synchronize the local time from the server, then obtains the local timestamp every second, converts it, and prints the current date and time on the serial port and OLED.
This also adds the OLED function in the previous task, showing the task content at the start stage and showing the current date and time in the timestamp update
After execution, the time update can be detected in the print serial port
On the OLED, you can see the startup task content prompt
And after the time synchronization is successful, the local time is updated
The complete function code is as follows, where wifi_ssid and wifi_password need to be replaced with your own corresponding values

Task 5: Using External Sensors

This task requires the use of external sensors. Two sensors are used this time, namely the AHT20 temperature and humidity sensor and the light sensor.
One is the I2C interface and the other is the ADC interface, so you need to use a cable to connect them to the expansion board.
First, the temperature and humidity sensor is connected to the I2C interface
Then it's lighting, connected to the simulation button
Next, we will prepare to operate the external temperature and humidity sensor AHT20. To use this sensor, you must add a support package for this device. This time I changed to another installation method: download it to the local computer and then install it.
First, go to the following link: https://pypi.org/search/?q=aht20 , search for MicroPython support packages that can be used by aht20, and download them
Then open the package manager
Select Install from Local
Select the package file of the specified format downloaded earlier
After opening, it shows that it is installing
After the installation is complete, you can see the ahtx0 package in the lib folder on the left.
Then you can use import to import the package in the program
Using AHT20
After that, you can use the following operations to obtain temperature and humidity values
Of course, the I2C part needs to be defined in advance, just like the previous OLED
Next, prepare the light sensor. This Grove - Light Sensor v1.2 is a photosensor that is often used to measure ambient light intensity. It can be used by connecting to the Grove baseboard or directly to the corresponding pins on the development board. The sensor above actually uses GL5528, a photoresistor (light-dependent resistor) to detect the intensity of light. The resistance of the photoresistor decreases as the light intensity increases. The onboard dual OpAmp chip LM358 generates a voltage corresponding to the light intensity (ie. based on the resistance value). The output signal is an analog value. The brighter the light, the larger the value. However, this value only reflects the approximate trend of the light intensity. It does not indicate the exact brightness. According to the manual, the maximum value of the photoresistor can be detected at about 350Lux.
This way you can use ADC sampling.
First, set the ADC pin and sampling parameters
Then get the ADC value and convert it into resistance value and light intensity
Finally, we have to add the OLED part and update the content on it.
With the above basic operation methods, we can now integrate them, that is, sample the temperature and humidity, as well as the photoresistor and calculate the illumination every second, and then update the display on the oled
The operation effect is as follows
You will also see the corresponding content printed in the shell output
The complete code is as follows
from machine import Pin, SoftI2C, ADC
import ssd1306
import utime
import time
from ahtx0 import AHT20

i2c = SoftI2C(scl=Pin(7), sda=Pin(6))

oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)

# 清空屏幕,并显示任务要求
oled.fill(0)
oled.text("Task 5:Sensor", 0, 0)
oled.text("Temp:", 0, 16)
oled.text("Humi:", 0, 32)
oled.text("Light:", 0, 48)
oled.show()

# aht20
aht = AHT20(i2c)

# 光照部分
adc = ADC(Pin(2))
adc.atten(ADC.ATTN_11DB)
adc.width(ADC.WIDTH_12BIT)  #4095

while True:
    temp = aht.temperature
    humi = aht.relative_humidity
    
    light_adc = adc.read()
    
    # 计算光照强度单位Lux
    light_lux = light_adc * 350 * 1.0 / 4095
    
    # 算出电阻值单位K
    light_res = (4095 - light_adc) * 10.0 / light_adc
    
    print("Temp(°):\n");
    print('{:.2f}'.format(temp))
    print("Humi(%):\n");
    print('{:.2f}'.format(humi))
    print("Light(lux)\n");
    print('{:.2f}'.format(light_lux))
    print("Light(K)\n");
    print('{:.2f}'.format(light_res))
    
    # 清除变化部分的内容
    oled.fill_rect(64,16,64,48,0) 
    oled.text('{:.2f}'.format(temp), 64, 16)
    oled.text('{:.2f}'.format(humi), 64, 32)
    oled.text('{:.2f}'.format(light_lux), 64, 48)
    oled.show()
    
    # 延时1秒
    time.sleep(1)


Task 6: Comprehensive Practice (Sub-task 3: Light Reminder)

This task requires the user to monitor the ambient light intensity. If the light is too dark, the user is reminded to turn on the light through the screen and buzzer to protect eyesight. After we have completed the previous tasks, it is relatively easy to complete this task.
That is to say, based on Task 5, remove the temperature and humidity part and add the buzzer part.
First, add a buzzer
Then add the illumination value judgment obtained by the photosensitivity below. When it is less than a certain value, the buzzer sounds and the prompt of Turn Light On is displayed on the OLED screen. If the illumination is greater than this value, the buzzer turns off and the OLED does not prompt the content.
The operation effect is as follows
When the illumination is greater than a certain value
When the illumination is less than this value
The complete code is as follows
from machine import Pin, SoftI2C, ADC, PWM
import ssd1306
import utime
import time

# Buzzer settings
buzzer_pin = Pin(5, Pin.OUT)
buzzer_pwm = PWM(buzzer_pin, freq=440, duty=0)  # 初始频率为440 Hz,初始占空比为0

i2c = SoftI2C(scl=Pin(7), sda=Pin(6))

oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)

# 清空屏幕,并显示任务要求
oled.fill(0)
oled.text("Task 6-3", 0, 0)
oled.text("Light:", 0, 16)
oled.show()

# 光照部分
adc = ADC(Pin(2))
adc.atten(ADC.ATTN_11DB)
adc.width(ADC.WIDTH_12BIT)  #4095

while True:

    
    light_adc = adc.read()
    
    # 计算光照强度单位Lux
    light_lux = light_adc * 350 * 1.0 / 4095
    
    # 算出电阻值单位K
    light_res = (4095 - light_adc) * 10.0 / light_adc
    
    print("Light(lux):");
    print('{:.2f}'.format(light_lux))
    print("Light(K):");
    print('{:.2f}'.format(light_res))
    
    # 清除变化部分的内容
    oled.fill_rect(64,16,64,48,0) 
    oled.fill_rect(0,48,128,16,0)
    
    oled.text('{:.2f}'.format(light_lux), 64, 16)
    
    if light_lux < 66:
        print("We need to turn the light on\n");
        oled.text("Turn Light On", 0, 48)
        buzzer_pwm.duty(512)
    else:
        buzzer_pwm.duty(0)
        
    # 在此处更新显示
    oled.show()
    
    # 延时1秒
    time.sleep(1)


See the video introduction for the effect.

Summary and experience

In fact, I am honored to participate in this issue of Follow Me event. During the event, there were not only live technical explanations, but also enthusiastic help from all the big guys. I felt the atmosphere of technical exchange and learned a lot from it. Thank you Dejie and thank you EEWorld.
This post is from DigiKey Technology Zone
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list