查看: 239|回复: 1

[教程] T-Watch手表初试micropython之电子秤教程

[复制链接]
  • TA的每日心情
    开心
    2019-7-17 13:13
  • 签到天数: 264 天

    [LV.8]以坛为家I

    发表于 2019-7-14 22:39 | 显示全部楼层 |阅读模式
    本帖最后由 沧海笑1122 于 2019-7-14 22:52 编辑

    【项目的故事】
    在极客玩具中,我一直喜欢穿戴类和小车类。前后做过两只运动心率表,并且参与过麦步手表的测试。TTGO最新出品了一块叫做T-Watch的手表,实际上,是一个可以做手表的穿戴平台,就将我原来的一个基于esp32的电子秤玩具移植到这块手表上,成为一个手表电子秤。使得大家对这个新玩具能有所了解吧。
    all.jpg

    【效果视频】


    T-watch的主要配置】
    芯片:ESP32(配置比较强:FLASH QSPI闪存16 MB / PSRAM 8 MB
    PMU电源管理:Axp202
    显示屏:1.54英寸LCD电容式触摸屏
    传感器:BMA423三轴加速度计,集成步数算法,活动/跟踪识别,高级识别手势
    RTCCF8563
    自定义按钮:一只(gpio36)
    从硬件来看,亮点有这么几处:一是psram8兆(手表也提供了TF卡槽),二是PMU电源管理,可以对屏幕等外设进行单独电源管理;三是1.54寸彩屏+电容触摸;四是三轴加速度以及RTC授时等。
    外观:42.5(宽)*46.5(长)*20(厚度),这是我手工测量,可能略有误差,但是也很精巧了。其中为了穿插表带,厚度至少多出来了4mm空间。
    all2.jpg
    micropython电子秤移植】
    T-Watch出厂时,内置的是一个arduinodemo,是一块很漂亮的带有记步功能以及BLE\WIFI\PMU等设置的手表。带屏幕关闭以及唤醒,如果你希望单纯的手表,实际上就可以直接上手了。
    这是一个成熟项目,我已经在esp32(mpy)上实现过,是基于M5STACK的平台。
    这次移植,主要是要解决PMU电源管理的驱动以及TFT显示器的驱动问题。
    1)感谢TTGO的高手lewis师兄,他将axp202的电源管理模块的驱动移植到了Mpy上,而且是非常完整的移植,对axp202的功能全部开放,方便玩家调用。我这次电子秤移植实际上只是使用到了很少一部分。
    2)这块手表的显示器驱动ICST7789V,这是常用于智能手表的驱动芯片。Lewis师兄将其移植到了mpy上,从玩家讨论来看,也有国外玩家先后尝试了mpy以及纯C两种7789的驱动后,据说后者的速度明显提升,但我们这次用的还是lewis师兄移植的mpy库,可以感受到,在整体刷屏上,速度的确比较慢,这也是后续需要完善的吧。
    我在lewis师兄的工作基础上,借鉴了github上一位玩家的9341库,将字符显示以及画点、画线、实线矩形等功能做了一点移植。这样,手表电子秤的基本功能就具备了。
    【制作中干货一二】
    一是关于字模的制作
    参考github玩家对9341的使用,玩家提供了一个转换工具,叫做font_to_py.py,这是一个非常有用的小工具,可以转换ttf字库至python库,然后由mpy直接调用。非常方便。
    fontpy.png
    这个叫做 freetype的模块需要自行pip安装
    Step2:寻找自己喜欢的字库,我找到了一款七段数码管的字库,digital-7.ttf,然后转变为Mpy可以调用的字库。

    kittenblock中小学创客名师推荐的图形化编程软件

    Python font_to_py.py digital-7.ttf 32 digital-7.py
    其中32就是生成新字库的高度。然后你就可以看到,多了一个名为digital-7.py的七段数码管字模文件啦。
    二是代码,由于注释比较详细,请玩家自行查阅

    kittenblock中小学创客名师推荐的图形化编程软件

    #--------------------------------
    # date:2019-07-03
    # 项目:基于T-watch+hx711的电子秤
    # ST7789以及apx202,来自lewis师兄提供,st7789的部分功能(画线、画点以及text显示来自https://github.com/jeffmer/micropython-ili9341)
    # HX711库,来自https://pypi.org/
    # 实现功能:校准以及校准参数存储,电子秤称重
    #---------------------------------
    
    import time
    import ustruct
    import framebuf
    #import glcdfont
    import tt14
    #import tt24
    #import tt32
    import digital7
    import bauhs93
    from utime import sleep_us
    from micropython import const
    from machine import Pin, SPI
    from hx711 import HX711
    from st7789class import ST7789
    
    #---------TFT pin 定义
    TFT_RST_PIN = const(0)
    TFT_LED_PIN = const(12)
    TFT_DC_PIN = const(27)
    TFT_CS_PIN = const(5)
    TFT_CLK_PIN = const(18)
    TFT_MISO_PIN = const(2)
    TFT_MOSI_PIN = const(19)
    
    
    OPEN_AXP202 = True
    buttonA = Pin(36, Pin.IN)     # create input pin on GPIO36
    
    if OPEN_AXP202:
        import axp202  #导入AXP202电源模块管理库
    
    
    
    
    def color565(r, g, b):
        return (r & 0xf8) << 8 | (g & 0xfc) << 3 | b >> 3
    
    global val_cort  #存放电子秤校正系数
    
    def drawbutton():
            #显示按钮以及文字
      display.erase()
      display.set_pos(150,20)
      display.set_font(tt14)
      display.print('CORR')
      display.rect(130,10,80,30,0xF700)  #button_CORR
    
      
    class Scales(HX711):
        def __init__(self, d_out, pd_sck):
            super(Scales, self).__init__(d_out, pd_sck)
            self.offset = 0
    
        def reset(self):
            self.power_off()
            self.power_on()
    
        def tare(self):
            self.offset = self.read()
            #self.offset = val_tare
    
        def raw_value(self):
            return self.read() - self.offset
    
        def stable_value(self, reads=10, delay_us=500):
            values = []
            for _ in range(reads):
                values.append(self.raw_value())
                sleep_us(delay_us)
            return self._stabilizer(values)
    
        @staticmethod
        def _stabilizer(values, deviation=10):
            weights = []
            for prev in values:
                weights.append(sum([1 for current in values if abs(prev - current) / (prev / 100) <= deviation]))
            return sorted(zip(values, weights), key=lambda x: x[1]).pop()[0]
            
    
    if OPEN_AXP202:
        a = axp202.PMU()
        a.setChgLEDMode(axp202.AXP20X_LED_BLINK_1HZ) #充电led模式
        a.enablePower(axp202.AXP202_LDO2) #打开LDO2路电源
        a.setLDO2Voltage(3300) #设置电压3.3v
    
    bl = Pin(TFT_LED_PIN, Pin.OUT)
    bl.value(1)  #屏幕背光打开
    
    spi = SPI(baudrate=40000000, miso=Pin(TFT_MISO_PIN), mosi=Pin(
        TFT_MOSI_PIN, Pin.OUT), sck=Pin(TFT_CLK_PIN, Pin.OUT))
    
    display = ST7789(spi, cs=Pin(TFT_CS_PIN), dc=Pin(TFT_DC_PIN), rst=None)   #声明一个ST7789实例
    
    '''
    1、建立一个scale实例
    2、从tare.txt当中提取皮重数据---赋值val_tare,设置偏移量用于去皮纠偏
    '''
    scales = Scales(d_out=21, pd_sck=22)
    #读出预存的校正系数
    with open('cort.txt', 'r') as myfile:
            val_cort=float(myfile.read().replace('\n', ''))  #读出预存的校正系数
    myfile.close()
    scales.tare() #初始化时进行一次去皮
    display.erase()
    display.set_pos(100,100)
    display.set_font(bauhs93) #设置字体bauhs93
    display.print('TTGO')
    time.sleep(3)
    display.erase()
    #显示按钮以及文字
    drawbutton()
    while True:
      if buttonA.value()==0: #校准按钮
        time.sleep(0.2)
        display.erase()
        display.set_pos(100,100)
        display.set_font(tt14)
        display.print("ut 100g please..") #请先放上100g的砝码
        sleep_us(5000000)
        val100 = scales.stable_value()  #把100g的对应稳定读数放入val100
        display.print(str(val100)) #屏显200g对应度数
        display.print("ut 200g please..") #请先放上100g的砝码
        sleep_us(5000000)
        val200 = scales.stable_value()  #把200g的对应稳定读数放入val200
        display.set_pos(100,160)
        display.print(str(val200)) #屏显200g对应度数        '''计算校正系统'''
        val_cort=100/(val200-val100)
        display.print(str(val_cort)) #屏显校正系数
        display.print("take away 200g..")
        sleep_us(5000000)
        '''将系数放入cort.txt当中'''
        f = open('cort.txt', 'w')  #打开cort.txt文件,以write方式,准备写入参数
        f.write(str(val_cort))   #把刚才计算的校正系统写入cort.txt中
        f.close()
        display.erase()
        #显示按钮以及文字
        drawbutton()
      display.set_pos(80,100)
      display.set_font(digital7)
      display.print('                           ')
      val = val_cort*scales.stable_value() #带有折算补偿系数的计算,如-0.00051235
      print(val)
      display.set_pos(80,100)
      display.set_font(digital7) #设置七段式数码管字体
      display.print(str("{:.1f}".format(val)))
      sleep_us(1000000)







    【图片一组】
    poweron1.jpg
    poweron.jpg
    w200.jpg w1.jpg

    分别是电子秤的校准以及测量过程,我用了两个砝码(100200克)进行校准,没有考虑温度补偿,设立了一个文本文件存储补偿系数,下次开机时,直接读取就可以了,这就是Mpy的方便之处,不像arduinoesp32中,还需要模拟eeprom库开写入类似的系数。
    corr.jpg
    【小结】
    TWatch优势:(1)硬件配置较好,包括psram\tf卡槽等,套件中提供了一个开发者底板,里面用排母引出来了大量gpio,还有一个IIC扩展槽。姿态传感器以及RTC非常容易开发出好玩的穿戴应用。(2tw并非是一块手表,而是一个像手表的极客平台。这次TTGO专门考虑了将成熟的手表固件准备了可烧写的文件格式,玩家即便不懂编程,也可以将分享的固件烧写到手表里,从而享受不同的体验。
    后续需要提升的希望:(1)希望在mpy的支持方面加大力度,尤其是GUI的开发,类似scratch等,esp32的硬件不断强大、程序的复杂性也日益提升,无论从降低玩家门槛、提升用户体验还是提升工作效率等方面而言,mpy都值得更加关注。(2)进一步丰富社区,在手表固件的开发、分享等方面做得更好。

    【分享】
    手表电子秤所需要的micropython代码、st7789库、hx711库以及fonts字模,均打包在附件中,与各位玩家分享。
    upload_arduino_cn0706.rar (39.14 KB, 下载次数: 1)
    打赏作者鼓励一下!
  • TA的每日心情
    无聊
    2019-7-18 10:00
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2019-7-15 15:05 | 显示全部楼层
    感谢大神分享,先素质三连再慢慢学习
    您需要登录后才可以回帖 登录 | 立即注册  

    本版积分规则

    热门推荐

    OLED 128*64自制可达10000000个选项的菜单(已更新)
    OLED 128*64自制可达10000
    OLED 128*64自制可达10000000个选项的菜单 温馨提示: 建议占个楼再食用本帖子
    【原创】全球最小口袋3D打印机mini one直播教程贴
    【原创】全球最小口袋3D打
    最近闲得蛋疼,没事搞个掌上3D打印机,先放效果图吧。 简介: 采用低导程15mm丝
    图表功能好像用不了
    图表功能好像用不了
    情况是这样,之前做好了一个 温度计,今天做另外一个的时候发现一样的代码写进去但是
    Mac连上Arduino,为什么在开发版信息中显示BN:未知的开发板
    Mac连上Arduino,为什么在
    温湿度DHT11+LCD1602
    温湿度DHT11+LCD1602
    (本人常年潜水,最近做一个小东西,有兴趣的小伙伴可以做一做) 利用 DHT11 + LCD160
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   ( 蜀ICP备14017632号-3 )
    快速回复 返回顶部 返回列表