M5Stack Basic 模拟小超市【2019-10-03更新stickv进阶】
本帖最后由 沧海笑1122 于 2019-10-4 08:35 编辑【项目简介】M5Stack 模拟小超市M5Stack Basic 是深圳明栈科技的基础款极客开发平台,基于esp32作为core。基本参数如下图。
感谢arduino.cn以及明栈科技M5Stack提供本次试用评测机会。我将尝试用M5Stack Basic+称重模块+热敏打印机,制作一个模拟的小超市。 小超市的基本功能:使用M5Stack Basic作为主控界面,给玩家提供一个超市购物界面:提供两种商品(苹果和核桃),玩家将货品(苹果或者核桃)放置在电子秤盘上,然后选择商品按钮,主控界面会显示出品名、单价、重量(g)以及总价。选择“打印”按钮后,主控将这些商品信息传送至热敏打印机控制器(使用arduino minipro),由控制器将数据解析后,发送至热敏打印机,打印出来超市小票。
下面我们首先通过一段视频,看看整个小超市是怎么运作的吧。
【小视频】
http://player.youku.com/embed/XNDM3Njk2NzcwOA==
【硬件准备】
序号品名型号以及备注
1超市主控M5Stack Basic
2热敏打印机控制器Arduino minipro 5V/16M
3热敏打印机701嵌入式热敏打印机模组,5~9V,2A稳压电源供电
4电子秤形变传感器+HX711模块
5杜邦线若干
【软件准备】
序号品名型号以及备注
1UIFLOWM5出品,图形化micropython编程工具
2VSCODE+M5Stack插件microsoft出品,强劲的编程代码工具,M5提供了M5Stack插件,便于调试
3Arduinojson库版本6.0,Arduinojson.org提供,用于解析json格式数据
4热敏打印机库for arduinohttps://www.adafruit.com/
5Arduino IDE1.8.9arduino.cc
【接线以及简要说明】
【代码以及注释】(1)uiflow进行超市主控的UI设计
(2)使用vscode+m5stack插件进行代码设计
(3)关于arduino promini的2个软串口,在使用过程中的侦听切换
(4)主控台的UI按钮设计以及主要功能简述
【小结】 这是模拟小超市的第一步,后续还会进阶,一是利用m5stickv对商品进行识别,然后把视觉结果传回主控,完成后续步骤,二是加上语音合成模块,提醒客户玩家及时付款。 再次感谢arduino.cn平台以及m5stack.com。这样有趣的极客平台,使得极客更加关注创意本身,而少一些造轮子之举。大幅度降低了进入门槛,也为我们带来了更多的乐趣。 欢迎各位玩家指正,沧海抱拳。
【附件】 本文用到的库以及代码均分享,作为附件上传。 M5stack电子秤是我的前一个小玩具,附上链接,关于电子秤的一些实现方法,在那篇小文中解释得比较详细。
本帖最后由 vany5921 于 2019-9-28 14:04 编辑
第一步:使用UIFLOW编制主控台(m5stack)的UI并且编写主控台侧程序 UIFLOW是M5出品的图形化编程工具,目前可以连接m5stack core以及m5stickc两种产品。玩家可以去官网自行了解一下。UIFLOW集成了M5的各类周边,提供了积木式的编程体验,同时也提供生成的micropyhon代码,除了开发以外,也是入门学习mpy的非常好的工具。 (1)首先设计UI,模拟超市的UI比较简单,一共分为标题栏、内容栏以及控制按钮等三部分。标题栏:显示M5 Sim SuperMarket内容栏:商品名称、重量、单价以及总价等四项内容控制栏:苹果按钮、核桃按钮以及打印按钮因为是模拟小超市,所以利用m5stack basic 的三只按钮,提供苹果以及核桃两种商品选择,玩家后续也可以通过M5的face套件或者刚刚出品的卡片键盘套件扩展你的商品选择。整个UI的设计是拖动+所见即所得式的,你可以在设计中不断“RUN”来观察在实际主控屏幕上的状态,这就是uiflow以及mpy的优势所在,如果是arduino,你需要不停地编译-上传,对于esp32来说,这个设计迭代周期会令人厌烦,但是在uiflow+mpy就让这项工作变得非常容易。(2)主控台编程 除了UI以外,主控台编程主要有几个部分:一是电子秤部分的编程,这部分要实现主控与电子秤之间的连接和调试,接线在一楼已经示意了,注意VCC我选用3.3V。软件部分主要依赖了一个hx711库,详细的调用方式,玩家可以参考我的那篇电子秤帖子。这里依然将校准系数保存在一个txt文件里,存储在主控里。由于uiflow可以很方便在主控里保留多个功能程序,所以我把电子秤的校准程序也上传到主控里,玩家可以根据温度变化(比如季节变化对形变传感器是有影响的)用100g/200g砝码进行校准,校准结果就存放在txt文件里,方便调用。二是uart部分的编程,我们选择uart2作为数据外送的端口。因为需要传送商品、单价、重量、总价等四组数据,所以我们使用json格式来进行传递。三是按钮陷阱的编程,这部分比较简单。对三只按钮的触发进行响应处理,其中苹果和核桃,将更新品名和单价,而打印按钮,就把组装好的json串通过uart2送出去。以下是主控台的代码,注释得还算清楚,您可以结合一楼进行理解。我们使用的工具是vscode+m5stack的插件,调试非常便捷,在下载程序时,用到了upyloder这个很棒的小工具。注意:使用vscode+m5stack的插件调试时,core侧必须保持在usb电缆连接模式下。
# date 2019-09-25
# UIFLOW设计ui,实现电子秤
# 0914 ----- 解决了uart发送单价+称重数据+总价+品名
# 0924 ----- 与arduino 第一次联调
# 0925 ----- 与arduino pro mini 5V/16M联调,价格大致参考市价,苹果15(核桃31元)/kg整理
from m5stack import *
from m5ui import *
from utime import sleep_us
from uiflow import *
from hx711 import HX711
global val_cort#校正系数
global val,v_up,v_tp
v_up=0
v_tp=0
global s_json,v_comd #发送到uart的json字符串
s_json=''
v_comd=''
#uart 初始化,使用uart2向arduin pro mini传递需要打印的数据
uart = None
uart = machine.UART(2, tx=17, rx=16)
uart.init(9600, bits=8, parity=None, stop=1)
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()
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())
return sorted(zip(values, weights), key=lambda x: x).pop()
#创建一个实例
scales = Scales(d_out=5, pd_sck=2)
#读出预存的校正系数
with open('cort.txt', 'r') as myfile:
val_cort=float(myfile.read().replace('\n', ''))#读出预存的校正系数
myfile.close()
scales.tare() #初始化时进行一次去皮
#------------------UI部分
setScreenColor(0x222222)
M5title = M5Title(title="M5 Sim Supermarket", x=3 , fgcolor=0xFFFFFF, bgcolor=0x0000FF)
label0 = M5TextBox(16, 49, "Commodity", lcd.FONT_Ubuntu,0xFFFFFF, rotate=0)
label1 = M5TextBox(16, 90, "Unit Price", lcd.FONT_Ubuntu,0xFFFFFF, rotate=0)
label2 = M5TextBox(16, 127, "Weight", lcd.FONT_Ubuntu,0xFFFFFF, rotate=0)
label3 = M5TextBox(17, 164, "Total Price", lcd.FONT_Ubuntu,0xFFFFFF, rotate=0)
rectangle0 = M5Rect(34, 203, 60, 20, 0xf80d0d, 0xfcfbfb)
rectangle1 = M5Rect(127, 203, 60, 20, 0x55e10c, 0xf8f4f4)
rectangle2 = M5Rect(222, 203, 60, 20, 0x528be5, 0xFFFFFF)
label4 = M5TextBox(42, 205, "Apple", lcd.FONT_Default,0xFFFFFF, rotate=0)
label5 = M5TextBox(134, 207, "Walnut", lcd.FONT_Default,0xfaf9fa, rotate=0)
label6 = M5TextBox(237, 207, "Print", lcd.FONT_Default,0xFFFFFF, rotate=0)
text_comd = M5TextBox(135, 47, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)
text_up = M5TextBox(134, 93, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)
text_weig = M5TextBox(134, 130, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)
text_tp = M5TextBox(134, 164, "Text_tp", lcd.FONT_Default,0xFFFFFF, rotate=0)
while True:
val = val_cort*scales.stable_value() #带有折算补偿系数的计算,如-0.00051235
val1=("%.2f" % val) #将称重数据格式化,小数点后保留2位
text_weig.setText(str(val1)) #显示更新称重数据
v_tp=val*v_up/1000 #因称重为克,折算千克的价格
v_tp=("%.2f" % v_tp)
text_tp.setText(str(v_tp)) #更新总价数据
sleep_us(200000)
if btnA.wasPressed():
# global params
v_comd='Apple'
text_comd.setText(v_comd)
text_up.setText('15.0')
v_up=15
pass
if btnB.wasPressed():
# global params
v_comd='Walnut'
text_comd.setText(v_comd)
text_up.setText('31.0')
v_up=31
pass
if btnC.wasPressed():
s_json="{\"up\":\""+str(v_up)+"\",\"tp\":\""+str(v_tp)+"\",\"commodity\":\""+v_comd+"\",\"weigh\":\""+str(val1)+"\"}"
uart.write(s_json+"\r\n")
pass
第二步:热敏打印机控制器(arduino UNO)与热敏打印机的调试(1)热敏打印机控制器我们选择arduino UNO来做原型调试,一是因为adafruit的热敏打印机库就是在arduino上的,我们没必要造轮子了。二是我们能在TB找到的打印机(包括价格能在接收范围内的),实际上也是基于这个库的,所以使用arduino做原型调试是首选。(2)热敏打印机选择在adafruit官网看到这个打印机,对照TB上面的图片,初步确定了这是一款701模组的嵌入式热敏打印机,购买时注意选择TTL电平。电压输入是5~9V,店家介绍最好在8V,供电电流要求1.5A~2A。实测5A/2A的供电方式,对于字符打印是足够的,但是在打印图片过程中,效果不好,因此建议玩家如果有条件用稳压电源吧。(3)控制器代码部分 控制器的代码主要有两部分内容: 一是需要定义两个软串口,一个用于接收来自m5stack的json格式的商品信息。第二个是用于向热敏打印机发出打印指令。两个软串口之间需要切换侦听,这一点务必注意。我在一楼也用专门的标注提醒了。否则不能正常工作。 二是需要解析来自m5stack的json格式数据,我们用到了大名鼎鼎的arduinojson库,目前版本是6.12,详细内容请玩家自行去arduinojson.org学习了解。因为这次仅仅需要解析四个数据,所以我们用了一层json的格式就可以了。arduinojson.org提供了一个json助手,可以很方便地对你需要设计的json串以及相关代码,内存分配等进行辅助性工作。 以下是arduino uno部分的代码。
//-------date:2019-09-24
//-------模拟超市打印机控制端程序
//-------主要功能:1、解析来自(M5STACK)softserial的数据
// 2、测试热敏打印机端的输出
// 3、与M5STACK basic对接
/*
m5stack 发送来数据格式:up---单价;tp---总价,commodity---品名,weigh--重量
{
"up": "7",
"tp": "840",
"commodity": "apple",
"weigh": "120"
}
*/
//------------ArduinoJson部分
#include <ArduinoJson.h>
#include <SoftwareSerial.h>
SoftwareSerial swSer1(10,11); //UNO-10-RX;UNO-11-TX
//------------Thermal printer部分
#include "Adafruit_Thermal.h"
SoftwareSerial mySerial(5, 6); // UNO-5-RX;UNO-6-TX
Adafruit_Thermal printer(&mySerial); // Pass addr to printer constructor
void setup() {
// Initialize serial port
Serial.begin(9600);
swSer1.begin(9600);
mySerial.begin(9600);
printer.begin(); // Init printer
}
void loop() {
//DynamicJsonDocument doc(152);
//监听来自M5STACK的软串口
swSer1.listen();
while (!swSer1.available())
delay(100);
// Deserialize the JSON document
const size_t capacity = JSON_OBJECT_SIZE(4) + 50;//定义来自arduinojson.org的助手生成
DynamicJsonDocument doc(capacity);
DeserializationError error = deserializeJson(doc, swSer1); //不用软串口读取数据
// Test if parsing succeeds.
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
//仅供调试
String s_commodity=doc["commodity"];
String s_weigh=doc["weigh"];
String s_up=doc["up"];
String s_tp=doc["tp"];
Serial.print(s_commodity);
Serial.print("-----");
Serial.print(s_weigh);
Serial.print("-----");
Serial.print(s_up);
Serial.print("-----");
Serial.println(s_tp);
ToPrint(s_commodity,s_weigh,s_up,s_tp); //调用打印模块
}
void ToPrint( String t_comm , String t_weig, String t_up , String t_tp){
//监听2号软串口
mySerial.listen();
printer.begin(); // Init printer
// caption
printer.inverseOn();
printer.println(F(" M5 Sim SuperMarket "));
printer.inverseOff();
printer.println("--------------------------");
printer.boldOn();
printer.print(F("Commodity:"));
printer.boldOff();
printer.println(t_comm);
printer.boldOn();
printer.print(F("Weigh(g):"));
printer.boldOff();
printer.println(t_weig);
printer.boldOn();
printer.print(F("Unit Price:"));
printer.boldOff();
printer.println( t_up);
printer.boldOn();
printer.print(F("Total Price:"));
printer.boldOff();
printer.println(t_tp);
printer.println("--------------------------");
printer.feed(2);
printer.setDefault(); // Restore printer to defaults
}
第三步:第一次联调:PC-----热敏打印机控制器(arduino UNO)及热敏打印机 联调一共分为两步,这是第一步,用PC的串口助手,模拟来自m5stack的商品数据,然后和arduino uno以及热敏打印机进行测试。本次联调实际上也是两步。一是你需要将arduino uno与热敏打印机首先调试成功,这一步实际上占用了我很多时间。注意提醒:1、你需要根据你到货的打印机标注的通信波特率,对adafriut家提供的打印机库里面的波特率进行修改,比如我买到的是9600,而默认是115200,需要自行调整一下。2、热敏打印机到手后,你可以做一个自检,自检页会显示驱动版本以及波特率。
https://learn.adafruit.com/mini-thermal-receipt-printer/microcontroller
这个教程写得非常详细清晰,感谢伟大的adafriut.com二是PC的串口助手,用一个测试的json串,9600波特率,通过一个usb-ttl转换器,连接到arduino uno上,接线如一楼。在UNO软串口收到来自PC的测试串口,进行解析,然后对需要打印的变量进行赋值。我们写了一个ToPrint()函数,将解析后的四个商品信息,打印到热敏打印机上。也就是形成了超市小票。这张小票同样有两个部分,一是标题区,我们用反相字体的方式进行设计,形成了超市的标题,二是内容区,品名等用粗体字,数据部分用正常字体。两个区域之间我们用“--------”进行隔离。在打印结束后,我们考虑了两步进纸。小票就生成了。然后恢复打印机设置为默认。
第四步:第二次联调:主控台(M5STACK)与打印机控制器(arduino UNO)及热敏打印机 有了前面的积累,这一步联调就比较简单了,注意:ESP32的电平是3.3V的,而我这次选择的arduino uno是可调电平的版本,需要注意将UNO的电平也调整至3.3V。 此刻,你就会看到,如视频中的展示:一旦print按钮按下,uno就收到json数据,然后你可以听到打印机欢快的声音了,因为是热敏打印机,你听不到针头以及喷头的声音,听到的就是进纸的声音。看到了小票打出,数据与主控台的数据一致,这步联调就结束了。需要说明的是:电子秤输出的是克(g),所以我们专门查询了苹果和核桃的市价,大致选择了一个平均价,这个价格是元/1000g,所以这个转换直接在程序设计里,就写入了。小票上,你看到的是重量为g,但是单价和总价都是元。体现模拟小超市尽可能接近现实吧。
第五步:将打印机控制器移植到arduino promini 缩小作品的体积 UNO的体积比较大,作为原型设计很好,但是作为模拟小超市的组成部分,显得体积较大和接线凌乱,所以我们选择了一款袖珍的arduino 控制器,同样是基于328的promini,原本我选择了一片3.3v/8m的版本,结果手头正好有一片焊了排针的5v/16m版,就拿来用了,注意:一是两者电平不一样,好在promini只是读取来自esp32的数据,所以我们省略掉了promini的TX-----esp32这根线。也就是说,来自m5stack(esp32)的3.3v是可以被promini识别的,而且没有过压的担心,反之的那根线我们省略掉了。如果需要两者交互通信,就必须考虑电平转换问题,这一点必须注意。 我们将接好线的promini放在一个透明的圆柱型小盒子里,看着很面熟吧,就是m5staickV的盒子,两头钻孔后,正好作为一个promini的容器。好啦,到此为止,所有的调试工作结束了,如果和孩子一起玩,还可以设计一个收款台,把热敏打印机嵌入到台面上(所谓嵌入,指的就是这个意思)。也可以和孩子一起做一些涂鸦和装饰。 后续我们可能还会跟踪提升这个小玩具。 在使用m5的过程中,我的体会是,能不造轮子尽量别造,能够利用网络上丰富的库和工具来实现你的创意,是一件很有意思的事。不是不鼓励造轮子和创造,而是一定要评估你自己的水平,像我这样的水平一般的就多用成品来组合,否则会有挫败感从而降低你创造的兴趣。 以上就是制作过程的分享,把我能想到的坑也都做了提醒,如果在制作过程中,大家还有问题,欢迎一起交流。谢谢大家。国庆将至,硕果累累,预祝大家节日快乐,善待自己、陪伴家人。 沧海合十。
本帖最后由 沧海笑1122 于 2019-10-4 08:44 编辑
【2019-10-03更新】
主要功能:(1)使用m5stickV进行商品识别,然后将识别后的结果(标签)发送至m5stack(总控台), (2)m5stack(总控台)根据uart1接收到的识别标签,更新商品名称以及单价。
【小视频】点击此处观看演示视频
一、m5stickV侧代码及说明
1、功能按钮:V的正面大按钮,当识别成功后,passlable被赋值为识别后的标签。点击大按钮,播放bi.wav,发出超市扫描的声音。
2、uart_A = UART(UART.UART1, 115200, 8, None, 1, timeout=1000, read_buf_len=4096)
定义uart1,接线是stickv的grove标准接头。
3、本侧代码参考了vany5921师兄发布的《servo hat作为模拟指针与SitickV的串口实验》,在此致谢:handshake。并且基于v-training的Boot.py代码,bi.wav音效来自互联网2
import audio
import gc
import image
import lcd
import sensor
import sys
import time
import uos
import os
import KPU as kpu
from fpioa_manager import *
from Maix import I2S, GPIO
from machine import I2C
#定义扬声器
fm.register(board_info.SPK_SD, fm.fpioa.GPIO0)
spk_sd=GPIO(GPIO.GPIO0, GPIO.OUT)
spk_sd.value(1) #Enable the SPK output
fm.register(board_info.SPK_DIN,fm.fpioa.I2S0_OUT_D1)
fm.register(board_info.SPK_BCLK,fm.fpioa.I2S0_SCLK)
fm.register(board_info.SPK_LRCLK,fm.fpioa.I2S0_WS)
wav_dev = I2S(I2S.DEVICE_0)
#定义uart------------------------用于传送识别数据
from machine import UART
fm.register(board_info.CONNEXT_B,fm.fpioa.UART1_TX)#CONNEXT_B---G34---白
fm.register(board_info.CONNEXT_A,fm.fpioa.UART1_RX)#CONNEXT_A---G35---黄
uart_A = UART(UART.UART1, 115200, 8, None, 1, timeout=1000, read_buf_len=4096)
# init button 这是正面的大按钮
fm.register(board_info.BUTTON_A, fm.fpioa.GPIO1)
but_a = GPIO(GPIO.GPIO1, GPIO.IN, GPIO.PULL_UP) #PULL_UP is required here!
passlable='' #这是需要传送的标签
#--------------------------------
lcd.init()
lcd.rotation(2)
try:
img = image.Image("/sd/startup.jpg")
lcd.display(img)
except:
lcd.draw_string(lcd.width()//2-100,lcd.height()//2-4, "Error: Cannot find start.jpg", lcd.WHITE, lcd.RED)
task = kpu.load("/sd/22503a57a92dcb04_mbnet10_quant.kmodel")
labels=["1","2","3","4","5","6","7","8","9"] #You can check the numbers here to real names.
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing((224, 224))
sensor.run(1)
lcd.clear()
def play_sound(filename):
try:
player = audio.Audio(path = filename)
player.volume(30)
wav_info = player.play_process(wav_dev)
wav_dev.channel_config(wav_dev.CHANNEL_1, I2S.TRANSMITTER,resolution = I2S.RESOLUTION_16_BIT, align_mode = I2S.STANDARD_MODE)
wav_dev.set_sample_rate(wav_info)
spk_sd.value(1)
while True:
ret = player.play()
if ret == None:
break
elif ret==0:
break
player.finish()
spk_sd.value(0)
except:
pass
while(True):
img = sensor.snapshot()
fmap = kpu.forward(task, img)
plist=fmap[:]
pmax=max(plist)
max_index=plist.index(pmax)
a = lcd.display(img)
if pmax > 0.99:
lcd.draw_string(40, 60, "Accu:%.2f Type:%s"%(pmax, labels.strip()))
passlable=str(labels) #赋值给需要传送的标记
#本地打印,仅作调试,正式运行时可以去除
#print(pmax)
print(labels.strip())
print('*******************')
#----------uart_A传送识别标签
#uart_A.write(str(labels))
#uart_A.write('\r')
time.sleep_ms(200)
else:
#未能识别时,送一个no标签
print('0')
print('no')
if but_a.value() == 0 and isButtonPressedA == 0:#按下按钮A
play_sound("/sd/di.wav") #发出扫描音效滴
#----------uart_A传送识别标签
uart_A.write(passlable)
if but_a.value() == 1:
isButtonPressedA = 0
a = kpu.deinit(task)
uart_A.deinit()#释放uart1
二、M5Stack core侧代码及说明
1、使用uart1作为接收口,接线为grove接头,所以uart1 = machine.UART(1, tx=21, rx=22)
2、在接收到数据后,做一个简单的判断,如果标签是9----核桃,如果标签是8---苹果。这是我训练的结果(训练以及本次进阶均采用实体核桃,并非图片),详细的训练过程,参见docs.mastack.com的详细文档。
# date 2019-09-25
# UIFLOW设计ui,实现电子秤
# 0914 ----- 解决了uart发送单价+称重数据+总价+品名
# 0924 ----- 与arduino 第一次联调
# 0925 ----- 与arduino pro mini 5V/16M联调,价格大致参考市价,苹果15(核桃31元)/kg整理
# 1003 ----- 与stickV联调,接收V识别的数据
from m5stack import *
from m5ui import *
from utime import sleep_us
from uiflow import *
from hx711 import HX711
global val_cort#校正系数
global val,v_up,v_tp
v_up=0
v_tp=0
global s_json,v_comd #发送到uart的json字符串
s_json=''
v_comd=''
#uart 初始化,使用uart2向arduin pro mini传递需要打印的数据
uart = None
uart = machine.UART(2, tx=17, rx=16)
uart.init(9600, bits=8, parity=None, stop=1)
uart1 = None
uart1 = machine.UART(1, tx=21, rx=22)
uart1.init(115200, bits=8, parity=None, stop=1)
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()
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())
return sorted(zip(values, weights), key=lambda x: x).pop()
#创建一个实例
scales = Scales(d_out=5, pd_sck=2)
#读出预存的校正系数
with open('cort.txt', 'r') as myfile:
val_cort=float(myfile.read().replace('\n', ''))#读出预存的校正系数
myfile.close()
scales.tare() #初始化时进行一次去皮
#------------------UI部分
setScreenColor(0x222222)
M5title = M5Title(title="M5 Sim Supermarket", x=3 , fgcolor=0xFFFFFF, bgcolor=0x0000FF)
label0 = M5TextBox(16, 49, "Commodity", lcd.FONT_Ubuntu,0xFFFFFF, rotate=0)
label1 = M5TextBox(16, 90, "Unit Price", lcd.FONT_Ubuntu,0xFFFFFF, rotate=0)
label2 = M5TextBox(16, 127, "Weight", lcd.FONT_Ubuntu,0xFFFFFF, rotate=0)
label3 = M5TextBox(17, 164, "Total Price", lcd.FONT_Ubuntu,0xFFFFFF, rotate=0)
rectangle0 = M5Rect(34, 203, 60, 20, 0xf80d0d, 0xfcfbfb)
rectangle1 = M5Rect(127, 203, 60, 20, 0x55e10c, 0xf8f4f4)
rectangle2 = M5Rect(222, 203, 60, 20, 0x528be5, 0xFFFFFF)
label4 = M5TextBox(42, 205, "Apple", lcd.FONT_Default,0xFFFFFF, rotate=0)
label5 = M5TextBox(134, 207, "Walnut", lcd.FONT_Default,0xfaf9fa, rotate=0)
label6 = M5TextBox(237, 207, "Print", lcd.FONT_Default,0xFFFFFF, rotate=0)
text_comd = M5TextBox(135, 47, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)
text_up = M5TextBox(134, 93, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)
text_weig = M5TextBox(134, 130, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)
text_tp = M5TextBox(134, 164, "Text_tp", lcd.FONT_Default,0xFFFFFF, rotate=0)
while True:
val = val_cort*scales.stable_value() #带有折算补偿系数的计算,如-0.00051235
val1=("%.2f" % val) #将称重数据格式化,小数点后保留2位
text_weig.setText(str(val1)) #显示更新称重数据
v_tp=val*v_up/1000 #因称重为克,折算千克的价格
v_tp=("%.2f" % v_tp)
text_tp.setText(str(v_tp)) #更新总价数据
sleep_us(200000)
if btnA.wasPressed():
# global params
v_comd='Apple'
text_comd.setText(v_comd)
text_up.setText('15.0')
v_up=15
pass
if btnB.wasPressed():
# global params
v_comd='Walnut'
text_comd.setText(v_comd)
text_up.setText('31.0')
v_up=31
pass
if btnC.wasPressed():
s_json="{\"up\":\""+str(v_up)+"\",\"tp\":\""+str(v_tp)+"\",\"commodity\":\""+v_comd+"\",\"weigh\":\""+str(val1)+"\"}"
uart.write(s_json+"\r\n")
pass
if uart1.any():
bin_data = uart1.readline(1)
decode_bin_data=bin_data.decode()
#label1.setText(decode_bin_data)
wait_ms(200)
if decode_bin_data=='9': #核桃
v_comd='Walnut'
text_comd.setText(v_comd)
text_up.setText('31.0')
v_up=31
else:
if decode_bin_data=='8': #苹果
# global params
v_comd='Apple'
text_comd.setText(v_comd)
text_up.setText('15.0')
v_up=15
else:
pass
pass
代码分享:包括上述文中两份代码以及di.wav ---- 来自互联网搜集
牛比了.楼主多发作业哟,这样看来M5STACK是有操作系统的哟.这才功能强大了. ynqjwfb 发表于 2019-10-5 12:47
牛比了.楼主多发作业哟,这样看来M5STACK是有操作系统的哟.这才功能强大了.
m5stack是基于esp32的极客平台,应该还属于单片机范畴,没有操作系统。mpy可以使开发效率更高。另外,小电脑和嵌入式系统的界限也在逼近。树莓派等小电脑价格和体积都更低,esp32\k210等单片机性能更强大。 感谢分享。。。
页:
[1]