422|0

33

帖子

3

TA的资源

一粒金砂(中级)

楼主
 

【得捷Follow me第3期】+ 寻找WiFi发射源的位置(任务综合帖) [复制链接]

 

 

在此非常感谢EEworld和DigiKey举办的Follow me系列第3期活动,给我们学习机会。谢谢

【第一部分】3—5分钟短视频

  

 

【第二部分】任务/项目总结报告

任务1:使用MicroPython系统【对该任务的介绍、功能对应的主要代码片段及说明、功能展示及说明、心得体会建议】

   此任务主要点是搭建Python开发环境,烧录Python固件并使用。

   1.1 搭建Python环境

     

       首先下载Thonny 工具安装,安装完成后建议使用English版本,若不使用English版本后面会对包管理造成影响,导致搜索不出来。

 

 

 

 

    1.2 下载最新的python固件

https://micropython.org/download/esp32c3/

 

     1.3 通过Thony下载python固件至ESP32C3中

     1.4 参考python手册使用实时时钟RTC

from machine import RTC

 

rtc = RTC()

rtc.datetime((2023,12, 12, 1, 12, 48, 0, 0)) # set a specific date and time

 

print(rtc.datetime() )# get date and time

 

 

任务2:驱动扩展板上的OLED屏幕【对该任务的介绍、功能对应的主要代码片段及说明、功能展示及说明、心得体会建议】

这里需提前在Thonny下载好ssd1306的库。

note:在安装的时候需选择English版本,否则无法更新。

 

 

 

 

 

 

  • import time
  • from machine import Pin, SoftI2C
  • import ssd1306
  • import math
  • # ESP8266 Pin assignment
  • i2c = SoftI2C(scl=Pin(7), sda=Pin(6))  # Adjust the Pin numbers based on your connections
  • oled_width = 128
  • oled_height = 64
  • oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
  • oled.fill(0# Clear the screen
  • oled.text("I Love EEWORLD!", 10, 15)
  • oled.text("/////", 30, 40)
  • oled.text("(`3`)y", 30, 55)
  • oled.show()  # Show the text

 

 

任务3:控制蜂鸣器播放音乐【对该任务的介绍、功能对应的主要代码片段及说明、功能展示及说明、心得体会建议】

3.1 蜂鸣器原理介绍

   通过扩展板资料查找,确认蜂鸣器buzzer的引脚是A3,结合XIAO C3的引脚图得知使用的引脚是GPIO5。

3.2 任务开发

    由以上蜂鸣器的驱动原理,可以确定蜂鸣器播放音乐步骤:

  3.2.1 确认引脚

    这里引入用户Button,当用户button按下后,蜂鸣器响起,我们先尝试将蜂鸣器驱动起来。

   

 

  3.2.2 将引脚设置为PWM输出

  • buzzer = machine.PWM(buzzer_pin)
  • buzzer.freq(1047)

  3.3.3 设定音乐频谱

我们主要是通过控制PWM频率来发出不同的声调,例如

 

  3.3.4 循环执行音乐频谱

 

 

任务4:连接WiFi网络【对该任务的介绍、功能对应的主要代码片段及说明、功能展示及说明、心得体会建议】

4.1  ESP32C3 联网库分析

  • import network
  • wlan = network.WLAN(network.STA_IF) # create station interface
  • wlan.active(True)       # activate the interface
  • wlan.scan()             # scan for access points
  • wlan.isconnected()      # check if the station is connected to an AP
  • wlan.connect('ssid', 'key') # connect to an AP
  • wlan.config('mac')      # get the interface's MAC address
  • wlan.ifconfig()         # get the interface's IP/netmask/gw/DNS addresses
  • ap = network.WLAN(network.AP_IF) # create access-point interface
  • ap.config(ssid='ESP-AP') # set the SSID of the access point
  • ap.config(max_clients=10) # set how many clients can connect to the network
  • ap.active(True)         # activate the interface

4.2 实现

连接到本地WIFI网络的一个有用的功能是:

  • def do_connect():
  •     import network
  •     wlan = network.WLAN(network.STA_IF)
  •     wlan.active(True)
  •     if not wlan.isconnected():
  •         print('connecting to network...')
  •         wlan.connect('ssid', 'key')
  •         while not wlan.isconnected():
  •             pass
  •     print('network config:', wlan.ifconfig())

一旦网络建立起来,该socket模块就可以像往常一样创建和使用 TCP/UDP 套接字,并且该requests模块可以用于方便的 HTTP 请求。

 

调用 后,默认情况下,设备将永远wlan.connect()重试连接 ,即使身份验证失败或范围内没有 AP。 将返回此状态,直到连接成功或接口被禁用。这可以通过调用 来更改,其中 n 是所需的重新连接尝试次数(0 表示不会重试,-1 将恢复尝试永久重新连接的默认行为)。wlan.status()network.STAT_CONNECTINGwlan.config(reconnects=n)

 

 

 

任务5:使用外部传感器【对该任务的介绍、功能对应的主要代码片段及说明、功能展示及说明、心得体会建议】

5.1 ATH20温湿度传感器说明

 

 

 

5.2 光照传感器说明

光照传感器主要通过不同光照照射

 

 

 

5.3 功能实现

  光照传感器主要通过ADC采样,通过python源码发现有类似的例子,通过Thonny修改下载后可读取ADC值。

 

 

 

AHT20 温湿度读取接口已在ahtx0.py有定义,可直接引用。

 

整体代码如下:

  • from machine import Pin, SoftI2C, ADC
  • import ssd1306
  • import utime
  • import time
  • from ahtx0 import AHT20
  • #设置I2C引脚
  • i2c = SoftI2C(scl=Pin(7), sda=Pin(6))
  • #设置SS1306对象
  • oled = ssd1306.SSD1306_I2C(128, 64, i2c)
  • # 清空屏幕,并显示温湿度和光照强度
  • oled.fill(0)
  • oled.text("##EEWORLD Task##", 0, 0)
  • oled.text("Temp:", 0, 16)
  • oled.text("Humi:", 0, 32)
  • oled.text("Light:", 0, 48)
  • oled.show()
  • # 温湿度对象申明
  • aht = AHT20(i2c)
  • # ADC读取光照强度
  • adc = ADC(Pin(2))
  • adc.atten(ADC.ATTN_11DB)
  • adc.width(ADC.WIDTH_12BIT)
  • 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)

任务6:寻找WiFi发射源的位置

     本期主线任务选择”寻找WIFI发射源位置“。

6.1 原理说明

     WIFI信号的强弱主要由RSSI值体现,

   RSSI的单位是DBm,dbm是一个表示功率绝对值的单位,他的计算公式为10lg(功率值/1mw)。例如如果接收到的功率为1mw,按照dbm单位进行折算后的值应该为10lg 1mw/1mw=0dbm。当然在实际传输过程中接收方是很难达到接收功率1mw的。因为还有接收端的天线增益,所以即使接收功率是0.00001mw(即-50db)时,RF射频的接收端也能很好地进行码元解码。

     

为什么测量出来的dbm值都是负数?

答:首先我们需要知道的是无线信号dbm都是负数,最大是0。因此测量出来的dbm值肯定都是负数。因为dbm值只在一种情况下为0,那就是在理想状态下经过实验测量的结果,一般我们认为dbm为0是其最大值,意味着接收方把发射方发射的所有无线信号都接收到了,即无线路由器发射多少功率,接收的无线网卡就获得多少功率。当然这是在理想状态下测量的,在实际中即使将无线网卡挨着无线路由器的发射天线也不会达到dbm为0的效果。所以说测量出来的dbm值都是负数,不要盲目的认为负数就是信号不好。

既然我们已经知道dbm是负数,那可以确定值越大,信号越好,越说明无线路由器发射的功率都被无线网卡接收到了。因此dbm值应该越大越好,-50dbm说明接收到的无线信号要好于-70dbm。

 

 

6.2 接口分析

   而要想识别RSSI的强弱,涉及很多信号原理相关知识,但是在ESP32C3的代码库中已经有现成的函数可以直接返回WIFI信号强度,通过对network.pyi分析,我们可以知道status接口会返回WIFI信号强度。

 

 

通过以上预备知识的梳理,我们现在正式开始项目。

 

6.3 代码实现

  6.3.1 需求

       1、连接路由器

       2、OLED需实时显示RSSI值

       3、当RSSI处于-80至-60时显示信号LOW,[-60,-40)显示Middle,【-40,-20)显示High,大于-20显示Excellent。

       4、信号越好蜂鸣器需鸣叫的越快,以便定位位置。

       5、显示温湿度

       6、获取网络最新时间并显示

 

6.3.2 实现  

  • import network
  • import time
  • from time import sleep
  • import machine,ntptime
  • from machine import Pin, SoftI2C,ADC
  • import ssd1306
  • import math
  • from ahtx0 import AHT20
  • #设置I2C引脚
  • i2c = SoftI2C(scl=Pin(7), sda=Pin(6))
  • # 温湿度对象申明
  • aht = AHT20(i2c)
  • # ADC读取光照强度
  • adc = ADC(Pin(2))
  • adc.atten(ADC.ATTN_11DB)
  • adc.width(ADC.WIDTH_12BIT)
  • # ESP32C3 Pin assignment
  • i2c = SoftI2C(scl=Pin(7), sda=Pin(6)) # Adjust the Pin numbers based on your connections
  • oled_width = 128
  • oled_height = 64
  • oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
  • # Network settings
  • wifi_ssid = "H3C_44671C"
  • wifi_password = "wjly032623"
  • oled.text("Starting up...", 0, 0)
  • oled.show()
  • station = network.WLAN(network.STA_IF)
  • station.active(True)
  • station.connect(wifi_ssid, wifi_password)
  • time.sleep(1)
  • while not station.isconnected():
  • time.sleep(1)
  • oled.fill(0)
  • oled.text("Connecting to", 0, 0)
  • oled.text(wifi_ssid, 0, 20)
  • oled.show()
  • time.sleep(2)
  • oled.fill(0)
  • ip_address = station.ifconfig()[0] # Get the IP address
  • oled.text("Connected! ", 0, 0)
  • oled.text("IP Address:", 0, 20)
  • oled.text(ip_address, 0, 40)
  • oled.show()
  • time.sleep(2)
  • # Buzzer settings
  • buzzer_pin = machine.Pin(5, machine.Pin.OUT)
  • buzzer = machine.PWM(buzzer_pin)
  • buzzer.freq(1047)
  • buzzer.duty(0)
  • center_x = oled_width // 2
  • center_y = oled_height // 2
  • square_size = 6 # Size of each square
  • num_squares = 12 # Number of squares
  • angle_increment = 2 * math.pi / num_squares
  • x_pos = [12, 38, 64, 90]
  • statuses = ["L", "M", "H", "Nice"]
  • def calculate_block_count(rssi):
  • # Determine the number of blocks based on RSSI values
  • if -80 <= rssi < -60:
  • return 1
  • elif -60 <= rssi < -40:
  • return 2
  • elif -40 <= rssi < -20:
  • return 3
  • elif -20 <= rssi <= 10:
  • return 4
  • def sync_ntp():
  • """通过网络校准时间"""
  • while True: #时间校准
  • try:
  • ntptime.settime()
  • break;
  • except:
  • print('time no')
  • time.sleep(1)
  • def ShowTime():
  • NetWortime=time.localtime()
  • NetWortime='%d-%d-%d %d:%d'%(NetWortime[0],NetWortime[1],NetWortime[2]+1,NetWortime[3]-16,NetWortime[4])
  • oled.text(NetWortime,0,48)
  • def Get_Sensor_Value():
  • temp = aht.temperature
  • humi = aht.relative_humidity
  • light_adc = adc.read()
  • # 计算光照强度单位Lux
  • light_lux = light_adc * 350 * 1.0 / 4095
  • oled.text("T:", 0, 24)
  • oled.text("H:", 64, 24)
  • oled.text("L:", 0, 36)
  • oled.text('{:.2f}'.format(temp), 16, 24)
  • oled.text('{:.2f}'.format(humi), 80, 24)
  • oled.text('{:.2f}'.format(light_lux), 16, 36)
  • oled.show()
  • while True:
  • sync_ntp();
  • NetWortime=time.localtime()
  • print(type(NetWortime),NetWortime)
  • NetWortime='%d-%d-%d %d:%d:%d'%(NetWortime[0],NetWortime[1],NetWortime[2],NetWortime[3]+8,NetWortime[4],NetWortime[5])
  • print(NetWortime)
  • oled.fill(0)
  • station = network.WLAN(network.STA_IF)
  • time.sleep(0.1)
  • oled.text("##EEWORLD Task##", 0, 0)
  • rssi = station.status('rssi')
  • rssi_duty = 160 + 2 * int(rssi)
  • rssi_duty_2 = int(rssi_duty / 2)
  • rssi_abs = abs(int(rssi)) / 100
  • block_count = calculate_block_count(rssi)
  • status = statuses[block_count - 1] # Get the status text based on block count
  • oled.text("RSSI:", 0, 12)
  • oled.text(str(rssi), 40, 12)
  • oled.text("SQ:",72,12)
  • oled.text(status, 96, 12)
  • Get_Sensor_Value()
  • ShowTime()
  • oled.text(ip_address, 0, 56)
  • # Update the display
  • oled.show()
  • buzzer.duty(rssi_duty)
  • time.sleep(rssi_abs)
  • buzzer.duty(0)
  • time.sleep(rssi_abs)
  • buzzer.duty(rssi_duty_2)
  • time.sleep(rssi_abs)
  • buzzer.duty(0)
  • time.sleep(rssi_abs)

 

 

【第三部分】 源码

https://download.eeworld.com.cn/detail/jone5/630296

 

 

【第四部分】心得体会

  我是第一次使用python对ESP32进行开发,因此此次任务对我来说还是具有很强的学习意义的,非常感谢EEWORLD联合得捷的此次任务,给了我们很多学习的机会。因为第一次接触用python去开发Esp32,由于工作繁忙,很多接口还不会使用,我会继续阅读学习Esp32 miceopython源码,以熟悉此中开发方式原理并进行分享。

  最后再次感谢EEWorld提供此学习机会及分享的平台。非常感谢

 

 

【第五部分】参考资料

ESP32C3资料链接: https://wiki.seeedstudio.com/XIAO_ESP32C3_Getting_Started/

扩展板资料: https://wiki.seeedstudio.com/Seeeduino-XIAO-Expansion-Board/

Micropython资料链接; https://wiki.seeedstudio.com/XIAO_ESP32C3_MicroPython/

Micropython 参考手册: https://docs.micropython.org/en/latest/esp32/quickref.html

光照传感器手册:https://mm.digikey.com/Volume0/opasdata/d220001/medias/docus/2283/101020132_Web.pdf

温湿度传感器手册:https://mm.digikey.com/Volume0/opasdata/d220001/medias/docus/448/101990644_Web.pdf

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
有奖直播报名| TI 面向楼宇和工厂自动化行业的毫米波雷达解决方案
【内容简介】TI 60GHz IWRL6432和 IWRL1432毫米波雷达传感器如何帮助解决楼宇和工厂自动化应用中的感应难题
【直播时间】5月28日(周三)上午10:00
【直播礼品】小米双肩包、contigo水杯、胶囊伞、安克充电器

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 9

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表