Funpack 第十期-kitronik ARCADE-摩斯密码练习器python的简单实现
使用微软makecode简单实现的摩斯密码练习器,具有计分,屏幕抖动,马达,蜂鸣器等功能的调用。
标签
Funpack
Python
ptlddn
更新2021-08-31
825

Funpack第十期: kitronik Arcade

 

硬件介绍

      ARCADE是kitronik出品的一款开发板,或者说是可以用微软makecode自行编程的游戏机。板子有一个1.77寸的全彩的LCD屏幕,有蜂鸣器、振动马达、6个操作按钮,一个bootlader自带的menu界面按钮,一个硬件复位按钮,一个电源开关,并通过3节5号电池供电,可以提供20小时续航(当游戏机用可能差了点意思)。

      板载的单片机核心是Atmel SAMD51J19A,是一款工作在 120MHz下的ARM Cotex-M4的单片机。按照命名型号,该单片机为64pin QFN封装,512KB Flash,192K的S-RAM。总的来说,性能并不强,但用来学习编程却能带来不错的体验。

      在手柄板子的背面,只有三个电池座,没有其他元件,也就是说,开发板元件基本采用单面铺贴,正面来看,板上元件极其简介,除了必要的电源芯片,滤波电容外,连电阻都很少用到。

ForA8zx1vdq4Syzz7pjTLBpuYRoG

      可以通过U盘方式下载,貌似u盘方式已经成为入门开发板的一种主流方案了。

      在这里简要介绍下[Microsoft MakeCode Arcade](https://arcade.makecode.com/)

makecode是由微软运营的一个开源的教育平台,旨在构建一套廉价、基础、有趣味性的编程学习平台:

      首先,提供了交互式的模拟器界面,虽然界面和实际硬件来说有一些区别,也不乏存在诸多bug,但却是极大的方便了学生学习编程的热情。

      对于较为初级、或者想感受计算机学习的用户,提供了轻松易懂的块编程,易于上手。

      对于中高级用户,则提供了更为灵活的javascript及python等编程界面。基本能覆盖语言初学者及创客的需求。主页上有很多游戏开发、编程的教程和例程,宝藏众多,论坛我一直没登陆进去,据说论坛有很多大神设计的游戏。

      尽管makecode支持的板卡众多,(大多数都是adafruit出品的),但国内其实能低价买到的并不多,其中最为出名的就是掌控板(microBit)了,但掌控板(本体)可没有该款arcade如此丰富的外设。另外树莓派zero,也可以通过刷写bootloader支持makecode,树莓派相对其他的板子,真可谓降维打击,和掌控板差不多的价格,确是桌面级架构。

接下来进入正题。

 任务

      本次选择的是任务二:设计一个摩斯密码练习器,选择两个按键为点与横,或者一个按键的长短按。LCD屏幕上随机出现一个字符,敲出相应组合,正确时,蜂鸣器响,错误时,电机振动。

      这个题目用python代码实现的,makecode自带的库里用来做文本显示差点意思,有个扩展库名为Text Sprite能够很好的解决文本显示问题,这个库需要加载下才能跑通代码。

      代码的主体就一个init(),里面只跑了一个生成摩斯码 gen_morse()函数,其他功能则通过按键中断调用函数的方式来实现。具体来说,开始时从摩斯码表中随机选出字符,并生成相应的摩斯码序列。接下来通过按按键AB,调用中断函数生成的输入摩斯码key_ram序列,与生成的正确摩斯码序key_ram_list序列做比较,如果相同,则正确,得分score +1 ,如果错误,不得分。界面则通过text sprite在每次按键时更新一次显示文本的方式实现。另外,左键为删除字符,右键为确认输出,上键则是显示正确字符。在右键调用的确认函数中,调用确定正确错误的函数,正确则通过 music.ba_ding.play_until_done(),调用蜂鸣器播放音乐,同时得分加一。错误则调用scene.camera_shake(),使屏幕抖动、调用pins.pin_by_cfg(101).digital_write(True)控制输出IO,使震动马达工作,并在100毫秒后关闭马达,表现为马达短时震动。

      本来想做个多码的摩斯序列, 因此加入了当输出长串时,缩小显示,换行等操作,后来没用上,就当个乐子吧。

      在模拟器上,鼠标点按键很容易出现连点(导致程序出错),硬件则没有这个现象,代码中应当加入按键中断的防抖功能,防止短时间多次调用中断,这部分后续可以加入一个判断函数实现。

      具体的代码见后续代码及附件,视频中进行了演示。

      仿真实现的效果,以及实际上机效果。

FlWH2imdiawEY5WGea2HvmQG4nVgFvmlvvSO6vR1ZUcAMTkDEAAYxlf4

心得体会

      这是第二次参加funpack的活动,之前在第四期的时候,玩过蓝牙传感器开发板,当时觉得,板子集成了很多传感器,非常实用,能用在很多项目中。这次提供的是一款可以当作游戏机玩的编程板,简直爱不释手,尝试了makecode上的一些作品后,也自己上手做了些简单的玩了下。

      板卡本身其实性价比并不高,重要的在于参与活动,提升自我,接触一些有趣的开发板。电子森林、硬禾学堂、得捷电子组织起的这个活动,为创客们带来了一个新的舞台,国外创客混迹hackaday,国内缺少一个能够供创客们展示的平台,funpack的活动是一个好的开始,希望电子森林能够办的越来越好,达到甚至超过hackaday平台。

附件

     附代码:直接粘贴到makecode的python界面使用,注意需要手工点击添加textSprite模块,以供正常编译。

# 生成摩斯码
def gen_morse():
    global char_ram_list,key_ram_list
    char_num= 1
    for index in range(char_num):
        rand= randint(0,38)
        char_ram_list= char_ram_list + char_tab[rand]+  " "
        key_ram_list = key_ram_list + key_tab[rand] + ""
        char_disp.set_text(char_ram_list)

# 显示摩斯码
def disp_key(key_ramtemp: str):
    if len(key_ramtemp) > 20:
        key_disp.set_max_font_height(6)
        key_disp.set_text(key_ramtemp.slice(0, 16))
        key_disp2.set_max_font_height(6)
        key_disp2.set_text(key_ramtemp.slice(16))
 
    else:
        key_disp.set_text(key_ramtemp)

# 键A行为
controller.A.on_event(ControllerButtonEvent.PRESSED, press_keyA)
def press_keyA():
    global key_ram
    key_ram= key_ram + "."+""
    disp_key(key_ram)


# 键B行为
controller.B.on_event(ControllerButtonEvent.PRESSED, press_keyB)
def press_keyB():
    global key_ram
    key_ram= key_ram + "_"+ ""
    disp_key(key_ram)
    
# 键左行为
controller.left.on_event(ControllerButtonEvent.PRESSED, press_keyleft)
def press_keyleft():
    global key_ram
    if len(key_ram)>=1:
       key_ram=key_ram[:-1]
    disp_key(key_ram)

# 键右行为
controller.right.on_event(ControllerButtonEvent.RELEASED, press_keyright)
def press_keyright():
    if check_char_vs_key():
        key_test_disp.set_text("correct")
        music.ba_ding.play_until_done()
        score= score+1
        info.change_score_by(1)
        score_disp.set_text("score:")
    else:
        key_test_disp.set_text("fault")
        scene.camera_shake()
        pins.pin_by_cfg(101).digital_write(True)
        pause(100)
        pins.pin_by_cfg(101).digital_write(False)
        key_disp2.set_text(key_ram_list)
    pause(3000)
    init()

# 显示答案
controller.up.on_event(ControllerButtonEvent.PRESSED, press_keyup)
def press_keyup():
    key_test_disp.set_text(key_ram_list)

# 校验对比
def check_char_vs_key():
    if len(key_ram) !=len(key_ram_list):
        return False
    i=0
    while i <= len(key_ram) - 1:
        if not (((key_ram[i] == '.') and (key_ram_list[i] == '.')) or
            ((key_ram[i] == '_') and (key_ram_list[i] == '_'))):
            return False
        i +=1
    return True

#disp 显示信息
def init():
    global char_ram,char_ram_list,key_ram,key_ram_list
    global char_num,score
    char_ram= ""
    key_ram= ""
    char_ram_list= ""
    key_ram_list= ""
    char_num=0
    key_disp.set_text("")
    key_disp2.set_text("")
    key_test_disp.set_text("")
    score_disp.set_text("score:")
    scene.set_background_color(9)
    gen_morse()

# char对应 字符 key 对应_.键值,tab=table

char_tab= [
    "A","B","C","D","E","F","G",
    "H","I","J","K","L","M","N",
    "O","P","Q","R","S","T",
    "U","V","W","X","Y","Z",
    "1","2","3","4","5","6","7","8","9","0",
    "?","/","-"
]
key_tab= [
    "._","_...","_._.","_..",".",".._.","__.",
    "....","..",".___","_._","._..","__","_.",
    "___",".__.","__._","._.","...","_",
    ".._","..._",".__","_.._","_.__","__..",
    ".____","..___","...__","...._",".....","_....","__...","___..","____.","_____",
    "..__..","_.._.","_...._"
]
info.set_score(0)
score= 0
char_ram_list= ""
key_ram_list= ""
char_num= 0
char_ram= ""
key_ram= ""
char_disp= textsprite.create("")
char_disp.set_max_font_height(30)
char_disp.set_outline(2,6)
char_disp.set_position(0,16)

key_disp= textsprite.create("")
key_disp.set_outline(1,8)
key_disp.set_max_font_height(10)
key_disp.set_position(15,50)

key_disp2= textsprite.create("")
key_disp2.set_outline(1,8)
key_disp2.set_max_font_height(10)
key_disp2.set_position(15,60)

key_test_disp=textsprite.create("")
key_test_disp.set_outline(1,8)
key_test_disp.set_max_font_height(8)
key_test_disp.set_position(10,100)
    
score_disp=textsprite.create("")
score_disp.set_outline(1,8)
score_disp.set_max_font_height(8)
score_disp.set_position(110,8)

init()
附件下载
funpack10_morsecode.py
附件中的代码粘贴到makecode的python代码编辑窗口,编译后直接在线下载到kitronik ARACADE板卡中
团队介绍
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号