diff --git a/docs/Advanced_development/zh/QuecPythonBus/ExtInt.md b/docs/Advanced_development/zh/QuecPythonBus/ExtInt.md new file mode 100644 index 0000000000000000000000000000000000000000..8212f411d32600013ac5fbdc48a1e56c33d2395b --- /dev/null +++ b/docs/Advanced_development/zh/QuecPythonBus/ExtInt.md @@ -0,0 +1,58 @@ +# 外部中断实验 + +## 修订历史 + +| 版本 | 日期 | 作者 | 变更表述 | +| ---- | ---------- | ------- | -------- | +| 1.0 | 2021-09-22 | Grey.Tu | 初版 | + +文档主要介绍如何实现 ExtInt 检测外部中断,从硬件设计和软件设计两方面讲解,通过阅读本文,您将学会 ExtInt 外部中断功能使用。 + +有关API详解请参考 [QuecPython-machine - ExtInt](https://python.quectel.com/wiki/#/zh-cn/api/QuecPythonClasslib?id=extint) + + + +## 硬件设计 + +ExtInt 外部中断原理为检测 PIN 脚外部电平转变,既 PIN 脚上有上升沿或下降沿信号。 + +![media_ExtInt_1](media/media_ExtInt_1.jpg) + +原理图与按键原理图类似: + +![media_ExtInt_2](media/media_ExtInt_2.jpg) + +## 软件设计 + +首先确定要控制硬件的哪个引脚,然后通过官网的 API 类库找到对应的 GPIO 编号 。详解请参考 [QuecPython-machine - ExtInt](https://python.quectel.com/wiki/#/zh-cn/api/QuecPythonClasslib?id=extint) + +例: ![media_ExtInt_3](media/media_ExtInt_3.jpg)EC600S/N的引脚10为GPIO1。 + +开始编写代码,选择对应的 GPIO 进行 ExtInt 外部中断初始化: + +```python +from machine import ExtInt + + +def callback(args): + print('interrupt: {}'.format(args)) + + +extint13 = ExtInt(ExtInt.GPIO13, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, callback) # 创建对象 +extint12 = ExtInt(ExtInt.GPIO12, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, callback) # 创建对象 +extint13.enable() # 使能中断 +extint12.enable() # 使能中断 +print('开启GPIO: {}中断. \r\n'.format(extint13.line())) +print('开启GPIO: {}中断. \r\n'.format(extint12.line())) + +# extint13.disable() # 关闭中断 +# extint12.disable() # 关闭中断 +``` + +配套代码 + +## 配套代码 + + + 下载代码 + diff --git a/docs/Advanced_development/zh/QuecPythonBus/button.md b/docs/Advanced_development/zh/QuecPythonBus/button.md new file mode 100644 index 0000000000000000000000000000000000000000..acfec324500112026c303a12032867fa95005da6 --- /dev/null +++ b/docs/Advanced_development/zh/QuecPythonBus/button.md @@ -0,0 +1,68 @@ +# 按键输入实验 + +## 修订历史 + +| 版本 | 日期 | 作者 | 变更表述 | +| ---- | ---------- | ---- | -------- | +| 1.0 | 2021-09-17 | Grey | 初版 | + +文档主要介绍如何实现检测 GPIO 电平,从硬件设计和软件设计两方面讲解,通过阅读本文,您将学会查看硬件连接关系、代码编写思路和验证实验理论。 + +有关API详解请参考 [QuecPython-machine - PIN](https://python.quectel.com/wiki/#/zh-cn/api/QuecPythonClasslib?id=pin) + + + +## 硬件资源 + +EC600x 开发板引出了两个 PIN 脚供客户实验按键输入实验。 + +我们配置对应 GPIO 为上拉输入模式便可以通过按而不按按键改变 GPIO的电平。 + +![media_button_1](media/media_button_1.jpg) + + + +## 软件设计 + +首先确定要检测的硬件引脚是那一个 GPIO ,我们通过官网的 API 类库找到对应的 GPIO编号 。详解请参考 [QuecPython-machine - PIN](https://python.quectel.com/wiki/#/zh-cn/api/QuecPythonClasslib?id=pin) + +例: ![media_button_2](media/media_button_2.jpg)EC600S/N的引脚10为GPIO1。 + +而我们 EC600x 开发板两个按键 PIN59/PIN60,对应EC600S/N为:PIN59 => GPIO12;PIN60 => GPIO13。对应EC600U为:PIN60 => GPIO4;PIN59 无对应 GPIO,不能进行按键输入检测。这边我们实现一个按键的按键检测功能。 + +### 代码实现 + +```python +import utime +from machine import Pin + + +if __name__ == '__main__': + gpio13 = Pin(Pin.GPIO13, Pin.IN, Pin.PULL_PU, 1) # EC600S/N开发板使用 + # gpio13 = Pin(Pin.GPIO4, Pin.IN, Pin.PULL_PU, 1) # EC600U开发板使用 + while True: + if gpio13.read() == 0: + utime.sleep_ms(10) + if gpio13.read() == 0: + while gpio13.read() == 0: + pass + print("GPIO13按下") + pass +``` + + + +## 下载验证 + +下载.py 文件到模组运行: + +![media_button_3](media/media_button_3.jpg) + +下载之后,按下按键,便会有信息打印: + +![media_button_4](media/media_button_4.jpg) + +## 配套代码 + + + 下载代码 \ No newline at end of file diff --git a/docs/Advanced_development/zh/QuecPythonBus/buzzer.md b/docs/Advanced_development/zh/QuecPythonBus/buzzer.md new file mode 100644 index 0000000000000000000000000000000000000000..f290fe779ca867c73094f053d4dc77f54dc2a5a7 --- /dev/null +++ b/docs/Advanced_development/zh/QuecPythonBus/buzzer.md @@ -0,0 +1,137 @@ +# 蜂鸣器实验 + +## 修订历史 + +| 版本 | 日期 | 作者 | 变更表述 | +|------|------|------|------| +| 1.0 | 2021-03-20 | gary.zhou | 初版 | +| 1.1 | 2021-09-15 | Grey.Tu | 修改有缘蜂鸣器绘制为无缘蜂鸣器控绘制. | + +文档主要介绍如何 PWM 控制 **无缘蜂鸣器** ,使 **无缘蜂鸣器** 发声。从硬件设计和软件设计两方面讲解,通过阅读本文,可以学习 PWM 基本使用。 + +有关 API 详解请参考 [QuecPython-misc - PWM](https://python.quectel.com/wiki/#/zh-cn/api/QuecPythonClasslib?id=pwm) + + + +## 硬件描述 + +蜂鸣器分为 **有源蜂鸣器** 与 **无源蜂鸣器** 两种。 **有缘蜂鸣器** 直接供电就会发声,控制如同 LED ,控制引脚输出高低电平即可。硬件电路也与 LED 电路类似。 有关驱动请参考 LED 控制章节。本文主要介绍 **无源蜂鸣器** 的驱动,实现 PWM 控制 **无缘蜂鸣器** 。 + +![media_buzzer_1](media/media_buzzer_1.jpg) + +淘宝搜索购买无源蜂鸣器 + +![media_buzzer_2](media/media_buzzer_2.jpg) + +无源蜂鸣器通过PWM开关三极管驱动。 我们只需要电源,以及2KHz~5KHz 的pwm方波即可。 + +![media_buzzer_3](media/media_buzzer_3.jpg) + + + +## 软件设计 + +#### 查询开发板对应的IO口 + +首先确定要控制硬件的哪个引脚,然后通过官网的 API 类库找到对应的 PWM 编号 。详解请参考 [QuecPython-misc - PWM](https://python.quectel.com/wiki/#/zh-cn/api/QuecPythonClasslib?id=pwm) 例: + +| 模块型号 | **对应引脚号** | +| -------------------------------------- | -------------- | +| EC600S/N ==> PWM2
EC600U ==> PWM0 | 引脚号70 | + + +### **实验代码** + +```python + +from misc import PWM +import utime as time +import urandom as random +import log + +# API https://python.quectel.com/wiki/#/zh-cn/api/QuecPythonClasslib?id=pwm +# 蜂鸣器模块 https://detail.tmall.com/item.htm?id=41251333522 +# 无源蜂鸣器-频率可控版 + +""" + +pwm0 = PWM(PWM.PWMn,PWM.ABOVE_xx,highTime,cycleTime) + +注:EC600SCN平台,支持PWM0-PWM3,对应引脚如下: + +PWM0 – 引脚号52 + +PWM1 – 引脚号53 + +PWM2 – 引脚号70 + +PWM3 – 引脚号69 + +""" + +# 获取logger对象 + +buzzer_log = log.getLogger("buzzer_test") + +# Duration 为 ms + +def outputpwm(HZ, duty_cycle, Duration): + + # 将HZ 转化为 10us 级别 + + cycleTime = int((10000000/HZ)/10) + highTime = int(cycleTime * duty_cycle) + + # 输出debug级别的日志 + + buzzer_log.debug( + """out put pin70 cycleTime {0} * 10us, + highTime {1} * 10us, Duration of {2}""" + .format(cycleTime, highTime, Duration)) + pwm1 = PWM(PWM.PWM2, PWM.ABOVE_10US, highTime, cycleTime) + pwm1.open() + + # 休眠给定毫秒数的时间 + + time.sleep_ms(Duration) + pwm1.close() + pass + + +def test_Buzzer(): + + #设置日志输出级别 + + log.basicConfig(level=log.DEBUG) + + # 循环遍历10次 + + for i in range(10): + + # 随机生成 start 到 end 范围内的浮点数,范围可以自己选择, 0~1 + + duty_cycle = random.uniform(0.1, 0.8) + + # 建议输出2000~5000HZ 的PWM波形 + # 随机生成一个 start 到 end 之间的整数 + + HZ = random.randint(2000, 5000) + outputpwm(HZ, duty_cycle, 500) + time.sleep_ms(1500) + + pass + + +if __name__ == "__main__": + + # creat a thread Check key status + + test_Buzzer() + +# 将代码下载运行,可以听到蜂鸣器产生随机的声音 +``` + +## 配套代码 + +* [下载代码](code/code_buzzer.py) + \ No newline at end of file diff --git a/docs/Advanced_development/zh/QuecPythonBus/code/code_ExtInt.py b/docs/Advanced_development/zh/QuecPythonBus/code/code_ExtInt.py new file mode 100644 index 0000000000000000000000000000000000000000..241ccd79ca3130dce058c71b9577fac8dc4b6da7 --- /dev/null +++ b/docs/Advanced_development/zh/QuecPythonBus/code/code_ExtInt.py @@ -0,0 +1,29 @@ +from machine import ExtInt +import utime as time +# PIN脚及API介绍请参考 https://python.quectel.com/wiki/#/zh-cn/api/QuecPythonClasslib?id=extint +state = 10 # 测试次数 + + +def callback(args): + print('interrupt: {}'.format(args)) + + +def main(): + extint13 = ExtInt(ExtInt.GPIO13, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, callback) # 创建对象 + extint12 = ExtInt(ExtInt.GPIO12, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, callback) # 创建对象 + extint13.enable() # 使能中断 + extint12.enable() # 使能中断 + print('开启GPIO: {}中断. \r\n'.format(extint13.line())) + print('开启GPIO: {}中断. \r\n'.format(extint12.line())) + # 等待按键按下,触发 + while state: + time.sleep_ms(1) + pass + # 停止映射外部中断 + extint13.disable() # 关闭中断 + extint12.disable() # 关闭中断 + print("The main function has exited") + + +if __name__ == "__main__": + main() diff --git a/docs/Advanced_development/zh/QuecPythonBus/code/code_UART_CDC.py b/docs/Advanced_development/zh/QuecPythonBus/code/code_UART_CDC.py new file mode 100644 index 0000000000000000000000000000000000000000..a8d288d5ef5c2687598f5a9bd78c390b6eb664ab --- /dev/null +++ b/docs/Advanced_development/zh/QuecPythonBus/code/code_UART_CDC.py @@ -0,0 +1,70 @@ +# import log +import utime +import _thread +import ubinascii +from machine import UART + +state = 1 +uart_x = None +usbcdc = None + +# # | 参数 | 参数类型 | 说明 | +# # | -------- | ------- | ------------------ | +# # | CRITICAL | 常量 | 日志记录级别的数值 50 | +# # | ERROR | 常量 | 日志记录级别的数值 40 | +# # | WARNING | 常量 | 日志记录级别的数值 30 | +# # | INFO | 常量 | 日志记录级别的数值 20 | +# # | DEBUG | 常量 | 日志记录级别的数值 10 | +# # | NOTSET | 常量 | 日志记录级别的数值 0 | +# log.basicConfig(level=log.CRITICAL) # 设置日志输出级别 +# log = log.getLogger("Grey") # 获取logger对象,如果不指定name则返回root对象,多次使用相同的name调用getLogger方法返回同一个logger对象 + + +def uart_x_read(): + global state + global uart_x + global usbcdc + + while state: + msglen = uart_x.any() # 返回是否有可读取的数据长度 + if msglen: # 当有数据时进行读取 + msg = uart_x.read(msglen) # 读取数据 + utf8_msg = msg.decode() # 初始数据是字节类型(bytes),将字节类型数据进行编码 + if "Grey" in utf8_msg: + break + else: + usbcdc.write("{}".format(utf8_msg)) # 发送数据 + utime.sleep_ms(1) + state = 0 + + +def usbcdc_read(): + global state + global uart_x + global usbcdc + + while state: + msglen = usbcdc.any() # 返回是否有可读取的数据长度 + if msglen: # 当有数据时进行读取 + msg = usbcdc.read(msglen) # 读取数据 + utf8_msg = msg.decode() # 初始数据是字节类型(bytes),将字节类型数据进行编码 + if "Grey" in utf8_msg: + break + else: + uart_x.write("{}".format(utf8_msg)) # 发送数据 + utime.sleep_ms(1) + state = 0 + + +if __name__ == "__main__": + uart_x = UART(UART.UART2, 115200, 8, 0, 1, 0) + usbcdc = UART(UART.UART3, 115200, 8, 0, 1, 0) + + uart_x.write("Grey_测试") + usbcdc.write("Grey_测试") + + _thread.start_new_thread(uart_x_read, ()) # 创建一个线程来监听接收uart消息 + _thread.start_new_thread(usbcdc_read, ()) # 创建一个线程来监听接收CDC消息 + + while state: + utime.sleep_ms(1) diff --git a/docs/Advanced_development/zh/QuecPythonBus/code/code_button.py b/docs/Advanced_development/zh/QuecPythonBus/code/code_button.py new file mode 100644 index 0000000000000000000000000000000000000000..097c0992ad2c319c7eabecbc90f4caa34713697c --- /dev/null +++ b/docs/Advanced_development/zh/QuecPythonBus/code/code_button.py @@ -0,0 +1,15 @@ +import utime +from machine import Pin + + +if __name__ == '__main__': + gpio13 = Pin(Pin.GPIO13, Pin.IN, Pin.PULL_PU, 1) # EC600S/N开发板使用 + # gpio13 = Pin(Pin.GPIO4, Pin.IN, Pin.PULL_PU, 1) # EC600U开发板使用 + while True: + if gpio13.read() == 0: + utime.sleep_ms(10) + if gpio13.read() == 0: + while gpio13.read() == 0: + pass + print("GPIO13按下") + pass diff --git a/docs/Advanced_development/zh/QuecPythonBus/code/code_buzzer.py b/docs/Advanced_development/zh/QuecPythonBus/code/code_buzzer.py new file mode 100644 index 0000000000000000000000000000000000000000..5225c7bbaed9b85736d1dad9b7cd261fc11b6215 --- /dev/null +++ b/docs/Advanced_development/zh/QuecPythonBus/code/code_buzzer.py @@ -0,0 +1,83 @@ +from misc import PWM +import utime as time +import urandom as random +import log + +# API https://python.quectel.com/wiki/#/zh-cn/api/QuecPythonClasslib?id=pwm +# 蜂鸣器模块 https://detail.tmall.com/item.htm?id=41251333522 +# 无源蜂鸣器-频率可控版 + +""" + +pwm0 = PWM(PWM.PWMn,PWM.ABOVE_xx,highTime,cycleTime) + +注:EC600SCN平台,支持PWM0-PWM3,对应引脚如下: + +PWM0 – 引脚号52 + +PWM1 – 引脚号53 + +PWM2 – 引脚号70 + +PWM3 – 引脚号69 + +""" + +# 获取logger对象 + +buzzer_log = log.getLogger("buzzer_test") + +# Duration 为 ms + +def outputpwm(HZ, duty_cycle, Duration): + + # 将HZ 转化为 10us 级别 + + cycleTime = int((10000000/HZ)/10) + highTime = int(cycleTime * duty_cycle) + + # 输出debug级别的日志 + + buzzer_log.debug( + """out put pin70 cycleTime {0} * 10us, + highTime {1} * 10us, Duration of {2}""" + .format(cycleTime, highTime, Duration)) + pwm1 = PWM(PWM.PWM2, PWM.ABOVE_10US, highTime, cycleTime) + pwm1.open() + + # 休眠给定毫秒数的时间 + + time.sleep_ms(Duration) + pwm1.close() + pass + + +def test_Buzzer(): + + #设置日志输出级别 + + log.basicConfig(level=log.DEBUG) + + # 循环遍历10次 + + for i in range(10): + + # 随机生成 start 到 end 范围内的浮点数,范围可以自己选择, 0~1 + + duty_cycle = random.uniform(0.1, 0.8) + + # 建议输出2000~5000HZ 的PWM波形 + # 随机生成一个 start 到 end 之间的整数 + + HZ = random.randint(2000, 5000) + outputpwm(HZ, duty_cycle, 500) + time.sleep_ms(1500) + + pass + + +if __name__ == "__main__": + + # creat a thread Check key status + + test_Buzzer() \ No newline at end of file diff --git a/docs/Advanced_development/zh/QuecPythonBus/media/media_ExtInt_1.jpg b/docs/Advanced_development/zh/QuecPythonBus/media/media_ExtInt_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..41421feb83f7955a3de178e949d94ed47a6287ea Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonBus/media/media_ExtInt_1.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonBus/media/media_ExtInt_2.jpg b/docs/Advanced_development/zh/QuecPythonBus/media/media_ExtInt_2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5355ab9897d86fdc57c91e1bd269567dba99043b Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonBus/media/media_ExtInt_2.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonBus/media/media_ExtInt_3.jpg b/docs/Advanced_development/zh/QuecPythonBus/media/media_ExtInt_3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5f7d9a8fdcc6186a90a06efeaced6fcf0e872fe4 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonBus/media/media_ExtInt_3.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonBus/media/media_UART_1.jpg b/docs/Advanced_development/zh/QuecPythonBus/media/media_UART_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0dd3d266fee8f2b92601ded72dbc03f677130a5b Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonBus/media/media_UART_1.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonBus/media/media_UART_2.jpg b/docs/Advanced_development/zh/QuecPythonBus/media/media_UART_2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1337a536d4331ae03a0f3bc74ff52fe0abef3bc5 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonBus/media/media_UART_2.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonBus/media/media_UART_3.jpg b/docs/Advanced_development/zh/QuecPythonBus/media/media_UART_3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..042fc4cfc8b4c1ccdc900ca31be90588cfcace38 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonBus/media/media_UART_3.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonBus/media/media_button_1.jpg b/docs/Advanced_development/zh/QuecPythonBus/media/media_button_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..99ad61a5655bdc24f0b63c0480548be6014594d0 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonBus/media/media_button_1.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonBus/media/media_button_2.jpg b/docs/Advanced_development/zh/QuecPythonBus/media/media_button_2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5f7d9a8fdcc6186a90a06efeaced6fcf0e872fe4 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonBus/media/media_button_2.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonBus/media/media_button_3.jpg b/docs/Advanced_development/zh/QuecPythonBus/media/media_button_3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1b8ca2f4595ea54bb892cfbf6c6854e1b9b195e0 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonBus/media/media_button_3.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonBus/media/media_button_4.jpg b/docs/Advanced_development/zh/QuecPythonBus/media/media_button_4.jpg new file mode 100644 index 0000000000000000000000000000000000000000..80bd9f7dd8497851cab1c8ea92455a595be6a9a7 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonBus/media/media_button_4.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonBus/media/media_buzzer_1.jpg b/docs/Advanced_development/zh/QuecPythonBus/media/media_buzzer_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..08655fb0aca59b86c0c8c0c856522fe0f440cd1a Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonBus/media/media_buzzer_1.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonBus/media/media_buzzer_2.jpg b/docs/Advanced_development/zh/QuecPythonBus/media/media_buzzer_2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..04f1abf9f20c5d03199c9f018b7fb957cc5db9b4 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonBus/media/media_buzzer_2.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonBus/media/media_buzzer_3.jpg b/docs/Advanced_development/zh/QuecPythonBus/media/media_buzzer_3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e46d0e65656a8f8d992dd1a51dc20e7c6157d2a0 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonBus/media/media_buzzer_3.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonBus/uart.md b/docs/Advanced_development/zh/QuecPythonBus/uart.md new file mode 100644 index 0000000000000000000000000000000000000000..0fb8e8c9997c5fe1ce66e26d9710dbb0e3566668 --- /dev/null +++ b/docs/Advanced_development/zh/QuecPythonBus/uart.md @@ -0,0 +1,78 @@ +# UART实验 + +## 修订历史 + +| 版本 | 日期 | 作者 | 变更表述 | +| ---- | ---------- | ------- | -------- | +| 1.0 | 2021-09-22 | Grey.tu | 初版 | + +文档主要介绍QuecPython_UART,UART作为一种常用的通用方式,主要用数据交互,可实现全双工传输。通过本文你将了解到EC600x(包括EC600S、EC600N、EC600U)UART的设置参数及使用方法。 + +有关API详解请参考 [QuecPython-machine-UART](https://python.quectel.com/wiki/#/zh-cn/api/QuecPythonClasslib?id=uart) + + + +## 硬件设计 + +针对不同的模组,开放的UART列表如下: + +| 模块型号 | UART编号 | UART_PIN | +| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| EC600S/N | UART0_DEBUG PORT
UART1_BT PORT
UART2_MAIN PORT
UART3_USB CDC PORT | UART0_DEBUG_PORT(TX => PIN71 & RX => PIN72)
UART1_BT_PORT(TX => PIN3 & RX => PIN2)
UART2_MAIN_PORT(TX => PIN32 & RX => PIN31)
USB_CDC_PORT ==> USB虚拟口,波特率不受限 | +| EC600U | UART0_DEBUG PORT
UART1_BT PORT
UART2_MAIN PORT
UART3_USB CDC PORT | UART0_DEBUG_PORT(TX => PIN71 & RX => PIN72)
UART1_BT_PORT(TX => PIN124 & RX => PIN123)
UART2_MAIN_PORT(TX => PIN32 & RX => PIN31)
USB_CDC_PORT ==> USB虚拟口,波特率不受限
注: EC600U_DEBUG PORT只能作为DEBUG_LOG输出使用,
不能作为UART通信使用. | + +官方QuecPython开发板V1.2/V1.3的UART位置标记如下图: + +![media_UART_1](media/media_UART_1.jpg) + +注:次图仅适用于官方QuecPython开发板V1.2/V1.3。后续开发板视情况而定。 + + + +## 软件设计 + +物理 UART 基本连接使用我们在 UART 功能章节已经介绍,我们本章过多介绍,本章我们主要介绍下 USB CDC PORT。 + +USB CDC PORT 为USB虚拟的串行通信口,此通信口采用 UART 一样的通信协议,但并未真正意义的 UART。它的通信速率不受 UART 波特率的限制,可根据USB协议自动设别。可以更快速率的传输数据,也无需固定波特率的繁琐。 + +```python +from machine import UART + +uart_x = UART(UART.UART2, 115200, 8, 0, 1, 0) +usbcdc = UART(UART.UART3, 115200, 8, 0, 1, 0) # 此波特率设置无效, 通信时可以任意波特率 + +while True: + uart_x_msglen = uart_x.any() + if uart_x_msglen: + uart_x_msg = uart_x.read(uart_x_msglen) + uart_x_utf8_msg = uart_x_msg.decode() + usbcdc.write("{}".format(uart_x_utf8_msg)) + + usbcdc_msglen = usbcdc.any() + if usbcdc_msglen: + usbcdc_msg = usbcdc.read(usbcdc_msglen) + usbcdc_utf8_msg = usbcdc_msg.decode() + uart_x.write("{}".format(usbcdc_utf8_msg)) +``` + +运行上面的脚本代码,便可实现物理 UART2 与 USB CDC PORT 的数据透传。 + + + +## 下载验证 + +下载.py 文件到模组运行: + +![media_UART_2](media/media_UART_2.jpg) + +下载之后,便可实现物理 UARTx 与 USB CDC PORT 的数据透传功能。 + +![media_UART_3](media/media_UART_3.jpg) + + + +## 配套代码 + + + 下载代码 + diff --git a/docs/Advanced_development/zh/QuecPythonSub/code/code_ebf_smd4805.py b/docs/Advanced_development/zh/QuecPythonSub/code/code_ebf_smd4805.py new file mode 100644 index 0000000000000000000000000000000000000000..ee9ac94fef04638b31b41e9a0017bf11a585210f --- /dev/null +++ b/docs/Advanced_development/zh/QuecPythonSub/code/code_ebf_smd4805.py @@ -0,0 +1,148 @@ +''' +File: EBF_SMD4805.py +Project: others +File Created: Wednesday, 6th January 2021 2:16:52 pm +Author: chengzhu.zhou +----- +Last Modified: Wednesday, 6th January 2021 2:56:42 pm +Modified By: chengzhu.zhou +----- +Copyright 2021 - 2021 quectel +''' + +""" +参考资料 +1. API +https://python.quectel.com/wiki/#/zh-cn/api/?id=pwm +https://python.quectel.com/wiki/#/zh-cn/api/?id=pin +2. 模块资料 +https://item.taobao.com/item.htm?ft=t&id=543053172983 +步进电机驱动器 + 42步进电机 +2.1 模块开发资料 +https://ebf-products.readthedocs.io/zh_CN/latest/module/motor/ebf-msd4805.html +""" + +""" +引脚连接 +| 电机 | EC600开发板 | 对应的函数标号 | +| ---------- | ------------------ | ------- | +| ENA- (GPIO) | GPIO81 (引脚号16) | GPIO7 | +| DIR- (GPIO) | GPIO77 (引脚号15) | GPIO6 | +| PUL- (PWM) | GPIO2_1V8 (引脚号70) | PWM2 | +| ENA+ DIR+ PUL+ | 1V8(电源) | 无 | +""" + + + + +from misc import PWM +from machine import Pin +import utime as time +import urandom as random +import log +def delay_500us(): + for i in range(600): + pass + + +def delay_250us(): + for i in range(310): + pass + + +ENABLE_MOTOR = 0x1 +DISABLE_MOTOR = 0x0 + +DIR_CLOCKWISE = 0x1 +DIR_ANTI_CLOCKWISE = 0x0 + + +class ebf_smd4805(): + + dev_log = None + + # 步进电机的参数 + sm_para_step = None # 步进角度 + # 控制器的参数 + env_pin = None # 使能引脚 + dir_pin = None # 方向引脚 + pul_pwm = None # 脉冲输出引脚 + ctrl_divstep = None # 细分参数,具体请参考控制器手册 + + def init(self, step, divstep): + self.dev_log = log.getLogger("ebf_smd4805") + self.env_pin = Pin(Pin.GPIO7, Pin.OUT, Pin.PULL_DISABLE, 0) + self.dir_pin = Pin(Pin.GPIO6, Pin.OUT, Pin.PULL_DISABLE, 0) + # 配置电机的参数 + self.sm_para_step = step + # 配置控制器的参数 + self.ctrl_divstep = divstep + + def reset(self): + self.env_pin.write(DISABLE_MOTOR) + self.dir_pin.write(DIR_ANTI_CLOCKWISE) + if self.pul_pwm is not None: + self.pul_pwm.close() + + # 根据频率 初始化PWM + def outputpwm(self, HZ, duty_cycle): + # 将HZ 转化为 us 级别 + cycleTime = int(1000000/HZ) + highTime = int(cycleTime * duty_cycle) + return highTime, cycleTime + + # 根据速度,设置PWM的输出 + def enable_pwm(self, speed): + # 1. 首先根据步进电机的步进角度,计算旋转一圈需要多少个脉冲 + Count_pulse = int(360/self.sm_para_step) + self.dev_log.debug("sm motor step as {0}".format(Count_pulse)) + # 2. 根据控制器的细分参数,计算控制器控制步进电机旋转一圈,需要多少的脉冲 + Count_pulse = int(Count_pulse * self.ctrl_divstep) + # 3. 最后计算出1秒旋转speed圈,需要多少个脉冲 , 换句话说 就是频率 + Count_pulse = int(Count_pulse * speed) + # 4. 初始化PWM, 默认占空比%50 + highTime, cycleTime = self.outputpwm(Count_pulse, 0.1) + self.dev_log.debug( + """config frequency is {0}HZ,cycleTime {1}us, hightime {2}us""" + .format(Count_pulse, cycleTime, highTime)) + self.pul_pwm = PWM(PWM.PWM2, PWM.ABOVE_10US, + int(highTime), int(cycleTime)) + self.pul_pwm.open() + pass + + def disable_pwm(self): + self.pul_pwm.close() + pass + + # speed 为速度, 每秒多少圈 + # Duration 为持续时间, ms + # dir 表示方向 + def run(self, speed, Duration, dir=DIR_CLOCKWISE): + self.dir_pin.write(dir) + self.dev_log.info( + "Configure the motor to rotate {0} revolutions per second".format(speed)) + self.enable_pwm(speed) + self.env_pin.write(1) + # delay + for i in range(int(Duration * 4)): + delay_250us() + self.env_pin.write(0) + + self.reset() + pass + + +def test_ebf_smd4805(): + log.basicConfig(level=log.DEBUG) + # log.basicConfig(level=log.INFO) + ebf_smd4805_dev = ebf_smd4805() + ebf_smd4805_dev.init(step=1.8, divstep=2) + for i in range(2, 10): + ebf_smd4805_dev.run(i, Duration=1000, dir=DIR_CLOCKWISE) + print("test_ebf_smd4805 Function exit,!!!") + pass + + +if __name__ == "__main__": + # creat a thread Check key status + test_ebf_smd4805() diff --git a/docs/Advanced_development/zh/QuecPythonSub/ebf_smd4805.md b/docs/Advanced_development/zh/QuecPythonSub/ebf_smd4805.md new file mode 100644 index 0000000000000000000000000000000000000000..9d434c1d4aca364265b283d4f4362573c62ebba9 --- /dev/null +++ b/docs/Advanced_development/zh/QuecPythonSub/ebf_smd4805.md @@ -0,0 +1,215 @@ +# 步进电机驱动实验 + +## 修订历史 + +| 版本 | 日期 | 作者 | 变更表述 | +| ---- | ---------- | ------- | -------- | +| 1.0 | 2021-09-24 | Grey.Tu | 初版 | + +本片文章主要描述使用 EC600x 来驱动步进电机控制器,从而驱动步进电机。 + + + +## 硬件说明 + +模块驱动步进电机需要步进电机控制器: + +#### 步进电机控制器 + +![media_ebf_smd4805_1](media/media_ebf_smd4805_1.jpg) + +#### 步进电机 + +![media_ebf_smd4805_2](media/media_ebf_smd4805_2.png) + +![media_ebf_smd4805_3](media/media_ebf_smd4805_3.jpg) + +步进电机有 42步进电机/ 57步进电机/ 86步进电机等之分,不同的步进电机适配不同的步进电机控制器。 + +### 实验设备 + +(1)直流电源,可以输 出 12V~48V 的直流电 + +(2)步进电机控制器 + +(3)步进电机 + +(4)连接线若干 + +### 驱动说明 + +步进电机驱动器只需要控制三个引脚,就可以驱动驱动器控制电机了。 + +(1)ENA使能控制引脚,使能驱动器驱动电机。根据驱动器型号不同电平有所不同。 + +(2)DIR方向控制引脚,确定顺时针或者是逆时针。根据驱动器型号不同电平有所不同。 + +(3)PUL步进脉冲引脚,给控制器脉冲。根据设置的细分有不同的脉冲数量步进一个步进角。细分设置为驱动器拨码开关设置。 + +### 引脚连接 + +(1)连接好 24V 电源,具体电压根据实际的步进电机驱动器规格确定。 + +| 驱动器引脚 | 电源引脚 | 说明 | 备份 | +| ---------- | -------- | -------- | ---- | +| V+ | 24V | 电源正极 | | +| V- | GND | 电源负极 | | + +(2)连接驱动器与步进电机,具体接线方式根据实际的步进电机驱动器与步进电机规格确定。 + +| 驱动器引脚 | 步进电机引脚 | 说明 | 备份 | +| ---------- | ------------ | ---- | ---- | +| A+ | A | A项+ | | +| A- | C | A项- | | +| B+ | B | B项+ | | +| B- | D | B项- | | + +(3)连接驱动器和 EC600x 开发板,,具体电压根据实际的步进电机驱动器规格确定。 + +步进电机驱动器可以采用共阳/共阴两种连接方式,我们这里采用共阳极的连接方式 + +![media_ebf_smd4805_4](media/media_ebf_smd4805_4.png) + +| 驱动器引脚 | EC600S 开发板引脚 | 说明 | 备份 | +| ---------- | ----------------- | ------------ | ---- | +| ENA+ | 1V8 | 共阳极 | | +| ENA- | GPIOx | 使能控制信号 | | +| DIR+ | 1V8 | 共阳极 | | +| DIR+ | GPIOx | 方向控制信号 | | +| PUL+ | 1V8 | 共阳极 | | +| PUL- | GPIOx / PWMx | 步进脉冲信号 | | + + + +## 软件设计 + +```python +# 引脚连接 +# | 电机引脚 | EC600开发板 | 对应的函数标号 | +# | ------------------- | --------------------- | ------------ | +# | ENA- (GPIO) | GPIO81 (引脚号16) | GPIO7 | +# | DIR- (GPIO) | GPIO77 (引脚号15) | GPIO6 | +# | PUL- (PWM) | GPIO2_1V8 (引脚号70) | PWM2 | +# | ENA+ DIR+ PUL+ | 1V8(电源) | 无 | + +from misc import PWM +from machine import Pin +import utime as time +import urandom as random +import log + + +def delay_500us(): + for i in range(600): + pass + + +def delay_250us(): + for i in range(310): + pass + + +ENABLE_MOTOR = 0x1 +DISABLE_MOTOR = 0x0 + +DIR_CLOCKWISE = 0x1 +DIR_ANTI_CLOCKWISE = 0x0 + + +class ebf_smd4805: + + dev_log = None + + # 步进电机的参数 + sm_para_step = None # 步进角度 + # 控制器的参数 + env_pin = None # 使能引脚 + dir_pin = None # 方向引脚 + pul_pwm = None # 脉冲输出引脚 + ctrl_divstep = None # 细分参数,具体请参考控制器手册 + + def init(self, step, divstep): + self.dev_log = log.getLogger("ebf_smd4805") + self.env_pin = Pin(Pin.GPIO7, Pin.OUT, Pin.PULL_DISABLE, 0) + self.dir_pin = Pin(Pin.GPIO6, Pin.OUT, Pin.PULL_DISABLE, 0) + # 配置电机的参数 + self.sm_para_step = step + # 配置控制器的参数 + self.ctrl_divstep = divstep + + def reset(self): + self.env_pin.write(DISABLE_MOTOR) + self.dir_pin.write(DIR_ANTI_CLOCKWISE) + if self.pul_pwm is not None: + self.pul_pwm.close() + + # 根据频率 初始化PWM + @staticmethod + def outputpwm(hz, duty_cycle): + # 将HZ 转化为 us 级别 + cycleTime = int(1000000 / hz) + highTime = int(cycleTime * duty_cycle) + return highTime, cycleTime + + # 根据速度,设置PWM的输出 + def enable_pwm(self, speed): + # 1. 首先根据步进电机的步进角度,计算旋转一圈需要多少个脉冲 + Count_pulse = int(360/self.sm_para_step) + self.dev_log.debug("sm motor step as {0}".format(Count_pulse)) + # 2. 根据控制器的细分参数,计算控制器控制步进电机旋转一圈,需要多少的脉冲 + Count_pulse = int(Count_pulse * self.ctrl_divstep) + # 3. 最后计算出1秒旋转speed圈,需要多少个脉冲 , 换句话说 就是频率 + Count_pulse = int(Count_pulse * speed) + # 4. 初始化PWM, 默认占空比%50 + highTime, cycleTime = self.outputpwm(Count_pulse, 0.5) + self.dev_log.debug( + """config frequency is {0}HZ,cycleTime {1}us, hightime {2}us""" + .format(Count_pulse, cycleTime, highTime)) + self.pul_pwm = PWM(PWM.PWM0, PWM.ABOVE_10US, + int(highTime), int(cycleTime)) + self.pul_pwm.open() + pass + + def disable_pwm(self): + self.pul_pwm.close() + pass + + # speed 为速度, 每秒多少圈 + # Duration 为持续时间, ms + # dir 表示方向 + def run(self, speed, duration, dir1=DIR_CLOCKWISE): + self.dir_pin.write(dir1) + self.dev_log.info( + "Configure the motor to rotate {0} revolutions per second".format(speed)) + self.enable_pwm(speed) + self.env_pin.write(1) + # delay + for i in range(int(duration * 4)): + delay_250us() + self.env_pin.write(0) + + self.reset() + pass + + +def test_ebf_smd4805(): + log.basicConfig(level=log.DEBUG) + # log.basicConfig(level=log.INFO) + ebf_smd4805_dev = ebf_smd4805() + ebf_smd4805_dev.init(step=1.8, divstep=2) + for i in range(2, 10): + ebf_smd4805_dev.run(i, duration=1000, dir1=DIR_CLOCKWISE) + print("test_ebf_smd4805 Function exit,!!!") + pass + + +if __name__ == "__main__": + test_ebf_smd4805() +``` + + + +## 配套代码 + + + 下载代码 \ No newline at end of file diff --git a/docs/Advanced_development/zh/QuecPythonSub/media/media_ebf_smd4805_1.jpg b/docs/Advanced_development/zh/QuecPythonSub/media/media_ebf_smd4805_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..448e34941fce5f3a89174e42a3e97046c185294c Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonSub/media/media_ebf_smd4805_1.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonSub/media/media_ebf_smd4805_2.png b/docs/Advanced_development/zh/QuecPythonSub/media/media_ebf_smd4805_2.png new file mode 100644 index 0000000000000000000000000000000000000000..30ffefcca8809e47b705b17f6c5bc7e08acf43da Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonSub/media/media_ebf_smd4805_2.png differ diff --git a/docs/Advanced_development/zh/QuecPythonSub/media/media_ebf_smd4805_3.jpg b/docs/Advanced_development/zh/QuecPythonSub/media/media_ebf_smd4805_3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d1b9b96a236ee53dbffc43848d4b390e667fb693 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonSub/media/media_ebf_smd4805_3.jpg differ diff --git a/docs/Advanced_development/zh/QuecPythonSub/media/media_ebf_smd4805_4.png b/docs/Advanced_development/zh/QuecPythonSub/media/media_ebf_smd4805_4.png new file mode 100644 index 0000000000000000000000000000000000000000..1d10a7f41db0bf594df84ca39930b7d815c389c7 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonSub/media/media_ebf_smd4805_4.png differ