eew_Ya3s2d 发表于 2024-10-15 00:27

【得捷Follow me第二季第1期】任务汇总+舵机与AGS02MA气体传感器使用

本帖最后由 eew_Ya3s2d 于 2024-10-18 15:46 编辑

<p>Hello,大家好,我是郑工,尘世间一个迷途小工程师。</p>

<p>&nbsp;</p>

<p>这个帖子我们来汇总一下所有的任务与讲解一下</p>

<p>&nbsp;</p>

<p>0、物料清单:</p>

<p>&nbsp; &nbsp; CPX主板</p>

<p>&nbsp; &nbsp; 舵机</p>

<p>&nbsp; &nbsp; AGS02MA气体传感器</p>

<p>&nbsp;</p>

<p>首先是我自己感觉有些尴尬的视频讲解</p>

<p>eedfda84f28c67abea9939b1ddca653e<br />
这个视频拍着拍着就拍到差不多15分钟了,视频2个G,最后是压缩了之后才能上传,下次拍视频之前还是得选不要太高清才行</p>

<p>&nbsp;</p>

<p><strong><span style="font-size:16px;">入门任务(必做):开发环境搭建,板载LED点亮</span></strong></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1288839-1-1.html">【Follow me第二季第1期】任务0:开发环境搭建,板载LED点亮 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)</a></p>

<p>程序就是通过time.sleep函数产生一个pwm去点亮led,不断更改pwm的占空比,这样led看起来就led就会有亮暗变化,像呼吸灯</p>

<p>最主要的函数是下面这个,产生一个简单的pwm,控制led灯。</p>

<pre>
<code class="language-python">def onLed(onTime, duty):
    if onTime &gt; 0:
      led.value = True
      time.sleep(onTime)
    if duty - onTime &gt; 0:
      led.value = False
      time.sleep(duty - onTime)</code></pre>

<p>8c23d536df42401548b2dd2f7df07893<br />
&nbsp;</p>

<p data-spm-anchor-id="0.0.0.i35.1b546b08JWFRHr"><strong><span style="font-size:16px;">基础任务一(必做):控制板载炫彩LED,跑马灯点亮和颜色变换</span></strong></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1289057-1-1.html">【Follow me第二季第1期】任务1:控制板载炫彩LED,跑马灯点亮和颜色变换 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)</a></p>

<p>这个其实就是控制WS2812B灯珠做流水灯,总体来说就是用neopixel库来实现彩色灯的效果,封装得太好,显得没有难度,其实中间一些时序问题,当年我也是想破头</p>

<p>颜色变换写了两种不同函数去遍历。</p>

<pre>
<code class="language-python">def Wheel2(i, r_in, g_in):
    if i &lt; 0 or i &gt; 10:
      r = g = b = 0
    elif i % 3 == 0:
      r = r_in
      g = g_in
      b = 255 - r - g
    elif i % 3 == 1:
      r = g_in
      b = r_in
      g = 255 - r - b
    else:
      g = r_in
      b = g_in
      r = 255 - b - g
    return (r, g, b)


def rainbow_cycle2():
    dir = True
    for r in range(255):
      start = 0
      stop = 255 - r
      step = 1
      if not dir:
            start = 255 - r
            stop = 0
            step = -1
      for g in range(start, stop, step):
            for i in range(10):
                pixels = Wheel2(i, r, g)
            pixels.show()
            time.sleep(colorFulWaitTime / 50)
      dir = not dir


def wheel(pos):
    if pos &lt; 0 or pos &gt; 768:
      r = g = b = 0
    elif pos &lt; 256:
      r = int(pos)
      g = int(255 - pos)
      b = 0
    elif pos &lt; 512:
      pos -= 256
      r = int(255 - pos)
      g = 0
      b = int(pos)
    else:
      pos -= 512
      r = 0
      g = int(pos)
      b = int(255 - pos)
    return (r, g, b)


def rainbow_cycle():
    for j in range(767):
      for i in range(num_pixels):
            pixel_index = (i * 767 // num_pixels) + j
            pixels = wheel(pixel_index % 767)
      pixels.show()
      time.sleep(colorFulWaitTime)</code></pre>

<p>22f9bc383bf6e55af3472be4f947f179<br />
&nbsp;</p>

<p><strong><span style="font-size:16px;">基础任务二(必做):监测环境温度和光线,通过板载LED展示舒适程度</span></strong></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1289310-1-1.html">【Follow me第二季第1期】任务2:监测环境温度和光线,通过板载LED展示舒适程度 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)</a></p>

<p>这个任务就是读取AD任务,通过读取光敏AD上的值,获取照度,通过adafruit_thermistor库,可以直接获取温度值,也是站在别人的肩膀上,顿时感觉轻松好多</p>

<p>库的使用也非常简单,我写了一些注释,只要初始化设置好,后面直接得到温度,简单快捷</p>

<pre>
<code class="language-python">import adafruit_thermistor

# 模拟输入的管脚
pin = board.TEMPERATURE
# 热敏电阻的常温阻值
resistor = 10000
# 普通电阻的阻值
resistance = 10000
# 热敏电阻的阻值温度
nominal_temp = 25
# 热敏电阻的B系数
b_coefficient = 3950
# 还有最后一个参数,参数名为high_side,表示热敏电阻是否连接在上端,默认为True,可以不填

thermistor = adafruit_thermistor.Thermistor(
    pin, resistor, resistance, nominal_temp, b_coefficient)</code></pre>

<p>程序通过灯珠数量反应照度值,通过灯珠颜色反应温度。不过灯珠就在光敏三极管旁边,还是有一些影响。</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p><strong><span style="font-size:16px;">基础任务三(必做):接近检测&mdash;&mdash;设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警</span></strong></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1290147-1-1.html">【Follow me第二季第1期】任务3:接近检测 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)</a></p>

<p>这是我耗时最久的一个任务,用红外收发实在是完成不了,最后是用了超声波距离模块实现程序功能,超声波模块只需要测量反馈的脉冲长度就可以知道物体的距离的,测试距离使用time.monotonic_ns()函数计算时间戳的差值(单位ns)即可,如下面代码</p>

<pre>
<code class="language-python">    # 发送出发信号,时间是500us,只要比需求长就可以了
    ir_tx.value = True
    time.sleep(0.0005)
    ir_tx.value = False
    rx_count = 0
    # 等待回复的高电平
    while ir_rx.value is False:
      time.sleep(0.0001)
      rx_count = rx_count + 1
      if rx_count &gt; 10000:# 发送高电平之后等待时间太长,认为是发送失败
            break
    start_time = time.monotonic_ns()    #获取高电平开始的时间戳,单位是ns
    while ir_rx.value is True:
      pass
    end_time = time.monotonic_ns()    #获取高电平结束的时间戳,单位是ns
    duration = round((end_time - start_time)/1000000, 2)
    if duration &lt; 0.05:# 时间太短
      continue
    print(f'duration time:{duration} ms')
    distance = round(duration*17.0, 1)       # 时间*340m/s(34cm/ms)/2
    print(f'distance:{distance} cm')</code></pre>

<p>98bcbcd1ec2107ae87dc9cffc0d17e29<br />
&nbsp;</p>

<p><strong><span style="font-size:16px;">进阶任务(必做):制作不倒翁&mdash;&mdash;展示不倒翁运动过程中的不同灯光效果</span></strong></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1295977-1-1.html">【Follow me第二季第1期】任务4:制作不倒翁&mdash;&mdash;展示不倒翁运动过程中的不同灯光效果 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)</a></p>

<p>这是一个整活的任务,其实我很多精力都用在搞那个不倒翁底座那里去了T_T</p>

<p>加速度传感器使用也非常简单,只需要调用库即可,如下</p>

<pre>
<code>import board
import busio
import adafruit_lis3dh

i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19)

# Set range of accelerometer (can be RANGE_2_G, RANGE_4_G, RANGE_8_G or RANGE_16_G).
lis3dh.range = adafruit_lis3dh.RANGE_2_G

ax, ay, az = [
      value / adafruit_lis3dh.STANDARD_GRAVITY for value in lis3dh.acceleration
    ]</code></pre>

<p>047a18051831057b8517ff7198dcf743<br />
&nbsp;</p>

<p>最后补充一下我另外买的两个零件,一个是舵机,一个是AGS02MA气体传感器</p>

<p>&nbsp;</p>

<p><strong><span style="font-size:18px;">舵机</span></strong></p>

<p>舵机主要就是通过pwm占空比来控制舵机的动作,从规格书我们可以看到具体的控制方式</p>

<p> &nbsp;</p>

<p>从上面可以看到,停止脉冲是1500us,顺时针方向是700-1500us,逆时针方向是1500-2300us</p>

<p>&nbsp;</p>

<p>所以只要用pwmio库产生一个pwm就可以控制舵机</p>

<pre>
<code class="language-python"># create a PWMOut object on Pin A1.
pwm = pwmio.PWMOut(board.A1, frequency=50, duty_cycle=7536)
# 2294      0.7ms min
# 4915      1.5ms stop
# 7536      2.3ms max</code></pre>

<p>我这里产生的是一个50hz的pwm波</p>

<p>&nbsp;</p>

<p><strong><span style="font-size:18px;">AGS02MA气体传感器</span></strong></p>

<p>这个要调试其实也有些麻烦,不过其实用法也简单,就那么两三个指令需要调试,不过直到我找到下面这个网站,所有困难都烟消云散了,还是得再次感叹一下python社区的人多力量大,我们都是站在巨人的肩膀上</p>

<p><a href="https://pypi.com.cn/project/adafruit-circuitpython-ags02ma/">adafruit-circuitpython-ags02ma - 用于 AGS02MA 气体传感器的 CircuitPython / Python 库_PyPI中文网</a></p>

<p> &nbsp;</p>

<p>直接安装就可以了。然后找到文件</p>

<p> &nbsp;</p>

<p>放到板子里面就可以使用了,文件里也说了使用方法</p>

<p> &nbsp;</p>

<p>代码如下:</p>

<pre>
<code>import board
import busio
import time
from adafruit_ags02ma import AGS02MA

# Initialize I2C bus.
i2c = busio.I2C(board.SCL, board.SDA, frequency = 20000)
ags = AGS02MA(i2c, address=0x1A)



while True:
    res = ags.gas_resistance
    tvoc = ags.TVOC
    print(f'tvoc:{tvoc},res:{res}')
    time.sleep(2)</code></pre>

<p>可惜的是,CPX线路板的硬件I2C并不支持20k的通讯速率,而AGS02MA的最大通讯速率是30k。最后我是使用ESP-S3 feather这个板子来完成,同样是follow me活动的板子,同样是使用circuit python代码完成的</p>

<p> &nbsp;</p>

<p> &nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p><strong><span style="font-size:18px;">感想</span></strong></p>

<p>最后的最后,还是得感谢举办方,感谢得捷电子,感谢EE。在不断摸索的过程中,感受到前人智慧的浩渺,我只是后来者,模仿者,轻松拿来使用的人。并没有什么值得骄傲的。科学进步才是社会发展的动力,我仍然需要虚心学习更多的知识,创造更美好的生活。</p>

<p>&nbsp;</p>

<p>下面是课程链接:</p>

<p><a href="https://training.eeworld.com.cn/course/68709">【得捷Follow me第二季第1期】任务汇总+舵机与AGS02MA气体传感器使用-EEWORLD大学堂</a></p>

<p>源码:</p>

<p><a href="https://download.eeworld.com.cn/detail/eew_Ya3s2d/634582">Follow me第二季第一期 所有代码 + 库-嵌入式开发相关资料下载-EEWORLD下载中心</a></p>

<p>&nbsp;</p>
页: [1]
查看完整版本: 【得捷Follow me第二季第1期】任务汇总+舵机与AGS02MA气体传感器使用