【问题标题】:share enum between python and arduino在 python 和 arduino 之间共享枚举
【发布时间】:2020-11-28 10:15:29
【问题描述】:

我在 python 中创建了一个 gui,允许 arduino 控制的 mecanum 轮车四处移动。

推车允许 8 种不同的移动方向,并且可以左右旋转。命令通过笔记本电脑(w10,python)和 arduino 之间的串行连接发送。

我在 python 中有一个 Enum 类,表示不同的移动方向。

我在 arduino 中有一个相应的枚举来解释来自 python 任务的命令。

为两种编码环境共享一个通用枚举定义的简单方法是什么?

【问题讨论】:

标签: python enums arduino share


【解决方案1】:

没有。 C/C++ 中的枚举和 python 中的 enum.Enum 是两个非常不同的东西。但是,有一个强大的解决方案。我建议从您的 python 代码中编写 C/C++/Arduino 标头。借助 python 强大的自省功能,可以轻松地使用 __dict__ 扫描您的 python 枚举/类,并编写一个您的 Arduino 代码可以使用的 .h 文件。这就是我生成与相关 python 项目中的枚举和常量匹配的 Verilog 和 SystemVerilog 标头的方式。运行 python 应用程序会生成一个新的头文件,始终保持同步。

编辑:更明确的示例

我为基于 FPGA 的微处理器构建了一个汇编程序。汇编器是用 python 编写的,而处理器是用 Verilog 编写的。所以我创建了一个这样的 Verilog 头文件:

# Compute the 'after' content.
content = '// opcodes.vh\n'
content += '`ifndef _opcodes_vh\n'
content += '`define _opcodes_vh\n'
content += '// DO NOT EDIT -- FILE GENERATED BY ASSEMBLER\n'
content += '// ------------------------------------\n'
content += '// OPCODES\n'
content += '// ------------------------------------\n'
A = Arch
for i in A.__dict__:
    if i.startswith('OPC_'):
        o = i.replace('OPC_', 'OPCODE_')
        s = '`define ' + o
        while len(s) < 40:
            s = s + ' '
        hexval = str(hex(A.__dict__[i])).replace('0x', '')
        decval = str(A.__dict__[i])
        s = s + "7'h" + hexval + '\t\t// ' + str(decval) + '\n'
        content += s
content += '// END OF GENERATED FILE.\n'
content += '`endif'

# Write to very specific location for Vivado to see it.
file = open(self.opcodes_filename, 'w', encoding='utf-8')
file.write(content)
file.close()

最终输出如下:

// opcodes.vh
`ifndef _opcodes_vh
`define _opcodes_vh
// DO NOT EDIT -- FILE GENERATED BY ASSEMBLER
// ------------------------------------
// OPCODES
// ------------------------------------
`define OPCODE_LD_GPR_EXPR              7'h0        // 0
`define OPCODE_LD_GPR_GPTR              7'h1        // 1
`define OPCODE_SV_EXPR_GPR              7'h2        // 2
...
`define OPCODE_IO_T                     7'h4a       // 74
`define OPCODE_TX_T                     7'h4b       // 75
// END OF GENERATED FILE.
`endif

【讨论】:

    【解决方案2】:

    正如@TomServo 所说,让您的 Python 代码编写 Arduino 标头。这是一个使用 aenum 3.01 或 Python 3.10 2 的示例:

    from aenum import Enum   # or "from enum import Enum"
    
    class CHeader(Enum):
        def __init_subclass__(cls, **kwds):
            # write Enums to C header file
            cls_name = cls.__name__
            header_path = getattr(cls, '_%s__header' % cls_name)
            with open(header_path, 'w') as fh:
                fh.write('initial header stuff here\n')
                for enum in cls:
                    fh.write('#define %s %r\n' % (enum.name, enum.value))
    
    class Arduino(CHeader):
        #
        _order_ = 'ONE TWO'  # only if using Python 2
        #
        __header = './arduino.h'
        #
        ONE = 1
        TWO = 2
    

    这会导致:

    initial header stuff here
    #define ONE 1
    #define TWO 2
    

    1 披露:我是Python stdlib Enumenum34 backportAdvanced Enumeration (aenum) 库的作者。

    2 在 aenum 3.0 和 Python 3.10 中,__init_subclass__ 将在 将枚举成员添加到 Enum 类之后调用(在之前的版本中,__init_subclass__ 被调用 在添加成员之前)。

    【讨论】:

    猜你喜欢
    • 2023-02-20
    • 2014-05-21
    • 2017-10-22
    • 2012-01-10
    • 2012-03-19
    • 2011-12-15
    • 2015-06-09
    • 2021-06-01
    • 1970-01-01
    相关资源
    最近更新 更多