codelab_adapter_extensions icon indicating copy to clipboard operation
codelab_adapter_extensions copied to clipboard

完善Arduino插件

Open wwj718 opened this issue 5 years ago • 41 comments

收到一封来自印度的邮件,之前始终没认真考虑接入Arduino,毕竟社区认为micro:bit/MicroPython/RPI更可能是未来,但由于低廉的价格,大量落后地区在使用Arduino,所以打算将pymata-aio内置到CodeLab Adapter,提供开箱可用的Arduino插件,不知是否有小伙伴愿意一起在这个分支上工作。

image

目前bilikyar已经完成了一部分工作:scratch3_arduino, 我们可以在这个基础上继续前进。

已经发布了内置pymata-aio的codelab-adapter版本: v0_8_3 。

wwj718 avatar May 27 '19 01:05 wwj718

开发引导

前端Scratch插件

创建你的第一个Scratch3.0 Extension

CodeLab Adapter extension

wwj718 avatar May 27 '19 02:05 wwj718

为了完善的Arduino插件,我们需要一下几点(有遗漏,欢迎补充):

  1. 需要印度这所学校用的操作系统的版本和Arduino的型号(nano 还是 uno),也就是简单的需求收集工作这点 @wwj718 能否麻烦你跟他们问一问呢?
  2. 完善adapter arduino插件,实现如果对于没有固件的arduino板子,进行自动烧录的工作。这个部分我比较熟我可以完成。
  3. 完善arduino的scratch部分的插件,然后我在考虑是否需要翻译插件为印地语,这个与需要根据印度那边的给我们的反馈。

bilikyar avatar May 27 '19 06:05 bilikyar

image Arduino nano with chg340 driver chip. using python 3.7. Os Ubuntu 18.04 64 bit. Python is in default path of Ubuntu.

zhouF96 avatar May 27 '19 06:05 zhouF96

这样就清楚了

bilikyar avatar May 27 '19 06:05 bilikyar

@bilikyar 关于第三点,我觉得使用英文就行了,英语在印度使用广泛。

wwj718 avatar May 27 '19 08:05 wwj718

好的,那现在的主要问题就是自动烧录固件了。

bilikyar avatar May 27 '19 10:05 bilikyar

@wwj718 我在ubuntu 18.04 上使用下面的方式启动插件的时候,adapter直接崩溃,你在打包pymata_aio 的时候进行测试过吗?

import zmq
import subprocess
import pathlib
import platform
import time
import threading

from time import sleep
from codelab_adapter import settings
from codelab_adapter.core_extension import Extension
from pymata_aio.pymata3 import PyMata3
from pymata_aio.constants import Constants

class arduinoExtension(Extension):
    def __init__(self):
        name = type(self).__name__
        super().__init__(name)
        board = PyMata3()

bilikyar avatar May 28 '19 07:05 bilikyar

Ubuntu上自动烧录固件功能已完成,现在需要跟之前的插件进行整合。

bilikyar avatar May 28 '19 08:05 bilikyar

@bilikyar 我到ubuntu下测试一下,我在mac和windows下测试过

wwj718 avatar May 29 '19 02:05 wwj718

@bilikyar 我刚在ubuhntu16.04 64bit下测试,

from pymata_aio.pymata3 import PyMata3
from pymata_aio.constants import Constants

是正常的

board = PyMata3()触发了错误:

pymata_aio Version 2.30	Copyright (c) 2015-2018 Alan Yorinks All rights reserved.

Unable to find Serial Port, Please plug in cable or check cable connections.

你可以在adapter之外先测试 PyMata3()

wwj718 avatar May 29 '19 03:05 wwj718

adapter之外運行是沒問題的

bilikyar avatar May 29 '19 04:05 bilikyar

@bilikyar 我在adapter之外运行也是一样的错误呢

image

wwj718 avatar May 29 '19 04:05 wwj718

你试试使用命令行运行,看错误信息

image

wwj718 avatar May 29 '19 04:05 wwj718

现在的问题说明:

1.这是我目前的插件测试代码

import zmq
import subprocess
import pathlib
import platform
import time
import threading
import os

from time import sleep

from pymata_aio.pymata3 import PyMata3
from pymata_aio.constants import Constants


from codelab_adapter.utils import ui_error
from codelab_adapter.core_extension import Extension
from codelab_adapter import settings


def get_python3_path():
    # If it is not working,  Please replace python3_path with your local python3 path. shell: which python3
    if (platform.system() == "Darwin"):
        # which python3
        # 不如用PATH python
        # 不确定
        path = "/usr/local/bin/python3"
    if platform.system() == "Windows":
        path = "python3"
    if platform.system() == "Linux":
        path = "/usr/bin/python3"
    return path


python3_path = get_python3_path()


class arduinoExtension(Extension):
    def __init__(self):
        name = type(self).__name__
        super().__init__(name)

        board = PyMata3()
        BOARD_LED = 13
        board.set_pin_mode(BOARD_LED, Constants.OUTPUT)

        print("LED On")
        board.digital_write(BOARD_LED, 1)
        board.sleep(1.0)
        print("LED Off")
        board.digital_write(BOARD_LED, 0)
        board.sleep(1.0)

    def run(self):
        pass

        while self._running:
            pass


export = arduinoExtension

2.通过命令行的方式运行adapter在ubuntu第一次启动插件,能运行成功,以下是成功信息:

pymata_aio Version 2.30	Copyright (c) 2015-2018 Alan Yorinks All rights reserved.

Using COM Port:/dev/ttyACM0

Initializing Arduino - Please wait... 2019-05-29 14:49:28,756 - INFO - [socketio_server.py:293:background_task2] - - sub: arduinoExtension-30871

Arduino Firmware ID: 2.5 StandardFirmataPlus.ino
Auto-discovery complete. Found 20 Digital Pins and 6 Analog Pins


LED On
LED Off
2019-05-29 14:49:38,050 - DEBUG - [gui.py:380:_handle_extension_checkbox] - - extension checkbox:extension_arduino_nano is clicked; value:0
2019-05-29 14:49:38,050 - DEBUG - [core_extension.py:65:publish] - - publish: {'topic': '__control', 'payload': 'terminate', 'type': 'adapter'}
2019-05-29 14:49:38,051 - DEBUG - [socketio_server.py:253:background_task] - - sensor_sub recv: {'topic': '__control', 'payload': 'terminate', 'type': 'adapter'}

3.关闭插件,重开就会报以下错误,adapter自动关闭:

pymata_aio Version 2.30	Copyright (c) 2015-2018 Alan Yorinks All rights reserved.

Using COM Port:/dev/ttyACM0

Initializing Arduino - Please wait... 2019-05-29 14:49:41,896 - INFO - [socketio_server.py:293:background_task2] - - sub: arduinoExtension-30825
_report_firmware() missing 1 required positional argument: 'sysex_data'
Shutting down ...

bilikyar avatar May 29 '19 06:05 bilikyar

@bilikyar 比力 我猜和插件的加载机制有关,看起来是资源没有释放,我看看插件加载机制,稍后给你反馈

wwj718 avatar May 29 '19 07:05 wwj718

@zhouF96 你看下这个问题

wwj718 avatar May 29 '19 08:05 wwj718

@bilikyar 我刚才梳理过了插件的生命周期 :

勾选插件:

  • import 对应python模块(extension_xxx.py)
  • 实例化类(arduinoExtension)
  • 将run方法运行为线程

取消勾选: 将self.__running设置为false

wwj718 avatar May 29 '19 08:05 wwj718

init(self):方法中应该只包含插件的基本信息,不占用端口资源等,与外界交互的逻辑部分/或有资源释放的部分应该写在run(self):方法下,run方法中,gui界面打勾的话,调用插件的run方法,并且将插件的self._running设置为true,不打勾的话,跳出self._running的循环,在循环后释放资源。

zhouF96 avatar May 29 '19 08:05 zhouF96

可能改成这样OK? @bilikyar @wwj718

import zmq
import subprocess
import pathlib
import platform
import time
import threading
import os

from time import sleep

from pymata_aio.pymata3 import PyMata3
from pymata_aio.constants import Constants


from codelab_adapter.utils import ui_error
from codelab_adapter.core_extension import Extension
from codelab_adapter import settings


def get_python3_path():
    # If it is not working,  Please replace python3_path with your local python3 path. shell: which python3
    if (platform.system() == "Darwin"):
        # which python3
        # 不如用PATH python
        # 不确定
        path = "/usr/local/bin/python3"
    if platform.system() == "Windows":
        path = "python3"
    if platform.system() == "Linux":
        path = "/usr/bin/python3"
    return path


python3_path = get_python3_path()


class arduinoExtension(Extension):
    def __init__(self):
        name = type(self).__name__
        super().__init__(name)

        

    def run(self):
        board = PyMata3()
        BOARD_LED = 13
        board.set_pin_mode(BOARD_LED, Constants.OUTPUT)
        while self._running:
            print("LED On")
            board.digital_write(BOARD_LED, 1)
            board.sleep(1.0)
            print("LED Off")
            board.digital_write(BOARD_LED, 0)
            board.sleep(1.0)


export = arduinoExtension

zhouF96 avatar May 29 '19 08:05 zhouF96

@zhouF96 现在报了以下错误:

Exception in thread 1559120970.4316733:
Traceback (most recent call last):
  File "threading.py", line 916, in _bootstrap_inner
  File "threading.py", line 864, in run
  File "codelab_adapter/core_extension.py", line 92, in start_as_thread
  File "/home/bilikyar/codelab_adapter/extensions/extension_arduino_nano.py", line 45, in run
    board = PyMata3()
  File "site-packages/pymata_aio/pymata3.py", line 67, in __init__
  File "asyncio/events.py", line 694, in get_event_loop
  File "asyncio/events.py", line 602, in get_event_loop
RuntimeError: There is no current event loop in thread '1559120970.4316733'.

2019-05-29 17:09:30,840 - INFO - [socketio_server.py:293:background_task2] - - sub: arduinoExtension-30843

bilikyar avatar May 29 '19 09:05 bilikyar

@zhouF96 在python的线程中需要这样运行协程: https://github.com/Scratch3Lab/codelab_adapter_extensions/blob/master/extension_mqtt_broker.py#L37

wwj718 avatar May 29 '19 11:05 wwj718

@bilikyar 这样改的话就OK了,测试没问题,注意调用board.shutdown()方法解除对tty的占用并结束线程 @wwj718

import zmq
import subprocess
import pathlib
import platform
import time
import threading
import os
import asyncio
from time import sleep

from pymata_aio.pymata3 import PyMata3
from pymata_aio.constants import Constants


from codelab_adapter.utils import ui_error
from codelab_adapter.core_extension import Extension
from codelab_adapter import settings
from codelab_adapter.utils import threaded

def get_python3_path():
    # If it is not working,  Please replace python3_path with your local python3 path. shell: which python3
    if (platform.system() == "Darwin"):
        # which python3
        # 不如用PATH python
        # 不确定
        path = "/usr/local/bin/python3"
    if platform.system() == "Windows":
        path = "python3"
    if platform.system() == "Linux":
        path = "/usr/bin/python3"
    return path


python3_path = get_python3_path()



class arduinoExtension(Extension):
    def __init__(self):
        name = type(self).__name__
        super().__init__(name)
    
    def boardaction(self):
        self.board = PyMata3()
        BOARD_LED = 13
        self.board.set_pin_mode(BOARD_LED, Constants.OUTPUT)
        print("LED On")
        self.board.digital_write(BOARD_LED, 1)
        self.board.sleep(1.0)
        print("LED Off")
        self.board.digital_write(BOARD_LED, 0)
        self.board.sleep(1.0)
        self.board.shutdown()
        print("finished")

    @threaded
    def task(self):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        loop.run_until_complete(self.boardaction())
        loop.run_forever()        

    def run(self):
        self.task()

        while self._running:
            pass
        

export = arduinoExtension

zhouF96 avatar Jun 05 '19 07:06 zhouF96

上海一家硬件公司开放的插件: https://github.com/Scratch3Lab/codelab_adapter_extensions/blob/master/extension_robofriends.py, 基于makeblock开放的arduino firmata项目

wwj718 avatar Jun 12 '19 02:06 wwj718

现在的问题说明:

1.这是我目前的插件测试代码

import zmq
import subprocess
import pathlib
import platform
import time
import threading
import os

from time import sleep

from pymata_aio.pymata3 import PyMata3
from pymata_aio.constants import Constants


from codelab_adapter.utils import ui_error
from codelab_adapter.core_extension import Extension
from codelab_adapter import settings


def get_python3_path():
    # If it is not working,  Please replace python3_path with your local python3 path. shell: which python3
    if (platform.system() == "Darwin"):
        # which python3
        # 不如用PATH python
        # 不确定
        path = "/usr/local/bin/python3"
    if platform.system() == "Windows":
        path = "python3"
    if platform.system() == "Linux":
        path = "/usr/bin/python3"
    return path


python3_path = get_python3_path()


class arduinoExtension(Extension):
    def __init__(self):
        name = type(self).__name__
        super().__init__(name)

        board = PyMata3()
        BOARD_LED = 13
        board.set_pin_mode(BOARD_LED, Constants.OUTPUT)

        print("LED On")
        board.digital_write(BOARD_LED, 1)
        board.sleep(1.0)
        print("LED Off")
        board.digital_write(BOARD_LED, 0)
        board.sleep(1.0)

    def run(self):
        pass

        while self._running:
            pass


export = arduinoExtension

2.通过命令行的方式运行adapter在ubuntu第一次启动插件,能运行成功,以下是成功信息:

pymata_aio Version 2.30	Copyright (c) 2015-2018 Alan Yorinks All rights reserved.

Using COM Port:/dev/ttyACM0

Initializing Arduino - Please wait... 2019-05-29 14:49:28,756 - INFO - [socketio_server.py:293:background_task2] - - sub: arduinoExtension-30871

Arduino Firmware ID: 2.5 StandardFirmataPlus.ino
Auto-discovery complete. Found 20 Digital Pins and 6 Analog Pins


LED On
LED Off
2019-05-29 14:49:38,050 - DEBUG - [gui.py:380:_handle_extension_checkbox] - - extension checkbox:extension_arduino_nano is clicked; value:0
2019-05-29 14:49:38,050 - DEBUG - [core_extension.py:65:publish] - - publish: {'topic': '__control', 'payload': 'terminate', 'type': 'adapter'}
2019-05-29 14:49:38,051 - DEBUG - [socketio_server.py:253:background_task] - - sensor_sub recv: {'topic': '__control', 'payload': 'terminate', 'type': 'adapter'}

3.关闭插件,重开就会报以下错误,adapter自动关闭:

pymata_aio Version 2.30	Copyright (c) 2015-2018 Alan Yorinks All rights reserved.

Using COM Port:/dev/ttyACM0

Initializing Arduino - Please wait... 2019-05-29 14:49:41,896 - INFO - [socketio_server.py:293:background_task2] - - sub: arduinoExtension-30825
_report_firmware() missing 1 required positional argument: 'sysex_data'
Shutting down ...

这个我测试了一下,主要是firmata的串口操作导致的,第一次连接成功;第二次连接枚举失败,目前比较傻瓜的解决方案是每次启动插件的时候,重新烧录一遍固件

jatsmulator avatar Jun 20 '19 09:06 jatsmulator

为了完善的Arduino插件,我们需要一下几点(有遗漏,欢迎补充):

  1. 需要印度这所学校用的操作系统的版本和Arduino的型号(nano 还是 uno),也就是简单的需求收集工作这点 @wwj718 能否麻烦你跟他们问一问呢?
  2. 完善adapter arduino插件,实现如果对于没有固件的arduino板子,进行自动烧录的工作。这个部分我比较熟我可以完成。
  3. 完善arduino的scratch部分的插件,然后我在考虑是否需要翻译插件为印地语,这个与需要根据印度那边的给我们的反馈。

adapter arduino插件如何实现arduino编译和烧录的呢?调用arduino官方自带的gcc exe编译器?

zfm076 avatar Jun 25 '19 09:06 zfm076

@bilikyar @zhouF96 @jatsmulator 可能比我更清楚 @zfm076 提出的这个问题, 是否能给出一些回答?

wwj718 avatar Jun 26 '19 02:06 wwj718

这个问题的解决方案是avrdude,arduino的本身就是调用此模块来烧录程序的。

bilikyar avatar Jun 26 '19 05:06 bilikyar

@bilikyar @zhouF96 @jatsmulator 可能比我更清楚 @zfm076 提出的这个问题, 是否能给出一些回答?

谢谢你们抽空回答我的问题。现在我在本地电脑已经完成了arduino的编译下载的exe程序开发。其实也是调用了arduino自带的gcc、avrdude的工具用python做一个exe文件而已。然后现在准备开发一套arduino的scratch blocks,按照网上的教程在我电脑搭建好了scratch-blocks、scratch-gui、scratch-vm。也编译通过了,网页也能打开scratch的编辑器了。 然后下一步就不懂怎么开发我想要的block了,也就是我要是想添加一个arduino的block 应该改哪些东西呢?有木有参考资料额?谢谢

zfm076 avatar Jun 27 '19 04:06 zfm076

你可以参考这个文章,然后你可以看看其他这个博客里文章,会对你比较有帮助。

bilikyar avatar Jun 27 '19 05:06 bilikyar

你可以参考这个文章,然后你可以看看其他这个博客里文章,会对你比较有帮助。

谢谢,我按照文章里面操作。 在Cmder输入以下提示 不是命令。所以打不开编辑器呢? λ webpack-dev-server --https 'webpack-dev-server' 不是内部或外部命令,也不是可运行的程序 或批处理文件。

zfm076 avatar Jun 27 '19 05:06 zfm076