diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..c71f34b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +*.js linguist-language=python +*.css linguist-language=python +*.html linguist-language=python +*.md linguist-language=python +*.yml linguist-language=python +*.py linguist-language=python +*.c linguist-language=python diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..d9f0a79 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,41 @@ +# This is a basic workflow to help you get started with Actions + +name: sync code to gitee + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +# on: +# push: +# branches: [ master ] +# pull_request: +# branches: [ master ] +on: [push, pull_request] + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + sync_gitee: + name: sync repo to gitee + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - name: checkout code from github + uses: actions/checkout@v2 + + # Runs a set of commands using the runners shell + - name: sync shell cmd + run: | + GITEE_GIT_ADDR="git@gitee.com:Sipeed/maixpy-v1_scripts.git" + git fetch --unshallow + SSHPATH="$HOME/.ssh" + rm -rf "$SSHPATH" + mkdir -p "$SSHPATH" + echo "${{ secrets.GITEE_SYNC_ACCESSS_KEY }}" > "$SSHPATH/id_rsa" + chmod 600 "$SSHPATH/id_rsa" + sudo sh -c "echo StrictHostKeyChecking no >>/etc/ssh/ssh_config" + git remote add upstream $GITEE_GIT_ADDR + git push upstream --all --force + diff --git a/README.md b/README.md index 4761882..147ec86 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -MaixPy Scripts +[MaixPy Scripts](https://github.com/sipeed/MaixPy_scripts) ==== @@ -10,31 +10,35 @@ Doc of MaixPy: [maixpy.sipeed.com](https://maixpy.sipeed.com) | directory | description | | --------- | ----------- | -| application | applications integraged to firmware | +| application | Some complex applications | | basic | basic micropython usage | | board | run python code, config your sipeed hardware | -| demo | more demo, applications, Compared to the single routines in other folders, the routines inside may be more complicated | | hardware | hardware API usage demo | | machine_vision | demo for vision related, including machine vision and AI processing related | | modules | external modules | -| multimedia | normal multimedia processing, audio video etc. | +| multimedia | normal multimedia processing, audio video game etc. | | network | network related | -| tools_on_PC | some tools for maxipy running on PC, not for maixpy | + +------------------------------- + +运行在 [MaixPy](https://github.com/sipeed/MaixPy) 上的脚本,玩得开心~ + +MaixPy 文档: [maixpy.sipeed.com](https://maixpy.sipeed.com) + +另外,国内也可以在[gitee](https://gitee.com/Sipeed/maixpy_scripts)上查看,会实时同步, 对脚本有疑问请到[github](https://github.com/sipeed/MaixPy_scripts/issues)搜索问题或者提问, MaixPy 固件相关问题请到[MaixPy issue](https://github.com/sipeed/MaixPy_scripts/issues)提问 + ## 目录结构 | 目录 | 描述 | | --------- | ----------- | -| application | 内置到固件中的应用 | +| application | 一些复杂的应用 | | basic | 基本的 micropython 使用 | | board | 运行 Python 代码,配置你的 sipeed 硬件 | -| demo | 更多的例程,像较与其它文件夹中的单一的功能示例,这里面的可能相对复杂一点 | | hardware | 硬件 API 使用例程 | | machine_vision | 视觉处理相关,包括机器视觉以及AI处理 | | modules | 外部外设模块使用, 比如 Grove 模块, sp-mod 模块 | -| multimedia | 普通的多媒体功能,比如音视频播放等 | +| multimedia | 普通的多媒体功能,比如音频、视频、GUI、游戏等 | | network | 网络相关例程 | -| tools_on_PC | 在电脑端使用的工具,注意不能在 maixpy 上运行 | - diff --git a/demo/camera/README.md b/application/camera/README.md similarity index 100% rename from demo/camera/README.md rename to application/camera/README.md diff --git a/demo/camera/cube_camera_shutter.py b/application/camera/cube_camera_shutter.py similarity index 100% rename from demo/camera/cube_camera_shutter.py rename to application/camera/cube_camera_shutter.py diff --git a/demo/capture_image_tool/README.md b/application/capture_image_tool/README.md similarity index 100% rename from demo/capture_image_tool/README.md rename to application/capture_image_tool/README.md diff --git a/demo/capture_image_tool/assets/capture.jpg b/application/capture_image_tool/assets/capture.jpg similarity index 100% rename from demo/capture_image_tool/assets/capture.jpg rename to application/capture_image_tool/assets/capture.jpg diff --git a/demo/capture_image_tool/boot.py b/application/capture_image_tool/boot.py similarity index 99% rename from demo/capture_image_tool/boot.py rename to application/capture_image_tool/boot.py index 370de59..f4b1980 100644 --- a/demo/capture_image_tool/boot.py +++ b/application/capture_image_tool/boot.py @@ -28,7 +28,7 @@ import image #### image size #### -set_windowing = (224, 224) # 320x240 if None +set_windowing = (224, 224) #### sensor config #### @@ -50,6 +50,8 @@ # sensor.set_vflip(True) # image vertical flip # sensor.set_auto_whitebal(False) +sensor.skip_frames() + #### lcd config #### lcd.init(type=1, freq=15000000) lcd.rotation(2) diff --git a/demo/gimbal/Gimbal.py b/application/gimbal/Gimbal.py similarity index 100% rename from demo/gimbal/Gimbal.py rename to application/gimbal/Gimbal.py diff --git a/demo/gimbal/README.md b/application/gimbal/README.md similarity index 100% rename from demo/gimbal/README.md rename to application/gimbal/README.md diff --git a/demo/gimbal/gimbal.mp4 b/application/gimbal/gimbal.mp4 similarity index 100% rename from demo/gimbal/gimbal.mp4 rename to application/gimbal/gimbal.mp4 diff --git a/demo/gimbal/maixpy_gimbal.png b/application/gimbal/maixpy_gimbal.png similarity index 100% rename from demo/gimbal/maixpy_gimbal.png rename to application/gimbal/maixpy_gimbal.png diff --git a/application/nes_emulator.py b/application/nes_emulator.py deleted file mode 100644 index e54dd9f..0000000 --- a/application/nes_emulator.py +++ /dev/null @@ -1,19 +0,0 @@ -import nes, lcd -from Maix import GPIO -from fpioa_manager import fm - -# AUDIO_PA_EN_PIN = None # Bit Dock and old MaixGo -AUDIO_PA_EN_PIN = 32 # Maix Go(version 2.20) -# AUDIO_PA_EN_PIN = 2 # Maixduino - -# open audio PA -if AUDIO_PA_EN_PIN: - fm.register(AUDIO_PA_EN_PIN, fm.fpioa.GPIO1, force=True) - wifi_en=GPIO(GPIO.GPIO1, GPIO.OUT) - wifi_en.value(1) - - -lcd.init(freq=15000000) -nes.init(nes.KEYBOARD) -nes.run("/sd/mario.nes") - diff --git a/application/uartTrans/README.md b/application/uartTrans/README.md new file mode 100644 index 0000000..a4770e4 --- /dev/null +++ b/application/uartTrans/README.md @@ -0,0 +1,293 @@ +# UartTrans + +自定义串口传输数据格式, 可用来传输指令(接收到指令执行用户注册的回调函数)或数据, 采用 crc16 校验 + +## 协议详情 + +| 2Byte | 1Byte | 2Byte | nByte | 2Byte | 2Byte | +| :---- | :----------- | :------- | :---- | :------ | :---- | +| 起始 | 指令或者数据 | 数据数量 | 数据 | CRC校验 | 结束 | + +* 起始: 0xaaff + +* 数据类型: 1. 指令 0. 数据 + +* 数据数量: 16bit + +* CRC16校验: (H) + +* 结束: 0xddff(H) + +## 快速开始 + +* 导入模块 + +```python +import UartTrans # import +``` + +* 创建 UartTrans + +```python +fm.register(22, fm.fpioa.UART1_TX, force=True) +fm.register(21, fm.fpioa.UART1_RX, force=True) +uart1 = UART(UART.UART1, 115200, 8, 1, 0, timeout=1000, read_buf_len=4096) +uart_t = UartTrans(uart1) +``` + +* 自定义函数并为其注册指令 + +```python +def cus_cmd(uart, s): + print("execute cus cmd {}".format(s)) + uart.write("execute cus cmd {}".format(s)) + +uart_t.reg_cmd("cus", cus_cmd, uart1, 'hello') # 注册当接收到指令 'cus' 时执行 cus_cmd, 该函数参数为 uart1,'hello' +``` + +* 发送指令或字符串 + +```python +uart_t.write('cus', True) # send 'cus' cmd +uart_t.write('hello') # send 'hello'data +``` + +* 发送数字(`pack_num` 使用请查看[pack_num API](#pack_num)) + +```python +nums = pack_num(3.1415, 'f') + pack_num(16, 'H') + pack_num(-8, 'b') # pack num data +uart_t.write(nums) # send num 3.1415(float) 16(uint16) -8(int8) +``` + +* 接收指令或数据 + +```python +udatas = uart_t.read() +``` + +* 执行接收的指令, 返回接收到的数据 + +```python +d = uart_t.parse(udatas) +``` + +## API: UartTrans + +### 注册指令 + +注册新指令并设置回调, 若指令已存在, 则会覆盖. + +```python +reg_cmd(cmd, fun, *args): +``` + +#### 参数 + +* `cmd` 指令名, 字符串类型 +* `fun` 指令回调函数 +* `*args` 回调函数参数 + +#### 返回值 + +无 + + +### 注销指令 + +```python +unreg_cmd(cmd): +``` + +#### 参数 + +`cmd` 指令名, 字符串类型. + +#### 返回值 + +无 + +### 发送指令或数据 + +```python +write(s, is_cmd) +``` + +#### 参数 + +`s` 要发送的字符串, 打包好的数字, 指令(也是字符串), `is_cmd` 是否以指令的形式发送 + +#### 返回值 + +无 + +### 打包数字
+ +将数字打包成传输格式 + +```python +pack_num(n, fl) +``` + +#### 参数 + + * `n` 数字 + * `fl` 数字类型, uint8_t(B), int8_t(b), uint16_t(H), int16_t(h), uint32_t(I), int32_t(i), uint64_t(Q), int64_t(q), float(f), double(d), str(s) + +#### 返回值 + +打包后的数字 + +#### 示例 + +将3.1415打包成float类型后发送 + +```python +pi = uart_t.pack_num(3.1415, 'f') +uart_t.write(pi) +``` + +### 接收指令或数据 + +读取数据、指令并解析后返回 + +```python +read() +``` + +#### 返回值 + +接收到的数据或指令列表, 格式为二维列表: `[[is_cmd, data]]` is_cmd: data 是否为指令(1), 数据(0), data: 数据或指令本身. +未接收到数据则为空列表 + +### 解析数据 + +将 read 得到的数据进行解析, 若为指令, 指令已注册则立即执行指令对应回调函数, 不存在将打印提醒信息, 若为数据, 将数据存储在列表中返回 + +```python +parse(udatas) +``` + +#### 参数 +`udatas` read 得到的数据 + +#### 返回值 + +列表, 解析后的数据列表 + +#### 示例 + +读取数据、指令并解析 + +```python +udatas = uart_t.read() +uart_t.parse(udatas) +``` +## 格式示例 + +1. 字符串 `aaaaaaaaaaaaaaaaaaa` + +> 串口接收: DD FF 00 00 13 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 CE 3A AA FF +> +> 分析: +> +> DD FF: head +> +> 00: data type +> +> 00 13: data len +> +> 61 ... 61: data +> +> CE 3A: crc16 +> +> AA FF: end +> +> read 后数据: +> +> ```python +> [(0, b'aaaaaaaaaaaaaaaaaaa')] # type: data +> ``` +> +> parse 后数据: +> +> ```python +> ['aaaaaaaaaaaaaaaaaaa'] +> ``` + +2. 数字 `3.1415, 16, -8` + +> 串口接收到: DD FF 00 00 0A 66 40 49 0E 56 48 00 10 62 F8 4C E0 AA FF +> +> 分析: +> +> DD FF: head +> +> 00: data type +> +> 0A: data len +> +> 66: 'f' float +> +> 40 49 0e 56: 3.1415 +> +> 48: 'H' uint16_t +> +> 00 10: 16 +> +> 62: 'b' int8_t +> +> F8: -8 +> +> 4C E0: crc16 +> +> AA FF: end +> +> read 后数据: +> +> ```python +> [(0, b'f@I\x0eVH\x00\x10b\xf8')] # type: data +> ``` +> +> parse 后数据: +> +> ```python +> [[3.1415, 16, -8]] +> ``` + +3. 指令 `cus` + +> 串口接收到: DD FF 01 00 03 63 75 73 E6 AB AA FF +> +> 分析: +> +> DD FF: head +> +> 00: data type +> +> 0A: data len +> +> 66: 'f' float +> +> 40 49 0e 56: 3.1415 +> +> 48: 'H' uint16_t +> +> 00 10: 16 +> +> 62: 'b' int8_t +> +> F8: -8 +> +> 4C E0: crc16 +> +> AA DD: end +> +> read 后数据: +> +> ```python +> [(1, b'cus')] # type: cmd +> ``` +> +> parse 后数据: +> +> 该条数据为指令类型, parse直接执行该指令回调函数 diff --git a/application/uartTrans/demo_cmd.py b/application/uartTrans/demo_cmd.py new file mode 100644 index 0000000..5895021 --- /dev/null +++ b/application/uartTrans/demo_cmd.py @@ -0,0 +1,51 @@ +# 指令使用例程 +from fpioa_manager import fm +import time +from machine import UART +import ustruct +from uart_protocol import UartTrans + +def cus_cmd(uart, str): + print("execute cus cmd {}".format(str)) + uart.write("execute cus cmd {}".format(str)) + +# read cmd from uart and execute cmd fun +if __name__ == "__main__": + fm.register(22, fm.fpioa.UART1_TX, force=True) + fm.register(21, fm.fpioa.UART1_RX, force=True) + + uart1 = UART(UART.UART1, 115200, 8, 1, 0, timeout=1000, read_buf_len=4096) + + uart_t = UartTrans(uart1) + + # pack cus cmd and send + print("send the packed 'cus' cmd to uart1") + uart_t.write('cus', 1) + + # register cus cmd + uart_t.reg_cmd("cus", cus_cmd, uart1, "cus1") + + # start to parse the receive cmd + while True: + udatas = uart_t.read() + if udatas: + print(udatas) + uart_t.parse(udatas) + time.sleep_ms(100) + +'''output +pc send: +DD FF 01 00 03 63 75 73 E6 AB AA FF + +analysis: +DD FF: head +01: cmd type +00 03: cmd len +63 75 73: 'cus' +E6 AB: crc16 +AA FF: end +output: +>>> send the packed 'cus' cmd to uart1 +recv cmd: b'cus' +execute cus cmd 1 +''' diff --git a/application/uartTrans/demo_data.py b/application/uartTrans/demo_data.py new file mode 100644 index 0000000..dd71314 --- /dev/null +++ b/application/uartTrans/demo_data.py @@ -0,0 +1,62 @@ +# 收发数据例程 +from fpioa_manager import fm +import time +from machine import UART +import ustruct +from uart_protocol import UartTrans + +# read cmd from uart and execute cmd fun +if __name__ == "__main__": + fm.register(22, fm.fpioa.UART1_TX, force=True) + fm.register(21, fm.fpioa.UART1_RX, force=True) + uart1 = UART(UART.UART1, 115200, 8, 1, 0, timeout=1000, read_buf_len=4096) + uart_t = UartTrans(uart1) + + # pack nums dat and send + print("send the packed nums data to uart1") + nums = uart_t.pack_num(3.1415, 'f') + uart_t.pack_num(16, 'H') + uart_t.pack_num(-8, 'b') + uart_t.write(nums) + uart_t.write("aaaaaaaaaaaaaaaaaaa") + + # start to parse the receive cmd + while True: + udatas = uart_t.read() + d = uart_t.parse(udatas) + if d: + print(d) + +# send and reveive string +'''log +pc send: DD FF 00 00 13 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 CE 3A AA FF + +analysis: +DD FF: head +00: data type +00 13: data len +61 ... 61: data +CE 3A: crc16 +AA FF: end + +output: +['aaaaaaaaaaaaaaaaaaa'] + +pc send: +DD FF 00 00 0A 66 40 49 0E 56 48 00 10 62 F8 4C E0 AA FF + +analysis: +DD FF: head +00: data type +0A: data len +66: 'f' float +40 49 0e 56: 3.1415 +48: 'H' uint16_t +00 10: 16 +62: 'b' int8_t +f8: -8 +4c e0: crc16 +aa ff: end + +output: +>>> send the packed nums data to uart1 +[3.1415, 16, -8] +''' \ No newline at end of file diff --git a/application/uartTrans/demo_dual.py b/application/uartTrans/demo_dual.py new file mode 100644 index 0000000..3782fc0 --- /dev/null +++ b/application/uartTrans/demo_dual.py @@ -0,0 +1,59 @@ +# 同时开启两个 uartTrans 例程 +from fpioa_manager import fm +import time +from machine import UART +import ustruct +from uart_protocol import UartTrans + +def cus_cmd(uart, str): + print("execute cus cmd {}".format(str)) + uart.write("execute cus cmd {}".format(str)) + +# read cmd from uart and execute cmd fun +if __name__ == "__main__": + fm.register(22, fm.fpioa.UART1_TX, force=True) + fm.register(21, fm.fpioa.UART1_RX, force=True) + + fm.register(24, fm.fpioa.UART2_TX, force=True) + fm.register(23, fm.fpioa.UART2_RX, force=True) + + uart1 = UART(UART.UART1, 115200, 8, 1, 0, timeout=1000, read_buf_len=4096) + uart2 = UART(UART.UART2, 115200, 8, 1, 0, timeout=1000, read_buf_len=4096) + + uart_TA = UartTrans(uart1) + uart_TB = UartTrans(uart2) + + # pack cus cmd and send + print("send the packed 'cus' cmd to uart1") + uart_TA.write('cus', 1) + + # register cus cmd + uart_TA.reg_cmd("cus", cus_cmd, uart1, "cus1") + uart_TB.reg_cmd("cus", cus_cmd, uart2, "cus2") + + # start to parse the receive cmd + while True: + uart_TA.parse(uart_TA.read()) + uart_TB.parse(uart_TB.read()) + time.sleep_ms(100) + +'''output +pc send: +DD FF 01 00 03 63 75 73 E6 AB AA FF + +analysis: +DD FF: head +01: cmd type +00 03: cmd len +63 75 73: 'cus' +E6 AB: crc16 +AA FF: end +output: +>>> send the packed 'cus' cmd to uart1 +recv cmd: b'cus' +execute cus cmd 1 +''' + +'''packed data: cmd: b'cus' + +''' \ No newline at end of file diff --git a/application/uartTrans/uart_protocol.py b/application/uartTrans/uart_protocol.py new file mode 100644 index 0000000..4a80f45 --- /dev/null +++ b/application/uartTrans/uart_protocol.py @@ -0,0 +1,176 @@ +import ustruct + +class UartTrans: + def __init__(self, uart): + self.uart = uart + self.orders = {} + self.args = {} + + CRC16_TABLE = ( + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, + 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, + 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, + 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, + 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, + 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, + 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, + 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, + 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, + 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, + 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, + 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, + 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, + 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, + 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, + 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, + 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, + 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, + 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, + 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, + 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, + 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, + 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, + 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, + 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, + 0x4100, 0x81C1, 0x8081, 0x4040) + + def crc16(self, data): + crc = 0xFFFF + for char in data: + crc = (crc >> 8) ^ self.CRC16_TABLE[((crc) ^ char) & 0xFF] + crc = ustruct.pack('HBH', data[i:i+5]) + if(head == 0xddff): # check head + try: + fmt = '>'+str(len)+'sHH' + (s, crc, end) = ustruct.unpack( + fmt, data[i+5:]) + if s != None: + crc_check = self.crc16(s) + if crc == crc_check: + ret.append((is_cmd, s)) + else: + print("receive crc check failed: ", data) + continue + except: + continue + except: + continue + return ret + + def read(self): + read_data = self.uart.read() + if read_data: + udatas = self.unpack_data(read_data, len(read_data)) + return udatas + + def write(self, s, is_cmd = 0): + s = self.pack_data(s, is_cmd) + return self.uart.write(s) + + # execute cmd + # cmd: string + def exec_cmd(self, cmd): + hcmd = hash(cmd) + try: + args = self.args[hcmd] + try: + self.orders[hcmd](*args) # execute cmd fun + except: + print("can't find cmd: ", cmd) + except: + try: + self.orders[hcmd]() # execute cmd fun + except: + print("can't find cmd: ", cmd) + + def bytes_to_nums(self, b): + ret = [] + i = 0 + while i < len(b): + try: + t = ustruct.unpack('>s', b[i:i+1]) # type + t = t[0].decode('utf-8') + fmt = '>' + t + try: + num = ustruct.unpack(fmt, b[i+1:]) + ret.append(num[0]) + i = i + 1 + ustruct.calcsize(str(t)) + except: + i = i + 1 + except: + i = i + 1 + return ret + + # fl: uint8_t(B),int8_t(b), uint16_t(H), int16_t(h), uint32_t(I), int32_t(i), double(d), str(s) + def pack_num(self, n, fl): + return ustruct.pack(">s"+fl,fl,n) + + # read data, parse to cmd and execute + def parse(self, udatas): + ret = [] + if udatas: + for udata in udatas: + is_cmd = udata[0] + if udata[0]: # cmd + self.exec_cmd(udata[1]) + else: # data + nums = self.bytes_to_nums(udata[1]) + if len(nums) > 0: + ret.append(nums) # is nums + try: + s = udata[1].decode('utf-8') # is string + ret.append(s) + except: + pass + return ret \ No newline at end of file diff --git a/basic/demo_crc16.py b/basic/demo_crc16.py new file mode 100644 index 0000000..5470237 --- /dev/null +++ b/basic/demo_crc16.py @@ -0,0 +1,93 @@ +CRC_LENGTH = 0x02 + +CRC16_TABLE = ( + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, + 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, + 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, + 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, + 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, + 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, + 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, + 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, + 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, + 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, + 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, + 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, + 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, + 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, + 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, + 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, + 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, + 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, + 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, + 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, + 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, + 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, + 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, + 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, + 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, + 0x4100, 0x81C1, 0x8081, 0x4040) +""" Code to generate the CRC-16 lookup table: +def generate_crc16_table(): + crc_table = [] + for byte in range(256): + crc = 0x0000 + for _ in range(8): + if (byte ^ crc) & 0x0001: + crc = (crc >> 1) ^ 0xa001 + else: + crc >>= 1 + byte >>= 1 + crc_table.append(crc) + return crc_table +""" + +import struct + + +def crc16(data): + crc = 0xFFFF + for char in data: + crc = (crc >> 8) ^ CRC16_TABLE[((crc) ^ char) & 0xFF] + return struct.pack('= (self.level or _level) + + def log(self, level, msg, *args): + if self.isEnabledFor(level): + levelname = self._level_str(level) + if args: + msg = msg % args + if self.handlers: + d = self.record.__dict__ + d["levelname"] = levelname + d["levelno"] = level + d["message"] = msg + d["name"] = self.name + for h in self.handlers: + h.emit(self.record) + else: + print(levelname, ":", self.name, ":", msg, sep="", file=_stream) + + def debug(self, msg, *args): + self.log(DEBUG, msg, *args) + + def info(self, msg, *args): + self.log(INFO, msg, *args) + + def warning(self, msg, *args): + self.log(WARNING, msg, *args) + + def error(self, msg, *args): + self.log(ERROR, msg, *args) + + def critical(self, msg, *args): + self.log(CRITICAL, msg, *args) + + def exc(self, e, msg, *args): + self.log(ERROR, msg, *args) + sys.print_exception(e, _stream) + + def addHandler(self, hndlr): + self.handlers.append(hndlr) + +_level = INFO +_loggers = {} + +def getLogger(name="root"): + if name in _loggers: + return _loggers[name] + l = Logger(name) + _loggers[name] = l + return l + +def info(msg, *args): + getLogger().info(msg, *args) + +def debug(msg, *args): + getLogger().debug(msg, *args) + +def basicConfig(level=INFO, filename=None, stream=None, format=None): + global _level, _stream + _level = level + if stream: + _stream = stream + if filename is not None: + print("basicConfig: filename arg is not supported") + if format is not None: + print("basicConfig: format arg is not supported") + +if __name__ == "__main__": + + basicConfig(level=INFO) + log = getLogger("test") + log.debug("Test message: %d(%s)", 100, "foobar") + log.info("Test message2: %d(%s)", 100, "foobar") + log.warning("Test message3: %d(%s)") + log.error("Test message4") + log.critical("Test message5") + info("Test message6") + + try: + 1/0 + except Exception as e: + log.exc(e, "Some trouble (%s)", "expected") + + class MyHandler(Handler): + def emit(self, record): + print("levelname=%(levelname)s name=%(name)s message=%(message)s" % record.__dict__) + + getLogger().addHandler(MyHandler()) + info("Test message7") diff --git a/basic/demo_repl_to_read.py b/basic/demo_repl_to_read.py new file mode 100644 index 0000000..80d1012 --- /dev/null +++ b/basic/demo_repl_to_read.py @@ -0,0 +1,8 @@ + +import sys + +while True: + tmp = sys.stdin.read(1) + if tmp == 'e': + break + sys.stdout.write(tmp) diff --git a/basic/demo_set_gc_heap_size.py b/basic/demo_set_gc_heap_size.py new file mode 100644 index 0000000..284ffb8 --- /dev/null +++ b/basic/demo_set_gc_heap_size.py @@ -0,0 +1,66 @@ +import machine +import Maix + +gc_mem_size = 1024*1024 + +print('config micropython gc stack 1M (1024KB) if not') +if Maix.utils.gc_heap_size() != gc_mem_size: + Maix.utils.gc_heap_size(gc_mem_size) + print('updates take effect when you reboot the system. ') + machine.reset() + +print('Current: ', Maix.utils.gc_heap_size()) + +''' + +[MAIXPY] Pll0:freq:806000000 +[MAIXPY] Pll1:freq:398666666 +[MAIXPY] Pll2:freq:45066666 +[MAIXPY] cpu:freq:403000000 +[MAIXPY] kpu:freq:398666666 +[MAIXPY] Flash:0xef:0x17 +[MaixPy] gc heap=0x800cbc50-0x8014bc50(524288) +[MaixPy] init end + + __ __ _____ __ __ _____ __ __ +| \/ | /\ |_ _| \ \ / / | __ \ \ \ / / +| \ / | / \ | | \ V / | |__) | \ \_/ / +| |\/| | / /\ \ | | > < | ___/ \ / +| | | | / ____ \ _| |_ / . \ | | | | +|_| |_| /_/ \_\ |_____| /_/ \_\ |_| |_| + +Official Site : https://www.sipeed.com +Wiki : https://maixpy.sipeed.com + +MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 +Type "help()" for more information. +>>> +>>> +>>> +raw REPL; CTRL-B to exit +>OK +config micropython gc stack 1M (1024KB) if not +updates take effect when you reboot the s +[MAIXPY] Pll0:freq:806000000 +[MAIXPY] Pll1:freq:398666666 +[MAIXPY] Pll2:freq:45066666 +[MAIXPY] cpu:freq:403000000 +[MAIXPY] kpu:freq:398666666 +[MAIXPY] Flash:0xef:0x17 +[MaixPy] gc heap=0x800cbc50-0x801cbc50(1048576) +[MaixPy] init end + + __ __ _____ __ __ _____ __ __ +| \/ | /\ |_ _| \ \ / / | __ \ \ \ / / +| \ / | / \ | | \ V / | |__) | \ \_/ / +| |\/| | / /\ \ | | > < | ___/ \ / +| | | | / ____ \ _| |_ / . \ | | | | +|_| |_| /_/ \_\ |_____| /_/ \_\ |_| |_| + +Official Site : https://www.sipeed.com +Wiki : https://maixpy.sipeed.com + +MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 +Type "help()" for more information. +>>> +''' diff --git a/basic/demo_sha256.py b/basic/demo_sha256.py new file mode 100644 index 0000000..cbbf42e --- /dev/null +++ b/basic/demo_sha256.py @@ -0,0 +1,19 @@ +import hashlib + +a = bytes([0]*65) +b = hashlib.sha256() +b.update(a) +b.update(a) +c = b.digest() +print(c) +if c != b"\xe5Z\\'sj\x87a\xc8\xe9j\xce\xc0r\x10#%\xe0\x8c\xb2\xd0\xdb\xb4\xd4p,\xfe8\xf8\xab\x07\t": + raise(Exception("error! {}".format(c))) + +a = bytes([0]*1024) +b = hashlib.sha256(a) +c = b.digest() +print(c) +if c != b'_p\xbf\x18\xa0\x86\x00p\x16\xe9H\xb0J\xed;\x82\x10:6\xbe\xa4\x17U\xb6\xcd\xdf\xaf\x10\xac\xe3\xc6\xef': + raise(Exception("error! {}".format(c))) + +print(c == b.digest()) # False here diff --git a/basic/hello.py b/basic/demo_sys_info.py similarity index 100% rename from basic/hello.py rename to basic/demo_sys_info.py diff --git a/basic/demo_time.py b/basic/demo_time.py new file mode 100644 index 0000000..71cd34e --- /dev/null +++ b/basic/demo_time.py @@ -0,0 +1,29 @@ +import time +import machine + +print(time.time()) +t1 = time.localtime(546450051) +print('t1', t1) +t2 = time.mktime(t1) +print('t2', t2) +print(time.time()) +time.set_time(t1) +print(time.time()) +time.sleep(1) +print(time.localtime(time.time())) + +''' +raw REPL; CTRL-B to exit +>OK +74 +t1 (2017, 4, 25, 15, 40, 51, 1, 115) +t2 546450051 +546450065 +546450051 +(2017, 4, 25, 15, 40, 52, 1, 115) +> +MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 +Type "help()" for more information. +>>> +>>> +''' diff --git a/basic/demo_view_mem.py b/basic/demo_view_mem.py new file mode 100644 index 0000000..4f1e957 --- /dev/null +++ b/basic/demo_view_mem.py @@ -0,0 +1,19 @@ +import gc + +print(gc.mem_free() / 1024) # stack mem + +import Maix + +print(Maix.utils.heap_free() / 1024) # heap mem + +''' +>>> +raw REPL; CTRL-B to exit +>OK +352.0937 +4640.0 +> +MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 +Type "help()" for more information. +>>> +''' \ No newline at end of file diff --git a/basic/demo_yield.py b/basic/demo_yield.py new file mode 100644 index 0000000..24883e6 --- /dev/null +++ b/basic/demo_yield.py @@ -0,0 +1,39 @@ +def event(): + print('start yield') + # return next(task) and yield next(task.send('set_two')) + one = yield 'get_one' + assert(one == 'set_two') + print(one) + yield 'get_two' # return next(task) and yield next(task.send('set_two')) + print('exit yield') + yield # yield next() to exit or raise StopIteration + + +task = event() +run_one = next(task) # need next(task) init and next(task) == task.send(None) +# so next(task) => yield 'get_one' => run_one = 'get_one' +assert(run_one == 'get_one') +run_two = task.send('set_two') +assert(run_two == 'get_two') +print('run : ', run_one, ' and ', run_two) + +try: + next(task) + print('run end') + next(task) # will raise StopIteration +except Exception as e: + print('yield StopIteration') + +if __name__ == '__main__': + + def task(): + while True: + print('hello') + yield + + tmp = task() + while True: + next(tmp) + + while True: + print('hello') diff --git a/basic/demo_yield_task.py b/basic/demo_yield_task.py new file mode 100644 index 0000000..d300dc5 --- /dev/null +++ b/basic/demo_yield_task.py @@ -0,0 +1,62 @@ +class Task: + + def __init__(self, event=(lambda: print('task running'))): + self.event = event + self.cb = self.pre() + next(self.cb) + print('task init') + + def pre(self): + print('task start') + flag = True + while flag is True: + flag = yield flag + self.event() + print('task exit') + + def run(self, flag=True): + try: + res = self.cb.send(flag) + return res + except StopIteration as e: + return False + + +if __name__ == "__main__": + tmp = Task() + + assert(tmp.run()) + assert(tmp.run()) + assert(False == tmp.run(False)) + + print(tmp.run()) + print(tmp.run(False)) + + class music: + + def __init__(self): + self.task = Task(self.pre) + self.args = None + print('music init') + + def pre(self): + print('pre ', self.args) + + def play(self, size=10): + self.args = list(range(size)) + print(self.task.run()) + + def stop(self): + print(self.task.run(False)) + self.__init__() + + def loop(self): + self.alive = False + while self.alive: + self.play() + stop() + + tmp = music() + tmp.play() + tmp.stop() + tmp.play() diff --git a/board/config_maix_amigo.py b/board/config_maix_amigo.py index 1ee71b8..2b6a6c2 100644 --- a/board/config_maix_amigo.py +++ b/board/config_maix_amigo.py @@ -47,22 +47,22 @@ # config sensor try: - os.remove('/flash/boot.py') + os.remove('boot.py') except: pass -with open('/flash/boot.py', 'wb') as f: +with open('boot.py', 'wb') as f: cfg_sensor = b'from machine import I2C\naxp173 = I2C(I2C.I2C0, freq=100000, scl=24, sda=27)\naxp173.writeto_mem(0x34, 0x27, 0x20)\naxp173.writeto_mem(0x34, 0x28, 0x0C)\naxp173.writeto_mem(0x34, 0x36, 0xCC, mem_size=8)' f.write(cfg_sensor) del cfg_sensor try: - with open('/flash/config.json', 'rb') as f: + with open('config.json', 'rb') as f: tmp = json.loads(f.read()) print(tmp) if tmp["type"] != config["type"]: raise Exception('config.json no exist') except Exception as e: - with open('/flash/config.json', "w") as f: + with open('config.json', "w") as f: f.write(cfg) import machine machine.reset() diff --git a/board/config_maix_amigo_ips.py b/board/config_maix_amigo_ips.py new file mode 100644 index 0000000..dcd1ec5 --- /dev/null +++ b/board/config_maix_amigo_ips.py @@ -0,0 +1,68 @@ + +import json + +config = { + "type": "amigo", + "lcd": { + "height": 320, + "width": 480, + "invert": 1, + "dir": 40, + "lcd_type": 2 + }, + "sdcard":{ + "sclk":11, + "mosi":10, + "miso":6, + "cs":26 + }, + "board_info": { + 'BOOT_KEY': 23, + 'LED_R': 14, + 'LED_G': 15, + 'LED_B': 17, + 'LED_W': 32, + 'BACK': 23, + 'ENTER': 16, + 'NEXT': 20, + 'WIFI_TX': 6, + 'WIFI_RX': 7, + 'WIFI_EN': 8, + 'I2S0_MCLK': 13, + 'I2S0_SCLK': 21, + 'I2S0_WS': 18, + 'I2S0_IN_D0': 35, + 'I2S0_OUT_D2': 34, + 'I2C_SDA': 27, + 'I2C_SCL': 24, + 'SPI_SCLK': 11, + 'SPI_MOSI': 10, + 'SPI_MISO': 6, + 'SPI_CS': 12, + } +} + +cfg = json.dumps(config) +print(cfg) + +# config sensor +try: + os.remove('/flash/boot.py') +except: + pass +with open('/flash/boot.py', 'wb') as f: + cfg_sensor = b'import lcd\nlcd.clear((99, 99, 99))\nlcd.register(0xD1, 0x00)\nlcd.init()\nfrom machine import I2C\naxp173 = I2C(I2C.I2C0, freq=100000, scl=24, sda=27)\naxp173.writeto_mem(0x34, 0x27, 0x20)\naxp173.writeto_mem(0x34, 0x28, 0x0C)\naxp173.writeto_mem(0x34, 0x36, 0xCC, mem_size=8)' + f.write(cfg_sensor) + del cfg_sensor + +try: + with open('/flash/config.json', 'rb') as f: + tmp = json.loads(f.read()) + print(tmp) + if tmp["type"] != config["type"]: + raise Exception('config.json no exist') +except Exception as e: + with open('/flash/config.json', "w") as f: + f.write(cfg) + import machine + machine.reset() diff --git a/board/config_maix_cube.py b/board/config_maix_cube.py index 623e183..ae52ae0 100644 --- a/board/config_maix_cube.py +++ b/board/config_maix_cube.py @@ -1,50 +1,60 @@ import json config = { - "type": "cube", - "lcd": { - "height": 240, - "width": 240, - "invert": 1, - "dir": 96 - }, - "board_info": { - 'BOOT_KEY': 16, - 'LED_R': 13, - 'LED_G': 12, - 'LED_B': 14, - 'LED_W': 32, - 'BACK': 11, - 'ENTER': 10, - 'NEXT': 16, - 'WIFI_TX': 6, - 'WIFI_RX': 7, - 'WIFI_EN': 8, - 'I2S0_MCLK': 19, - 'I2S0_SCLK': 35, - 'I2S0_WS': 33, - 'I2S0_IN_D0': 34, - 'I2S0_OUT_D2': 18, - 'I2C_SDA': 31, - 'I2C_SCL': 30, - 'SPI_SCLK': 21, - 'SPI_MOSI': 8, - 'SPI_MISO': 15, - 'SPI_CS': 20, - } + "type": "cube", + "lcd": { + "height": 240, + "width": 240, + "invert": 1, + "dir": 96 + }, + "board_info": { + 'BOOT_KEY': 16, + 'LED_R': 13, + 'LED_G': 12, + 'LED_B': 14, + 'LED_W': 32, + 'BACK': 11, + 'ENTER': 10, + 'NEXT': 16, + 'WIFI_TX': 6, + 'WIFI_RX': 7, + 'WIFI_EN': 8, + 'I2S0_MCLK': 19, + 'I2S0_SCLK': 35, + 'I2S0_WS': 33, + 'I2S0_IN_D0': 34, + 'I2S0_OUT_D2': 18, + 'I2C_SDA': 31, + 'I2C_SCL': 30, + 'SPI_SCLK': 21, + 'SPI_MOSI': 8, + 'SPI_MISO': 15, + 'SPI_CS': 20, + } } cfg = json.dumps(config) print(cfg) +# config lcd back_light try: - with open('/flash/config.json', 'rb') as f: - tmp = json.loads(f.read()) - print(tmp) - if tmp["type"] != config["type"]: - raise Exception('config.json no exist') + os.remove('/flash/boot.py') +except: + pass +with open('/flash/boot.py', 'wb') as f: + cfg_sensor = b'from fpioa_manager import fm\nfrom Maix import GPIO\nfm.register(17, fm.fpioa.GPIOHS28)\nlcd_en = GPIO(GPIO.GPIOHS28, GPIO.OUT)\nlcd_en.value(0)\n' + f.write(cfg_sensor) + del cfg_sensor + +try: + with open('/flash/config.json', 'rb') as f: + tmp = json.loads(f.read()) + print(tmp) + if tmp["type"] != config["type"]: + raise Exception('config.json no exist') except Exception as e: - with open('/flash/config.json', "w") as f: - f.write(cfg) - import machine - machine.reset() + with open('/flash/config.json', "w") as f: + f.write(cfg) + import machine + machine.reset() diff --git a/board/config_maix_duino.py b/board/config_maix_duino.py index c5dcd22..0bf9b66 100644 --- a/board/config_maix_duino.py +++ b/board/config_maix_duino.py @@ -29,7 +29,7 @@ 'PIN4':23, 'PIN5':24, 'PIN6':32, - 'PIN7':16, + 'PIN7':15, 'PIN8':14, 'PIN9':13, 'PIN10':12, diff --git a/demo/README.md b/demo/README.md deleted file mode 100644 index f727c24..0000000 --- a/demo/README.md +++ /dev/null @@ -1,7 +0,0 @@ -demo -===== - -some uage examles, PR welcom -MUST create a folder and MUST contain `README.md` in every demo folder - - diff --git a/hardware/demo_binocular.py b/hardware/demo_binocular.py index f04a5ce..88b0543 100644 --- a/hardware/demo_binocular.py +++ b/hardware/demo_binocular.py @@ -1,3 +1,4 @@ +# It need binocular sensor !!!!! import sensor import image diff --git a/hardware/demo_camera.py b/hardware/demo_camera.py index 31d4caa..2851220 100644 --- a/hardware/demo_camera.py +++ b/hardware/demo_camera.py @@ -1,6 +1,9 @@ import sensor, lcd -sensor.reset() +try: + sensor.reset() +except Exception as e: + raise Exception("sensor reset fail, please check hardware connection, or hardware damaged! err: {}".format(e)) sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) # sensor.set_hmirror(1) # cube & amigo diff --git a/hardware/demo_fft_waterfall.py b/hardware/demo_fft_waterfall.py new file mode 100644 index 0000000..eb82809 --- /dev/null +++ b/hardware/demo_fft_waterfall.py @@ -0,0 +1,38 @@ +from Maix import GPIO, I2S, FFT +import image, lcd, math +from fpioa_manager import fm +import KPU as kpu + +sample_rate = 11025 +sample_points = 1024 +fft_points = 512 +hist_x_num = 128 + +lcd.init() +# close WiFi +fm.register(8, fm.fpioa.GPIO0) +wifi_en=GPIO(GPIO.GPIO0,GPIO.OUT) +wifi_en.value(0) +fm.register(20,fm.fpioa.I2S0_IN_D0) +fm.register(30,fm.fpioa.I2S0_WS) # 30 on dock/bit Board +fm.register(32,fm.fpioa.I2S0_SCLK) # 32 on dock/bit Board + +rx = I2S(I2S.DEVICE_0) +rx.channel_config(rx.CHANNEL_0, rx.RECEIVER, align_mode = I2S.STANDARD_MODE) +rx.set_sample_rate(sample_rate) +img = image.Image(size=(128,128)) +img=img.to_grayscale() + +while True: + audio = rx.record(sample_points) + fft_res = FFT.run(audio.to_bytes(),fft_points) + fft_amp = FFT.amplitude(fft_res) + img_tmp = img.cut(0,0,128,127) + img.draw_image(img_tmp, 0,1) + for i in range(hist_x_num): + img[i] = fft_amp[i] + del(img_tmp) + imgc = img.to_rainbow(1) + lcd.display(imgc) + del(imgc) + fft_amp.clear() \ No newline at end of file diff --git a/hardware/demo_i2c.py b/hardware/demo_i2c.py index 33050cf..7492b8f 100644 --- a/hardware/demo_i2c.py +++ b/hardware/demo_i2c.py @@ -1,8 +1,11 @@ from machine import I2C +from fpioa_manager import fm # i2c = I2C(I2C.I2C0, freq=100000, scl=28, sda=29) # hardware i2c i2c = I2C(I2C.I2C3, freq=100000, scl=28, sda=29) # software i2c - +#i2c = I2C(I2C.I2C_SOFT, freq=100000, scl=28, sda=29, + #gscl = fm.fpioa.GPIOHS1, gsda = fm.fpioa.GPIOHS2) # software i2c for the latest firmware + devices = i2c.scan() print(devices) diff --git a/hardware/demo_i2s.py b/hardware/demo_i2s.py new file mode 100644 index 0000000..714cf68 --- /dev/null +++ b/hardware/demo_i2s.py @@ -0,0 +1,26 @@ +from Maix import GPIO, I2S +import image, lcd, math, audio +from fpioa_manager import fm + +sample_rate = 22050 +sample_points = 1024 + +rx = I2S(I2S.DEVICE_0) +rx.channel_config(I2S.CHANNEL_0, rx.RECEIVER, resolution = I2S.RESOLUTION_16_BIT, cycles = I2S.SCLK_CYCLES_32, align_mode = I2S.STANDARD_MODE) +rx.set_sample_rate(sample_rate) + +fm.fpioa.set_function(pin=20, func=fm.fpioa.I2S0_IN_D0) +fm.fpioa.set_function(pin=19, func=fm.fpioa.I2S0_WS) +fm.fpioa.set_function(pin=18, func=fm.fpioa.I2S0_SCLK) + +tx = I2S(I2S.DEVICE_2) + +tx.channel_config(I2S.CHANNEL_1, I2S.TRANSMITTER, resolution = I2S.RESOLUTION_16_BIT, cycles = I2S.SCLK_CYCLES_32, align_mode = I2S.RIGHT_JUSTIFYING_MODE) +tx.set_sample_rate(sample_rate) + +fm.fpioa.set_function(pin=34, func=fm.fpioa.I2S2_OUT_D1) +fm.fpioa.set_function(pin=35, func=fm.fpioa.I2S2_SCLK) +fm.fpioa.set_function(pin=33, func=fm.fpioa.I2S2_WS) + +while True: + tx.play(rx.record(sample_points)) diff --git a/hardware/demo_lcd.py b/hardware/demo_lcd.py index cb996be..2d3b956 100644 --- a/hardware/demo_lcd.py +++ b/hardware/demo_lcd.py @@ -1,17 +1,29 @@ -import lcd -import time -import image -bg = (236, 36, 36) -lcd.init(freq=15000000) -lcd.direction(lcd.YX_RLDU) +import lcd, time + +lcd.init() +#lcd.direction(lcd.XY_RLDU) + +#lcd.init(type=2, invert=True) # cube ips +#lcd.init(width=320, height=240, invert=True, freq=20000000) + +# see lcd datasheet (such as amigo ips) +#lcd.register(0x36, 0b01101000) # BGR2RGB Mode +#lcd.register(0x21, None) # invert=True +#lcd.register(0x20, None) # invert=False +#lcd.register(0x36, [0b01101000, ]) # invert=True + lcd.clear(lcd.RED) + +lcd.rotation(0) +lcd.draw_string(30, 30, "hello maixpy", lcd.WHITE, lcd.RED) time.sleep(1) +lcd.rotation(1) +lcd.draw_string(60, 60, "hello maixpy", lcd.WHITE, lcd.RED) +time.sleep(1) +lcd.rotation(2) +lcd.draw_string(120, 60, "hello maixpy", lcd.WHITE, lcd.RED) +time.sleep(1) +lcd.rotation(3) lcd.draw_string(120, 120, "hello maixpy", lcd.WHITE, lcd.RED) -time.sleep(2) - - -img = image.Image() -img.draw_string(60, 100, "hello maixpy", scale=2) -img.draw_rectangle((120, 120, 30, 30)) -lcd.display(img) +time.sleep(1) diff --git a/hardware/demo_lcd_800x480.py b/hardware/demo_lcd_800x480.py new file mode 100644 index 0000000..598d1fc --- /dev/null +++ b/hardware/demo_lcd_800x480.py @@ -0,0 +1,24 @@ +import time +import lcd + +lcd.init(type=5, lcd_type=3) +while True: + lcd.clear(0xff00) + lcd.rotation(0) + lcd.draw_string(30, 30, "hello maixpy", lcd.WHITE, 0xff00) + time.sleep(1) + + lcd.clear(0x00ff) + lcd.rotation(1) + lcd.draw_string(60, 60, "hello maixpy", lcd.WHITE, 0X00FF) + time.sleep(1) + + lcd.clear(0x0ff0) + lcd.rotation(2) + lcd.draw_string(120, 60, "hello maixpy", lcd.WHITE, 0x0ff0) + time.sleep(1) + + lcd.clear(0x0f0f) + lcd.rotation(3) + lcd.draw_string(120, 120, "hello maixpy", lcd.WHITE, 0x0f0f) + time.sleep(1) diff --git a/hardware/demo_mic_array.py b/hardware/demo_mic_array.py index 7281ec1..339c721 100644 --- a/hardware/demo_mic_array.py +++ b/hardware/demo_mic_array.py @@ -5,6 +5,8 @@ mic.init() #mic.init(i2s_d0=23, i2s_d1=22, i2s_d2=21, i2s_d3=20, i2s_ws=19, i2s_sclk=18, sk9822_dat=24, sk9822_clk=25) +#mic.init(i2s_d0=20, i2s_d1=21, i2s_d2=15, i2s_d3=8, i2s_ws=7, i2s_sclk=6, sk9822_dat=25, sk9822_clk=24)# for maix cube + while True: imga = mic.get_map() b = mic.get_dir(imga) diff --git a/hardware/demo_onewire_ds18x20.py b/hardware/demo_onewire_ds18x20.py new file mode 100644 index 0000000..f173cd0 --- /dev/null +++ b/hardware/demo_onewire_ds18x20.py @@ -0,0 +1,67 @@ +from fpioa_manager import * +from modules import onewire +from micropython import const +from board import board_info +import time + +class DS18X20: + _CONVERT = const(0x44) + _RD_SCRATCH = const(0xBE) + _WR_SCRATCH = const(0x4E) + _SKIP_ROM = const(0xCC) + def __init__(self, pin): + self.device = onewire(pin) + self.buf = bytearray(9) + + def scan(self): + return self.device.search(65) + + def convert_temp(self): + self.device.reset() + self.device.writebyte(_SKIP_ROM) + self.device.writebyte(_CONVERT) + + def read_scratch(self, rom): + self.device.reset() + self.convert_temp() + self.device.select(rom) + self.device.writebyte(_RD_SCRATCH) + self.buf = self.device.readbuffer(len(self.buf)) + if self.device.crc8(self.buf): + raise Exception("CRC error") + return self.buf + + def write_scratch(self, rom, buf): + self.device.reset() + self.device.select(rom) + self.device.writebyte(_WR_SCRATCH) + self.device.writebuffer(buf) + + def read_temp(self, rom): + temp = [] + for _rom in rom: + buf = self.read_scratch(_rom) + if _rom[0] == 0x10: + if buf[1]: + t = buf[0] >> 1 | 0x80 + t = -((~t + 1) & 0xFF) + else: + t = buf[0] >> 1 + temp.append(t - 0.25 + (buf[7] - buf[6]) / buf[7]) + else: + t = buf[1] << 8 | buf[0] + if t & 0x8000: # sign bit set + t = -((t ^ 0xFFFF) + 1) + temp.append(t / 16) + if len(temp) < 1: + return -1 + if len(temp) < 2: + return temp[0] + return tuple(temp) + + +fm.register(14, fm.fpioa.GPIOHS2, force=True) +ds18b20_2 = DS18X20(fm.fpioa.GPIOHS2) +while True: + print(ds18b20_2.read_temp(rom_2)) + time.sleep_ms(100) diff --git a/hardware/demo_spi.py b/hardware/demo_spi_cs.py similarity index 99% rename from hardware/demo_spi.py rename to hardware/demo_spi_cs.py index fb29be3..0804266 100644 --- a/hardware/demo_spi.py +++ b/hardware/demo_spi_cs.py @@ -1,14 +1,3 @@ -from machine import SPI - -spi1 = SPI(SPI.SPI1, mode=SPI.MODE_MASTER, baudrate=10000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=28, mosi=29, miso=30) -w = b'1234' -r = bytearray(4) -spi1.write(w) -spi1.write_readinto(w, r) -spi1.read(5, write=0x00) -spi1.readinto(r, write=0x00) - -''' import time from machine import SPI from fpioa_manager import fm @@ -32,4 +21,14 @@ cs.value(1) print(w, r) time.sleep(0.1) + +''' +from machine import SPI +spi1 = SPI(SPI.SPI1, mode=SPI.MODE_MASTER, baudrate=10000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=28, mosi=29, miso=30) +w = b'1234' +r = bytearray(4) +spi1.write(w) +spi1.write_readinto(w, r) +spi1.read(5, write=0x00) +spi1.readinto(r, write=0x00) ''' diff --git a/hardware/demo_spi_soft.py b/hardware/demo_spi_soft.py index 581dcf5..64b743e 100644 --- a/hardware/demo_spi_soft.py +++ b/hardware/demo_spi_soft.py @@ -20,4 +20,5 @@ spi.readinto(id_buf, write=0xff) work_data = id_buf cs.value(1) - print(work_data) \ No newline at end of file + print(work_data) + \ No newline at end of file diff --git a/hardware/amigo_switch_sensor.py b/hardware/demo_switch_sensor.py similarity index 100% rename from hardware/amigo_switch_sensor.py rename to hardware/demo_switch_sensor.py diff --git a/hardware/demo_timer.py b/hardware/demo_timer.py index 235d5c9..f4f1d5d 100644 --- a/hardware/demo_timer.py +++ b/hardware/demo_timer.py @@ -1,9 +1,21 @@ from machine import Timer +import time def on_timer(timer): print("time up:",timer) print("param:",timer.callback_arg()) tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_ONE_SHOT, period=3000, callback=on_timer, arg=on_timer) +# tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PERIODIC, period=1, unit=Timer.UNIT_S, callback=on_timer, arg=on_timer, start=False, priority=1, div=0) + print("period:",tim.period()) +tim.start() +time.sleep(5) +tim.stop() +time.sleep(5) +tim.restart() +time.sleep(5) +tim.stop() +del tim + diff --git a/hardware/demo_timer2.py b/hardware/demo_timer2.py deleted file mode 100644 index 029db65..0000000 --- a/hardware/demo_timer2.py +++ /dev/null @@ -1,18 +0,0 @@ -import time -from machine import Timer - -def on_timer(timer): - print("time up:",timer) - print("param:",timer.callback_arg()) - -tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PERIODIC, period=1, unit=Timer.UNIT_S, callback=on_timer, arg=on_timer, start=False, priority=1, div=0) -print("period:",tim.period()) -tim.start() -time.sleep(5) -tim.stop() -time.sleep(5) -tim.restart() -time.sleep(5) -tim.stop() -del tim - diff --git a/hardware/demo_uart_many.py b/hardware/demo_uart_many.py index 0980919..a5619ce 100644 --- a/hardware/demo_uart_many.py +++ b/hardware/demo_uart_many.py @@ -12,15 +12,14 @@ uart_A = UART(UART.UART1, 115200, 8, 0, 0, timeout=1000, read_buf_len=4096) uart_B = UART(UART.UART2, 115200, 8, 0, 0, timeout=1000, read_buf_len=4096) -write_str = 'hello world' +write_bytes = b'hello world' for i in range(20): uart_A.write(write_str) if uart_A.any(): read_data = uart_B.read() if read_data: - read_str = read_data.decode('utf-8') - print("string = ", read_str) - if read_str == write_str: + print("write_bytes = ", write_bytes) + if read_data == write_bytes: print("baudrate:115200 bits:8 parity:0 stop:0 ---check Successfully") uart_A.deinit() diff --git a/hardware/lcd_test.py b/hardware/lcd_test.py deleted file mode 100644 index d92f528..0000000 --- a/hardware/lcd_test.py +++ /dev/null @@ -1,26 +0,0 @@ -import lcd,image, time - - -lcd.init(type=1, freq=15000000) -# lcd.init(type=2, freq=20000000) -# lcd.init(type=1, width=320, height=240, invert=True, freq=20000000) - -img = image.Image(size=(240,240)) - -img.draw_rectangle(0,0,30, 240, fill=True, color=(0xff, 0xff, 0xff)) -img.draw_rectangle(30,0,30, 240, fill=True, color=(250, 232, 25)) -img.draw_rectangle(60,0,30, 240, fill=True, color=(106, 198, 218)) -img.draw_rectangle(90,0,30, 240, fill=True, color=(98, 177, 31)) -img.draw_rectangle(120,0,30, 240, fill=True, color=(180, 82, 155)) -img.draw_rectangle(150,0,30, 240, fill=True, color=(231, 47, 29)) -img.draw_rectangle(180,0,30, 240, fill=True, color=(32, 77, 158)) -img.draw_rectangle(210,0,30, 240, fill=True, color=(27, 28, 32)) - -lcd.display(img) - -count = 500 -while count > 0: - t = time.ticks_ms() - lcd.display(img) - print(time.ticks_ms() - t) - count -= 1 diff --git a/machine_vision/demo_find_face.py b/machine_vision/demo_find_face.py deleted file mode 100644 index 62bdf3a..0000000 --- a/machine_vision/demo_find_face.py +++ /dev/null @@ -1,24 +0,0 @@ -#refer to http://blog.sipeed.com/p/675.html -import sensor -import image -import lcd -import KPU as kpu - -lcd.init() -sensor.reset() -sensor.set_pixformat(sensor.RGB565) -sensor.set_framesize(sensor.QVGA) -sensor.run(1) -task = kpu.load(0x300000) # you need put model(face.kfpkg) in flash at address 0x300000 -# task = kpu.load("/sd/face.kmodel") -anchor = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437, 6.92275, 6.718375, 9.01025) -a = kpu.init_yolo2(task, 0.5, 0.3, 5, anchor) -while(True): - img = sensor.snapshot() - code = kpu.run_yolo2(task, img) - if code: - for i in code: - print(i) - a = img.draw_rectangle(i.rect()) - a = lcd.display(img) -a = kpu.deinit(task) diff --git a/machine_vision/face_find/demo_find_face.py b/machine_vision/face_find/demo_find_face.py new file mode 100644 index 0000000..1401359 --- /dev/null +++ b/machine_vision/face_find/demo_find_face.py @@ -0,0 +1,60 @@ + +import sensor, image, lcd, time +import KPU as kpu +import gc, sys + +def lcd_show_except(e): + import uio + err_str = uio.StringIO() + sys.print_exception(e, err_str) + err_str = err_str.getvalue() + img = image.Image(size=(224,224)) + img.draw_string(0, 10, err_str, scale=1, color=(0xff,0x00,0x00)) + lcd.display(img) + +def main(model_addr=0x300000, lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False): + try: + sensor.reset() + except Exception as e: + raise Exception("sensor reset fail, please check hardware connection, or hardware damaged! err: {}".format(e)) + sensor.set_pixformat(sensor.RGB565) + sensor.set_framesize(sensor.QVGA) + sensor.set_hmirror(sensor_hmirror) + sensor.set_vflip(sensor_vflip) + sensor.run(1) + + lcd.init(type=1) + lcd.rotation(lcd_rotation) + lcd.clear(lcd.WHITE) + + anchors = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437, 6.92275, 6.718375, 9.01025) + try: + task = None + task = kpu.load(model_addr) + kpu.init_yolo2(task, 0.5, 0.3, 5, anchors) # threshold:[0,1], nms_value: [0, 1] + while(True): + img = sensor.snapshot() + t = time.ticks_ms() + objects = kpu.run_yolo2(task, img) + t = time.ticks_ms() - t + if objects: + for obj in objects: + img.draw_rectangle(obj.rect()) + img.draw_string(0, 200, "t:%dms" %(t), scale=2) + lcd.display(img) + except Exception as e: + raise e + finally: + if not task is None: + kpu.deinit(task) + + +if __name__ == "__main__": + try: + main( model_addr=0x300000, lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False) + # main(model_addr="/sd/m.kmodel") + except Exception as e: + sys.print_exception(e) + lcd_show_except(e) + finally: + gc.collect() diff --git a/machine_vision/face_recognization/README.md b/machine_vision/face_recognization/README.md new file mode 100644 index 0000000..6540aa7 --- /dev/null +++ b/machine_vision/face_recognization/README.md @@ -0,0 +1,16 @@ +face recognization +============ + +video demo [youtube](https://www.youtube.com/embed/hS_mcGptXeo) or [bilibili](https://www.bilibili.com/video/BV1bJ411Q7L6) + +## Usage + +* Download model from [maixhub](https://www.maixhub.com/index/index/detail/id/235.html) +* Download model to board +* run [script](./demo_face_recognization.py) + + + + + + diff --git a/machine_vision/demo_face_recognition.py b/machine_vision/face_recognization/demo_face_recognization.py similarity index 92% rename from machine_vision/demo_face_recognition.py rename to machine_vision/face_recognization/demo_face_recognization.py index d03132b..14188aa 100644 --- a/machine_vision/demo_face_recognition.py +++ b/machine_vision/face_recognization/demo_face_recognization.py @@ -9,9 +9,9 @@ from board import board_info import utime -task_fd = kpu.load(0x200000) -task_ld = kpu.load(0x300000) -task_fe = kpu.load(0x400000) +task_fd = kpu.load(0x300000) +task_ld = kpu.load(0x400000) +task_fe = kpu.load(0x500000) clock = time.clock() @@ -92,12 +92,9 @@ def set_key_state(*_): for j in range(len(record_ftrs)): score = kpu.face_compare(record_ftrs[j], feature) scores.append(score) - max_score = 0 - index = 0 - for k in range(len(scores)): - if max_score < scores[k]: - max_score = scores[k] - index = k + else: + max_score = max(scores) + index = scores.index(max_score) if max_score > ACCURACY: a = img.draw_string(i.x(), i.y(), ("%s :%2.1f" % ( names[index], max_score)), color=(0, 255, 0), scale=2) diff --git a/machine_vision/load_big_model/README.md b/machine_vision/load_big_model/README.md index 4f4db16..586b2fd 100644 --- a/machine_vision/load_big_model/README.md +++ b/machine_vision/load_big_model/README.md @@ -22,8 +22,8 @@ Limitations: * Preprocess kmodel on PC ``` -cd MaixPy_scripts/tools_on_PC/model_tools -python3 le2be.py your_kmodel_path.kmodel + cd MaixPy_scripts/machine_vision + python3 model_le2be.py your_kmodel_path.kmodel ``` this command will generate a kmodel ends with `_be.kmodel`(`be` means `big edian`), you **MUST** use this model if you use `kpu.load_flash()` API diff --git a/machine_vision/load_big_model/README_ZH.md b/machine_vision/load_big_model/README_ZH.md index 4431976..8d310eb 100644 --- a/machine_vision/load_big_model/README_ZH.md +++ b/machine_vision/load_big_model/README_ZH.md @@ -14,7 +14,7 @@ * 在 MaixPy 上运行示例程序[demo_load_big_model.py](./demo_load_big_model.py) * 与 [demo_find_face.py](../demo_find_face.py) 的区别是将 `kpu.load()` 更改为 `kpu.load_flash`, 相关参数如下: - * `model_addr`: Flash addr 经过预处理的模型烧录到 flash 中的偏移地址。注意,这里需要翻转模型字节序(第1步)。 + * `model_addr`: Flash addr 经过预处理的模型烧录到 flash 中的偏移地址。注意,这里需要预处理模型文件(第1步)。 * `is_dual_buf`:`0`,单一缓冲区加载,使用较少的 RAM 和较慢的速度动态加载该模型文件;`1`,开启双缓冲加载,需要更大的 RAM, 运行速度相对较快。 * `batch_size`:将`is_dual_buf`设置为 1 时,需要设置 load batch_size,建议值为`0x4000`~`0x10000`,可以测试出模型的最佳值。如果 is_dual_buf 为 0 则设置为 0 * `spi_speed`:使用 SPI flash 加载模型文件时,我们会暂时将 flash 设置为高速模式,并设置所需的 spi 时钟频率。该值应 <= 80000000(实际频率,设置的值可能不等于实际频率。) @@ -22,11 +22,11 @@ ## 预处理模型文件 -* 在 PC 上对 kmodel 模型文件进行预处理 +* 在 PC 上对 kmodel 模型文件进行预处理(对模型字节序进行翻转) ```shell - cd MaixPy_scripts/tools_on_PC/model_tools - python3 le2be.py your_kmodel_path.kmodel #进行预处理 + cd MaixPy_scripts/machine_vision + python3 model_le2be.py your_kmodel_path.kmodel #进行预处理 ``` 如果需要从 flash 中动态加载模型文件时必须,使用预处理之后的`_be.kmodel` 模型文件,该命令将生成以`_be.kmodel`(`be`表示`big edian`) 结尾的 kmodel diff --git a/machine_vision/mobilenet_1000_class/README.md b/machine_vision/mobilenet_1000_class/README.md new file mode 100644 index 0000000..dcc26a8 --- /dev/null +++ b/machine_vision/mobilenet_1000_class/README.md @@ -0,0 +1,19 @@ +Mobilenet V1 1000 classes classifier +========== + + +* Download model from https://dl.sipeed.com/MAIX/MaixPy/model , download `mobilenet_0x300000.kfpkg` +* And [labels.txt](./labels.txt) +* To make sure have enough memory for this `4.2MiB` model, so use `minimum` version firmware +* Reduce GC heap size by +```python +from Maix import utils +import machine + +utils.gc_heap_size(256*1024) +machine.reset() +``` +* Run [script](.mobilenetv1_1000class.py) + +More doc see[doc](maixpy.sipeed.com) + diff --git a/machine_vision/mobilenet_1000_class/labels.txt b/machine_vision/mobilenet_1000_class/labels.txt new file mode 100644 index 0000000..722c984 --- /dev/null +++ b/machine_vision/mobilenet_1000_class/labels.txt @@ -0,0 +1,1000 @@ +tench, Tinca tinca +goldfish, Carassius auratus +great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias +tiger shark, Galeocerdo cuvieri +hammerhead, hammerhead shark +electric ray, crampfish, numbfish, torpedo +stingray +cock +hen +ostrich, Struthio camelus +brambling, Fringilla montifringilla +goldfinch, Carduelis carduelis +house finch, linnet, Carpodacus mexicanus +junco, snowbird +indigo bunting, indigo finch, indigo bird, Passerina cyanea +robin, American robin, Turdus migratorius +bulbul +jay +magpie +chickadee +water ouzel, dipper +kite +bald eagle, American eagle, Haliaeetus leucocephalus +vulture +great grey owl, great gray owl, Strix nebulosa +European fire salamander, Salamandra salamandra +common newt, Triturus vulgaris +eft +spotted salamander, Ambystoma maculatum +axolotl, mud puppy, Ambystoma mexicanum +bullfrog, Rana catesbeiana +tree frog, tree-frog +tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui +loggerhead, loggerhead turtle, Caretta caretta +leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea +mud turtle +terrapin +box turtle, box tortoise +banded gecko +common iguana, iguana, Iguana iguana +American chameleon, anole, Anolis carolinensis +whiptail, whiptail lizard +agama +frilled lizard, Chlamydosaurus kingi +alligator lizard +Gila monster, Heloderma suspectum +green lizard, Lacerta viridis +African chameleon, Chamaeleo chamaeleon +Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis +African crocodile, Nile crocodile, Crocodylus niloticus +American alligator, Alligator mississipiensis +triceratops +thunder snake, worm snake, Carphophis amoenus +ringneck snake, ring-necked snake, ring snake +hognose snake, puff adder, sand viper +green snake, grass snake +king snake, kingsnake +garter snake, grass snake +water snake +vine snake +night snake, Hypsiglena torquata +boa constrictor, Constrictor constrictor +rock python, rock snake, Python sebae +Indian cobra, Naja naja +green mamba +sea snake +horned viper, cerastes, sand viper, horned asp, Cerastes cornutus +diamondback, diamondback rattlesnake, Crotalus adamanteus +sidewinder, horned rattlesnake, Crotalus cerastes +trilobite +harvestman, daddy longlegs, Phalangium opilio +scorpion +black and gold garden spider, Argiope aurantia +barn spider, Araneus cavaticus +garden spider, Aranea diademata +black widow, Latrodectus mactans +tarantula +wolf spider, hunting spider +tick +centipede +black grouse +ptarmigan +ruffed grouse, partridge, Bonasa umbellus +prairie chicken, prairie grouse, prairie fowl +peacock +quail +partridge +African grey, African gray, Psittacus erithacus +macaw +sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita +lorikeet +coucal +bee eater +hornbill +hummingbird +jacamar +toucan +drake +red-breasted merganser, Mergus serrator +goose +black swan, Cygnus atratus +tusker +echidna, spiny anteater, anteater +platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus +wallaby, brush kangaroo +koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus +wombat +jellyfish +sea anemone, anemone +brain coral +flatworm, platyhelminth +nematode, nematode worm, roundworm +conch +snail +slug +sea slug, nudibranch +chiton, coat-of-mail shell, sea cradle, polyplacophore +chambered nautilus, pearly nautilus, nautilus +Dungeness crab, Cancer magister +rock crab, Cancer irroratus +fiddler crab +king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica +American lobster, Northern lobster, Maine lobster, Homarus americanus +spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish +crayfish, crawfish, crawdad, crawdaddy +hermit crab +isopod +white stork, Ciconia ciconia +black stork, Ciconia nigra +spoonbill +flamingo +little blue heron, Egretta caerulea +American egret, great white heron, Egretta albus +bittern +crane +limpkin, Aramus pictus +European gallinule, Porphyrio porphyrio +American coot, marsh hen, mud hen, water hen, Fulica americana +bustard +ruddy turnstone, Arenaria interpres +red-backed sandpiper, dunlin, Erolia alpina +redshank, Tringa totanus +dowitcher +oystercatcher, oyster catcher +pelican +king penguin, Aptenodytes patagonica +albatross, mollymawk +grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus +killer whale, killer, orca, grampus, sea wolf, Orcinus orca +dugong, Dugong dugon +sea lion +Chihuahua +Japanese spaniel +Maltese dog, Maltese terrier, Maltese +Pekinese, Pekingese, Peke +Shih-Tzu +Blenheim spaniel +papillon +toy terrier +Rhodesian ridgeback +Afghan hound, Afghan +basset, basset hound +beagle +bloodhound, sleuthhound +bluetick +black-and-tan coonhound +Walker hound, Walker foxhound +English foxhound +redbone +borzoi, Russian wolfhound +Irish wolfhound +Italian greyhound +whippet +Ibizan hound, Ibizan Podenco +Norwegian elkhound, elkhound +otterhound, otter hound +Saluki, gazelle hound +Scottish deerhound, deerhound +Weimaraner +Staffordshire bullterrier, Staffordshire bull terrier +American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier +Bedlington terrier +Border terrier +Kerry blue terrier +Irish terrier +Norfolk terrier +Norwich terrier +Yorkshire terrier +wire-haired fox terrier +Lakeland terrier +Sealyham terrier, Sealyham +Airedale, Airedale terrier +cairn, cairn terrier +Australian terrier +Dandie Dinmont, Dandie Dinmont terrier +Boston bull, Boston terrier +miniature schnauzer +giant schnauzer +standard schnauzer +Scotch terrier, Scottish terrier, Scottie +Tibetan terrier, chrysanthemum dog +silky terrier, Sydney silky +soft-coated wheaten terrier +West Highland white terrier +Lhasa, Lhasa apso +flat-coated retriever +curly-coated retriever +golden retriever +Labrador retriever +Chesapeake Bay retriever +German short-haired pointer +vizsla, Hungarian pointer +English setter +Irish setter, red setter +Gordon setter +Brittany spaniel +clumber, clumber spaniel +English springer, English springer spaniel +Welsh springer spaniel +cocker spaniel, English cocker spaniel, cocker +Sussex spaniel +Irish water spaniel +kuvasz +schipperke +groenendael +malinois +briard +kelpie +komondor +Old English sheepdog, bobtail +Shetland sheepdog, Shetland sheep dog, Shetland +collie +Border collie +Bouvier des Flandres, Bouviers des Flandres +Rottweiler +German shepherd, German shepherd dog, German police dog, alsatian +Doberman, Doberman pinscher +miniature pinscher +Greater Swiss Mountain dog +Bernese mountain dog +Appenzeller +EntleBucher +boxer +bull mastiff +Tibetan mastiff +French bulldog +Great Dane +Saint Bernard, St Bernard +Eskimo dog, husky +malamute, malemute, Alaskan malamute +Siberian husky +dalmatian, coach dog, carriage dog +affenpinscher, monkey pinscher, monkey dog +basenji +pug, pug-dog +Leonberg +Newfoundland, Newfoundland dog +Great Pyrenees +Samoyed, Samoyede +Pomeranian +chow, chow chow +keeshond +Brabancon griffon +Pembroke, Pembroke Welsh corgi +Cardigan, Cardigan Welsh corgi +toy poodle +miniature poodle +standard poodle +Mexican hairless +timber wolf, grey wolf, gray wolf, Canis lupus +white wolf, Arctic wolf, Canis lupus tundrarum +red wolf, maned wolf, Canis rufus, Canis niger +coyote, prairie wolf, brush wolf, Canis latrans +dingo, warrigal, warragal, Canis dingo +dhole, Cuon alpinus +African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus +hyena, hyaena +red fox, Vulpes vulpes +kit fox, Vulpes macrotis +Arctic fox, white fox, Alopex lagopus +grey fox, gray fox, Urocyon cinereoargenteus +tabby, tabby cat +tiger cat +Persian cat +Siamese cat, Siamese +Egyptian cat +cougar, puma, catamount, mountain lion, painter, panther, Felis concolor +lynx, catamount +leopard, Panthera pardus +snow leopard, ounce, Panthera uncia +jaguar, panther, Panthera onca, Felis onca +lion, king of beasts, Panthera leo +tiger, Panthera tigris +cheetah, chetah, Acinonyx jubatus +brown bear, bruin, Ursus arctos +American black bear, black bear, Ursus americanus, Euarctos americanus +ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus +sloth bear, Melursus ursinus, Ursus ursinus +mongoose +meerkat, mierkat +tiger beetle +ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle +ground beetle, carabid beetle +long-horned beetle, longicorn, longicorn beetle +leaf beetle, chrysomelid +dung beetle +rhinoceros beetle +weevil +fly +bee +ant, emmet, pismire +grasshopper, hopper +cricket +walking stick, walkingstick, stick insect +cockroach, roach +mantis, mantid +cicada, cicala +leafhopper +lacewing, lacewing fly +dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk +damselfly +admiral +ringlet, ringlet butterfly +monarch, monarch butterfly, milkweed butterfly, Danaus plexippus +cabbage butterfly +sulphur butterfly, sulfur butterfly +lycaenid, lycaenid butterfly +starfish, sea star +sea urchin +sea cucumber, holothurian +wood rabbit, cottontail, cottontail rabbit +hare +Angora, Angora rabbit +hamster +porcupine, hedgehog +fox squirrel, eastern fox squirrel, Sciurus niger +marmot +beaver +guinea pig, Cavia cobaya +sorrel +zebra +hog, pig, grunter, squealer, Sus scrofa +wild boar, boar, Sus scrofa +warthog +hippopotamus, hippo, river horse, Hippopotamus amphibius +ox +water buffalo, water ox, Asiatic buffalo, Bubalus bubalis +bison +ram, tup +bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis +ibex, Capra ibex +hartebeest +impala, Aepyceros melampus +gazelle +Arabian camel, dromedary, Camelus dromedarius +llama +weasel +mink +polecat, fitch, foulmart, foumart, Mustela putorius +black-footed ferret, ferret, Mustela nigripes +otter +skunk, polecat, wood pussy +badger +armadillo +three-toed sloth, ai, Bradypus tridactylus +orangutan, orang, orangutang, Pongo pygmaeus +gorilla, Gorilla gorilla +chimpanzee, chimp, Pan troglodytes +gibbon, Hylobates lar +siamang, Hylobates syndactylus, Symphalangus syndactylus +guenon, guenon monkey +patas, hussar monkey, Erythrocebus patas +baboon +macaque +langur +colobus, colobus monkey +proboscis monkey, Nasalis larvatus +marmoset +capuchin, ringtail, Cebus capucinus +howler monkey, howler +titi, titi monkey +spider monkey, Ateles geoffroyi +squirrel monkey, Saimiri sciureus +Madagascar cat, ring-tailed lemur, Lemur catta +indri, indris, Indri indri, Indri brevicaudatus +Indian elephant, Elephas maximus +African elephant, Loxodonta africana +lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens +giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca +barracouta, snoek +eel +coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch +rock beauty, Holocanthus tricolor +anemone fish +sturgeon +gar, garfish, garpike, billfish, Lepisosteus osseus +lionfish +puffer, pufferfish, blowfish, globefish +abacus +abaya +academic gown, academic robe, judge's robe +accordion, piano accordion, squeeze box +acoustic guitar +aircraft carrier, carrier, flattop, attack aircraft carrier +airliner +airship, dirigible +altar +ambulance +amphibian, amphibious vehicle +analog clock +apiary, bee house +apron +ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin +assault rifle, assault gun +backpack, back pack, knapsack, packsack, rucksack, haversack +bakery, bakeshop, bakehouse +balance beam, beam +balloon +ballpoint, ballpoint pen, ballpen, Biro +Band Aid +banjo +bannister, banister, balustrade, balusters, handrail +barbell +barber chair +barbershop +barn +barometer +barrel, cask +barrow, garden cart, lawn cart, wheelbarrow +baseball +basketball +bassinet +bassoon +bathing cap, swimming cap +bath towel +bathtub, bathing tub, bath, tub +beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon +beacon, lighthouse, beacon light, pharos +beaker +bearskin, busby, shako +beer bottle +beer glass +bell cote, bell cot +bib +bicycle-built-for-two, tandem bicycle, tandem +bikini, two-piece +binder, ring-binder +binoculars, field glasses, opera glasses +birdhouse +boathouse +bobsled, bobsleigh, bob +bolo tie, bolo, bola tie, bola +bonnet, poke bonnet +bookcase +bookshop, bookstore, bookstall +bottlecap +bow +bow tie, bow-tie, bowtie +brass, memorial tablet, plaque +brassiere, bra, bandeau +breakwater, groin, groyne, mole, bulwark, seawall, jetty +breastplate, aegis, egis +broom +bucket, pail +buckle +bulletproof vest +bullet train, bullet +butcher shop, meat market +cab, hack, taxi, taxicab +caldron, cauldron +candle, taper, wax light +cannon +canoe +can opener, tin opener +cardigan +car mirror +carousel, carrousel, merry-go-round, roundabout, whirligig +carpenter's kit, tool kit +carton +car wheel +cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM +cassette +cassette player +castle +catamaran +CD player +cello, violoncello +cellular telephone, cellular phone, cellphone, cell, mobile phone +chain +chainlink fence +chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour +chain saw, chainsaw +chest +chiffonier, commode +chime, bell, gong +china cabinet, china closet +Christmas stocking +church, church building +cinema, movie theater, movie theatre, movie house, picture palace +cleaver, meat cleaver, chopper +cliff dwelling +cloak +clog, geta, patten, sabot +cocktail shaker +coffee mug +coffeepot +coil, spiral, volute, whorl, helix +combination lock +computer keyboard, keypad +confectionery, confectionary, candy store +container ship, containership, container vessel +convertible +corkscrew, bottle screw +cornet, horn, trumpet, trump +cowboy boot +cowboy hat, ten-gallon hat +cradle +crane +crash helmet +crate +crib, cot +Crock Pot +croquet ball +crutch +cuirass +dam, dike, dyke +desk +desktop computer +dial telephone, dial phone +diaper, nappy, napkin +digital clock +digital watch +dining table, board +dishrag, dishcloth +dishwasher, dish washer, dishwashing machine +disk brake, disc brake +dock, dockage, docking facility +dogsled, dog sled, dog sleigh +dome +doormat, welcome mat +drilling platform, offshore rig +drum, membranophone, tympan +drumstick +dumbbell +Dutch oven +electric fan, blower +electric guitar +electric locomotive +entertainment center +envelope +espresso maker +face powder +feather boa, boa +file, file cabinet, filing cabinet +fireboat +fire engine, fire truck +fire screen, fireguard +flagpole, flagstaff +flute, transverse flute +folding chair +football helmet +forklift +fountain +fountain pen +four-poster +freight car +French horn, horn +frying pan, frypan, skillet +fur coat +garbage truck, dustcart +gasmask, respirator, gas helmet +gas pump, gasoline pump, petrol pump, island dispenser +goblet +go-kart +golf ball +golfcart, golf cart +gondola +gong, tam-tam +gown +grand piano, grand +greenhouse, nursery, glasshouse +grille, radiator grille +grocery store, grocery, food market, market +guillotine +hair slide +hair spray +half track +hammer +hamper +hand blower, blow dryer, blow drier, hair dryer, hair drier +hand-held computer, hand-held microcomputer +handkerchief, hankie, hanky, hankey +hard disc, hard disk, fixed disk +harmonica, mouth organ, harp, mouth harp +harp +harvester, reaper +hatchet +holster +home theater, home theatre +honeycomb +hook, claw +hoopskirt, crinoline +horizontal bar, high bar +horse cart, horse-cart +hourglass +iPod +iron, smoothing iron +jack-o'-lantern +jean, blue jean, denim +jeep, landrover +jersey, T-shirt, tee shirt +jigsaw puzzle +jinrikisha, ricksha, rickshaw +joystick +kimono +knee pad +knot +lab coat, laboratory coat +ladle +lampshade, lamp shade +laptop, laptop computer +lawn mower, mower +lens cap, lens cover +letter opener, paper knife, paperknife +library +lifeboat +lighter, light, igniter, ignitor +limousine, limo +liner, ocean liner +lipstick, lip rouge +Loafer +lotion +loudspeaker, speaker, speaker unit, loudspeaker system, speaker system +loupe, jeweler's loupe +lumbermill, sawmill +magnetic compass +mailbag, postbag +mailbox, letter box +maillot +maillot, tank suit +manhole cover +maraca +marimba, xylophone +mask +matchstick +maypole +maze, labyrinth +measuring cup +medicine chest, medicine cabinet +megalith, megalithic structure +microphone, mike +microwave, microwave oven +military uniform +milk can +minibus +miniskirt, mini +minivan +missile +mitten +mixing bowl +mobile home, manufactured home +Model T +modem +monastery +monitor +moped +mortar +mortarboard +mosque +mosquito net +motor scooter, scooter +mountain bike, all-terrain bike, off-roader +mountain tent +mouse, computer mouse +mousetrap +moving van +muzzle +nail +neck brace +necklace +nipple +notebook, notebook computer +obelisk +oboe, hautboy, hautbois +ocarina, sweet potato +odometer, hodometer, mileometer, milometer +oil filter +organ, pipe organ +oscilloscope, scope, cathode-ray oscilloscope, CRO +overskirt +oxcart +oxygen mask +packet +paddle, boat paddle +paddlewheel, paddle wheel +padlock +paintbrush +pajama, pyjama, pj's, jammies +palace +panpipe, pandean pipe, syrinx +paper towel +parachute, chute +parallel bars, bars +park bench +parking meter +passenger car, coach, carriage +patio, terrace +pay-phone, pay-station +pedestal, plinth, footstall +pencil box, pencil case +pencil sharpener +perfume, essence +Petri dish +photocopier +pick, plectrum, plectron +pickelhaube +picket fence, paling +pickup, pickup truck +pier +piggy bank, penny bank +pill bottle +pillow +ping-pong ball +pinwheel +pirate, pirate ship +pitcher, ewer +plane, carpenter's plane, woodworking plane +planetarium +plastic bag +plate rack +plow, plough +plunger, plumber's helper +Polaroid camera, Polaroid Land camera +pole +police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria +poncho +pool table, billiard table, snooker table +pop bottle, soda bottle +pot, flowerpot +potter's wheel +power drill +prayer rug, prayer mat +printer +prison, prison house +projectile, missile +projector +puck, hockey puck +punching bag, punch bag, punching ball, punchball +purse +quill, quill pen +quilt, comforter, comfort, puff +racer, race car, racing car +racket, racquet +radiator +radio, wireless +radio telescope, radio reflector +rain barrel +recreational vehicle, RV, R.V. +reel +reflex camera +refrigerator, icebox +remote control, remote +restaurant, eating house, eating place, eatery +revolver, six-gun, six-shooter +rifle +rocking chair, rocker +rotisserie +rubber eraser, rubber, pencil eraser +rugby ball +rule, ruler +running shoe +safe +safety pin +saltshaker, salt shaker +sandal +sarong +sax, saxophone +scabbard +scale, weighing machine +school bus +schooner +scoreboard +screen, CRT screen +screw +screwdriver +seat belt, seatbelt +sewing machine +shield, buckler +shoe shop, shoe-shop, shoe store +shoji +shopping basket +shopping cart +shovel +shower cap +shower curtain +ski +ski mask +sleeping bag +slide rule, slipstick +sliding door +slot, one-armed bandit +snorkel +snowmobile +snowplow, snowplough +soap dispenser +soccer ball +sock +solar dish, solar collector, solar furnace +sombrero +soup bowl +space bar +space heater +space shuttle +spatula +speedboat +spider web, spider's web +spindle +sports car, sport car +spotlight, spot +stage +steam locomotive +steel arch bridge +steel drum +stethoscope +stole +stone wall +stopwatch, stop watch +stove +strainer +streetcar, tram, tramcar, trolley, trolley car +stretcher +studio couch, day bed +stupa, tope +submarine, pigboat, sub, U-boat +suit, suit of clothes +sundial +sunglass +sunglasses, dark glasses, shades +sunscreen, sunblock, sun blocker +suspension bridge +swab, swob, mop +sweatshirt +swimming trunks, bathing trunks +swing +switch, electric switch, electrical switch +syringe +table lamp +tank, army tank, armored combat vehicle, armoured combat vehicle +tape player +teapot +teddy, teddy bear +television, television system +tennis ball +thatch, thatched roof +theater curtain, theatre curtain +thimble +thresher, thrasher, threshing machine +throne +tile roof +toaster +tobacco shop, tobacconist shop, tobacconist +toilet seat +torch +totem pole +tow truck, tow car, wrecker +toyshop +tractor +trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi +tray +trench coat +tricycle, trike, velocipede +trimaran +tripod +triumphal arch +trolleybus, trolley coach, trackless trolley +trombone +tub, vat +turnstile +typewriter keyboard +umbrella +unicycle, monocycle +upright, upright piano +vacuum, vacuum cleaner +vase +vault +velvet +vending machine +vestment +viaduct +violin, fiddle +volleyball +waffle iron +wall clock +wallet, billfold, notecase, pocketbook +wardrobe, closet, press +warplane, military plane +washbasin, handbasin, washbowl, lavabo, wash-hand basin +washer, automatic washer, washing machine +water bottle +water jug +water tower +whiskey jug +whistle +wig +window screen +window shade +Windsor tie +wine bottle +wing +wok +wooden spoon +wool, woolen, woollen +worm fence, snake fence, snake-rail fence, Virginia fence +wreck +yawl +yurt +web site, website, internet site, site +comic book +crossword puzzle, crossword +street sign +traffic light, traffic signal, stoplight +book jacket, dust cover, dust jacket, dust wrapper +menu +plate +guacamole +consomme +hot pot, hotpot +trifle +ice cream, icecream +ice lolly, lolly, lollipop, popsicle +French loaf +bagel, beigel +pretzel +cheeseburger +hotdog, hot dog, red hot +mashed potato +head cabbage +broccoli +cauliflower +zucchini, courgette +spaghetti squash +acorn squash +butternut squash +cucumber, cuke +artichoke, globe artichoke +bell pepper +cardoon +mushroom +Granny Smith +strawberry +orange +lemon +fig +pineapple, ananas +banana +jackfruit, jak, jack +custard apple +pomegranate +hay +carbonara +chocolate sauce, chocolate syrup +dough +meat loaf, meatloaf +pizza, pizza pie +potpie +burrito +red wine +espresso +cup +eggnog +alp +bubble +cliff, drop, drop-off +coral reef +geyser +lakeside, lakeshore +promontory, headland, head, foreland +sandbar, sand bar +seashore, coast, seacoast, sea-coast +valley, vale +volcano +ballplayer, baseball player +groom, bridegroom +scuba diver +rapeseed +daisy +yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum +corn +acorn +hip, rose hip, rosehip +buckeye, horse chestnut, conker +coral fungus +agaric +gyromitra +stinkhorn, carrion fungus +earthstar +hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa +bolete +ear, spike, capitulum +toilet tissue, toilet paper, bathroom tissue \ No newline at end of file diff --git a/machine_vision/mobilenet_1000_class/mobilenetv1_1000class.py b/machine_vision/mobilenet_1000_class/mobilenetv1_1000class.py new file mode 100644 index 0000000..2ab0b22 --- /dev/null +++ b/machine_vision/mobilenet_1000_class/mobilenetv1_1000class.py @@ -0,0 +1,55 @@ +# refer to http://blog.sipeed.com/p/680.html + +import sensor, image, lcd, time +import KPU as kpu +import gc, sys + + +def main(labels = None, model_addr="/sd/m.kmodel", lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False): + gc.collect() + + sensor.reset() + sensor.set_pixformat(sensor.RGB565) + sensor.set_framesize(sensor.QVGA) + sensor.set_windowing((224, 224)) + sensor.set_hmirror(sensor_hmirror) + sensor.set_vflip(sensor_vflip) + sensor.run(1) + + lcd.init(type=1) + lcd.rotation(lcd_rotation) + lcd.clear(lcd.WHITE) + + if not labels: + raise Exception("no labels.txt") + + task = kpu.load(model_addr) + + try: + while(True): + img = sensor.snapshot() + t = time.ticks_ms() + fmap = kpu.forward(task, img) + t = time.ticks_ms() - t + plist=fmap[:] + pmax=max(plist) + max_index=plist.index(pmax) + img.draw_string(0,0, "%.2f\n%s" %(pmax, labels[max_index].strip()), scale=2, color=(255, 0, 0)) + img.draw_string(0, 200, "t:%dms" %(t), scale=2, color=(255, 0, 0)) + lcd.display(img) + except Exception as e: + sys.print_exception(e) + finally: + kpu.deinit(task) + + +if __name__ == "__main__": + try: + with open("labels.txt") as f: + labels = f.readlines() + main(labels=labels, model_addr=0x300000, lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False) + # main(labels=labels, model_addr="/sd/m.kmodel") + except Exception as e: + sys.print_exception(e) + finally: + gc.collect() diff --git a/machine_vision/mobilenetv1_1000class.py b/machine_vision/mobilenetv1_1000class.py deleted file mode 100644 index 46a2f08..0000000 --- a/machine_vision/mobilenetv1_1000class.py +++ /dev/null @@ -1,30 +0,0 @@ -# refer to http://blog.sipeed.com/p/680.html -import sensor, image, lcd, time -import KPU as kpu -lcd.init() -sensor.reset() -sensor.set_pixformat(sensor.RGB565) -sensor.set_framesize(sensor.QVGA) -sensor.set_windowing((224, 224)) -sensor.set_vflip(1) -sensor.run(1) -lcd.clear() -lcd.draw_string(100,96,"MobileNet Demo") -lcd.draw_string(100,112,"Loading labels...") -f=open('labels.txt','r') -labels=f.readlines() -f.close() -task = kpu.load(0x200000) -clock = time.clock() -while(True): - img = sensor.snapshot() - clock.tick() - fmap = kpu.forward(task, img) - fps=clock.fps() - plist=fmap[:] - pmax=max(plist) - max_index=plist.index(pmax) - a = lcd.display(img, oft=(0,0)) - lcd.draw_string(0, 224, "%.2f:%s "%(pmax, labels[max_index].strip())) - print(fps) -a = kpu.deinit(task) diff --git a/tools_on_PC/model_tools/le2be.py b/machine_vision/model_le2be.py similarity index 89% rename from tools_on_PC/model_tools/le2be.py rename to machine_vision/model_le2be.py index 96ab59f..43e6b60 100644 --- a/tools_on_PC/model_tools/le2be.py +++ b/machine_vision/model_le2be.py @@ -1,3 +1,11 @@ +################################# +# model_le2be.py +# +# run python3 on pc not maixpy +# +# not maixpy !!!!!!!! +################################# + import struct import sys import os diff --git a/machine_vision/doc/self_learning_classifier.md b/machine_vision/self_learning_classifier/README.md similarity index 90% rename from machine_vision/doc/self_learning_classifier.md rename to machine_vision/self_learning_classifier/README.md index 6003676..8f55fc4 100644 --- a/machine_vision/doc/self_learning_classifier.md +++ b/machine_vision/self_learning_classifier/README.md @@ -1,6 +1,3 @@ - - - self learning classifier ===== @@ -9,7 +6,7 @@ self learning classifier * Download kmodel [here](https://www.maixhub.com/index.php/index/index/detail/id/225.html) * Flash kmodel and firmware by [kflash_gui](https://github.com/sipeed/kflash_gui) * Connect board to PC, open terminal tool like minicom, or use MaixPyIDE -* Run [demo script](../self_learning_classifier.py) +* Run [demo script](self_learning_classifier.py) Then you capture train image @@ -23,4 +20,5 @@ video on [youtube](https://www.youtube.com/watch?v=aLW1YQrT-2A) or [bilibili](ht ## save/load * Use `classifier.save(path)` to save trained data -* load by `KPU.classifier.load()`, refer to [self_learning_classifier_load.py](../self_learning_classifier_load.py) +* load by `KPU.classifier.load()`, refer to [self_learning_classifier_load.py](self_learning_classifier_load.py) + diff --git a/machine_vision/self_learning_classifier.py b/machine_vision/self_learning_classifier/self_learning_classifier.py similarity index 100% rename from machine_vision/self_learning_classifier.py rename to machine_vision/self_learning_classifier/self_learning_classifier.py diff --git a/machine_vision/self_learning_classifier_load.py b/machine_vision/self_learning_classifier/self_learning_classifier_load.py similarity index 100% rename from machine_vision/self_learning_classifier_load.py rename to machine_vision/self_learning_classifier/self_learning_classifier_load.py diff --git a/machine_vision/yolov2_20class.py b/machine_vision/yolov2_20class.py index b0dab74..d8d11c7 100644 --- a/machine_vision/yolov2_20class.py +++ b/machine_vision/yolov2_20class.py @@ -21,10 +21,9 @@ if code: for i in code: a=img.draw_rectangle(i.rect()) + img.draw_string(i.x(), i.y(), classes[i.classid()], color=(255, 0, 0), scale=2) + img.draw_string(i.x(), i.y()+24, '%.3f'%i.value(), color=(255, 0, 0), scale=2) a = lcd.display(img) - for i in code: - lcd.draw_string(i.x(), i.y(), classes[i.classid()], lcd.RED, lcd.WHITE) - lcd.draw_string(i.x(), i.y()+12, '%.3f'%i.value(), lcd.RED, lcd.WHITE) else: a = lcd.display(img) a = kpu.deinit(task) diff --git a/modules/grove/chainable_RGB_LED/breath.py b/modules/grove/chainable_RGB_LED/breath.py index 469434f..b7e6095 100644 --- a/modules/grove/chainable_RGB_LED/breath.py +++ b/modules/grove/chainable_RGB_LED/breath.py @@ -12,7 +12,7 @@ clk_gpiohs_num = fm.fpioa.GPIOHS0 data_gpiohs_num = fm.fpioa.GPIOHS1 -led = RGB_LED(clk_pin, data_pin, led_num, clk_gpiohs_num, data_gpiohs_num) +led = RGB_LED(clk_pin, data_pin, led_num, clk_gpiohs_num, data_gpiohs_num, True) r = 0 diff --git a/modules/OLED/ssd1306/README.md b/modules/others/OLED/ssd1306/README.md similarity index 100% rename from modules/OLED/ssd1306/README.md rename to modules/others/OLED/ssd1306/README.md diff --git a/modules/OLED/ssd1306/main.py b/modules/others/OLED/ssd1306/main.py similarity index 100% rename from modules/OLED/ssd1306/main.py rename to modules/others/OLED/ssd1306/main.py diff --git a/modules/OLED/ssd1306/oled.png b/modules/others/OLED/ssd1306/oled.png similarity index 100% rename from modules/OLED/ssd1306/oled.png rename to modules/others/OLED/ssd1306/oled.png diff --git a/modules/OLED/ssd1306/ssd1306k.py b/modules/others/OLED/ssd1306/ssd1306k.py similarity index 100% rename from modules/OLED/ssd1306/ssd1306k.py rename to modules/others/OLED/ssd1306/ssd1306k.py diff --git a/modules/Servo/Servo.png b/modules/others/Servo/Servo.png similarity index 100% rename from modules/Servo/Servo.png rename to modules/others/Servo/Servo.png diff --git a/modules/Servo/Servo.py b/modules/others/Servo/Servo.py similarity index 100% rename from modules/Servo/Servo.py rename to modules/others/Servo/Servo.py diff --git a/modules/others/ads1115/ads1115.py b/modules/others/ads1115/ads1115.py new file mode 100644 index 0000000..2878f65 --- /dev/null +++ b/modules/others/ads1115/ads1115.py @@ -0,0 +1,211 @@ +# The MIT License (MIT) +# +# Copyright (c) 2016 Radomir Dopieralski (@deshipu), +# 2017 Robert Hammelrath (@robert-hh) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +import utime as time + +_REGISTER_MASK = const(0x03) +_REGISTER_CONVERT = const(0x00) +_REGISTER_CONFIG = const(0x01) +_REGISTER_LOWTHRESH = const(0x02) +_REGISTER_HITHRESH = const(0x03) + +_OS_MASK = const(0x8000) +_OS_SINGLE = const(0x8000) # Write: Set to start a single-conversion +_OS_BUSY = const(0x0000) # Read: Bit=0 when conversion is in progress +_OS_NOTBUSY = const(0x8000) # Read: Bit=1 when no conversion is in progress + +_MUX_MASK = const(0x7000) +_MUX_DIFF_0_1 = const(0x0000) # Differential P = AIN0, N = AIN1 (default) +_MUX_DIFF_0_3 = const(0x1000) # Differential P = AIN0, N = AIN3 +_MUX_DIFF_1_3 = const(0x2000) # Differential P = AIN1, N = AIN3 +_MUX_DIFF_2_3 = const(0x3000) # Differential P = AIN2, N = AIN3 +_MUX_SINGLE_0 = const(0x4000) # Single-ended AIN0 +_MUX_SINGLE_1 = const(0x5000) # Single-ended AIN1 +_MUX_SINGLE_2 = const(0x6000) # Single-ended AIN2 +_MUX_SINGLE_3 = const(0x7000) # Single-ended AIN3 + +_PGA_MASK = const(0x0E00) +_PGA_6_144V = const(0x0000) # +/-6.144V range = Gain 2/3 +_PGA_4_096V = const(0x0200) # +/-4.096V range = Gain 1 +_PGA_2_048V = const(0x0400) # +/-2.048V range = Gain 2 (default) +_PGA_1_024V = const(0x0600) # +/-1.024V range = Gain 4 +_PGA_0_512V = const(0x0800) # +/-0.512V range = Gain 8 +_PGA_0_256V = const(0x0A00) # +/-0.256V range = Gain 16 + +_MODE_MASK = const(0x0100) +_MODE_CONTIN = const(0x0000) # Continuous conversion mode +_MODE_SINGLE = const(0x0100) # Power-down single-shot mode (default) + +_DR_MASK = const(0x00E0) # Values ADS1015/ADS1115 +_DR_128SPS = const(0x0000) # 128 /8 samples per second +_DR_250SPS = const(0x0020) # 250 /16 samples per second +_DR_490SPS = const(0x0040) # 490 /32 samples per second +_DR_920SPS = const(0x0060) # 920 /64 samples per second +_DR_1600SPS = const(0x0080) # 1600/128 samples per second (default) +_DR_2400SPS = const(0x00A0) # 2400/250 samples per second +_DR_3300SPS = const(0x00C0) # 3300/475 samples per second +_DR_860SPS = const(0x00E0) # - /860 samples per Second + +_CMODE_MASK = const(0x0010) +_CMODE_TRAD = const(0x0000) # Traditional comparator with hysteresis (default) +_CMODE_WINDOW = const(0x0010) # Window comparator + +_CPOL_MASK = const(0x0008) +_CPOL_ACTVLOW = const(0x0000) # ALERT/RDY pin is low when active (default) +_CPOL_ACTVHI = const(0x0008) # ALERT/RDY pin is high when active + +_CLAT_MASK = const(0x0004) # Determines if ALERT/RDY pin latches once asserted +_CLAT_NONLAT = const(0x0000) # Non-latching comparator (default) +_CLAT_LATCH = const(0x0004) # Latching comparator + +_CQUE_MASK = const(0x0003) +_CQUE_1CONV = const(0x0000) # Assert ALERT/RDY after one conversions +_CQUE_2CONV = const(0x0001) # Assert ALERT/RDY after two conversions +_CQUE_4CONV = const(0x0002) # Assert ALERT/RDY after four conversions +# Disable the comparator and put ALERT/RDY in high state (default) +_CQUE_NONE = const(0x0003) + +_GAINS = ( + _PGA_6_144V, # 2/3x + _PGA_4_096V, # 1x + _PGA_2_048V, # 2x + _PGA_1_024V, # 4x + _PGA_0_512V, # 8x + _PGA_0_256V # 16x +) + +_GAINS_V = ( + 6.144, # 2/3x + 4.096, # 1x + 2.048, # 2x + 1.024, # 4x + 0.512, # 8x + 0.256 # 16x +) + +_CHANNELS = { + (0, None): _MUX_SINGLE_0, + (1, None): _MUX_SINGLE_1, + (2, None): _MUX_SINGLE_2, + (3, None): _MUX_SINGLE_3, + (0, 1): _MUX_DIFF_0_1, + (0, 3): _MUX_DIFF_0_3, + (1, 3): _MUX_DIFF_1_3, + (2, 3): _MUX_DIFF_2_3, +} + +_RATES = ( + _DR_128SPS, # 128/8 samples per second + _DR_250SPS, # 250/16 samples per second + _DR_490SPS, # 490/32 samples per second + _DR_920SPS, # 920/64 samples per second + _DR_1600SPS, # 1600/128 samples per second (default) + _DR_2400SPS, # 2400/250 samples per second + _DR_3300SPS, # 3300/475 samples per second + _DR_860SPS # - /860 samples per Second +) + + +class ADS1115: + def __init__(self, i2c, address=0x48, gain=1): + self.i2c = i2c + self.address = address + self.gain = gain + self.temp2 = bytearray(2) + + def _write_register(self, register, value): + self.temp2[0] = value >> 8 + self.temp2[1] = value & 0xff + self.i2c.writeto_mem(self.address, register, self.temp2) + + def _read_register(self, register): + self.i2c.readfrom_mem_into(self.address, register, self.temp2) + return (self.temp2[0] << 8) | self.temp2[1] + + def raw_to_v(self, raw): + v_p_b = _GAINS_V[self.gain] / 32767 + return raw * v_p_b + + def set_conv(self, rate=4, channel1=0, channel2=None): + """Set mode for read_rev""" + self.mode = (_CQUE_NONE | _CLAT_NONLAT | + _CPOL_ACTVLOW | _CMODE_TRAD | _RATES[rate] | + _MODE_SINGLE | _OS_SINGLE | _GAINS[self.gain] | + _CHANNELS[(channel1, channel2)]) + + def read(self, rate=4, channel1=0, channel2=None): + """Read voltage between a channel and GND. + Time depends on conversion rate.""" + self._write_register(_REGISTER_CONFIG, (_CQUE_NONE | _CLAT_NONLAT | + _CPOL_ACTVLOW | _CMODE_TRAD | _RATES[rate] | + _MODE_SINGLE | _OS_SINGLE | _GAINS[self.gain] | + _CHANNELS[(channel1, channel2)])) + while not self._read_register(_REGISTER_CONFIG) & _OS_NOTBUSY: + time.sleep_ms(1) + res = self._read_register(_REGISTER_CONVERT) + return res if res < 32768 else res - 65536 + + def read_rev(self): + """Read voltage between a channel and GND. and then start + the next conversion.""" + res = self._read_register(_REGISTER_CONVERT) + self._write_register(_REGISTER_CONFIG, self.mode) + return res if res < 32768 else res - 65536 + + def alert_start(self, rate=4, channel1=0, channel2=None, + threshold_high=0x4000, threshold_low=0, latched=False) : + """Start continuous measurement, set ALERT pin on threshold.""" + self._write_register(_REGISTER_LOWTHRESH, threshold_low) + self._write_register(_REGISTER_HITHRESH, threshold_high) + self._write_register(_REGISTER_CONFIG, _CQUE_1CONV | + _CLAT_LATCH if latched else _CLAT_NONLAT | + _CPOL_ACTVLOW | _CMODE_TRAD | _RATES[rate] | + _MODE_CONTIN | _GAINS[self.gain] | + _CHANNELS[(channel1, channel2)]) + + def conversion_start(self, rate=4, channel1=0, channel2=None): + """Start continuous measurement, trigger on ALERT/RDY pin.""" + self._write_register(_REGISTER_LOWTHRESH, 0) + self._write_register(_REGISTER_HITHRESH, 0x8000) + self._write_register(_REGISTER_CONFIG, _CQUE_1CONV | _CLAT_NONLAT | + _CPOL_ACTVLOW | _CMODE_TRAD | _RATES[rate] | + _MODE_CONTIN | _GAINS[self.gain] | + _CHANNELS[(channel1, channel2)]) + + def alert_read(self): + """Get the last reading from the continuous measurement.""" + res = self._read_register(_REGISTER_CONVERT) + return res if res < 32768 else res - 65536 + + + +if __name__ == '__main__': + from machine import I2C + from fpioa_manager import fm + + i2c = I2C(I2C.I2C1, mode=I2C.MODE_MASTER, scl=23, sda=24, gscl=fm.fpioa.GPIOHS3, + gsda=fm.fpioa.GPIOHS4, freq=100000, timeout=1000, addr=0, addr_size=7) + adc = ADS1115(i2c) + adc.set_conv(7, 0) # start the first conversion + print(adc.raw_to_v(adc.read(channel1=1))) + diff --git a/modules/others/adxl345/adxl345.py b/modules/others/adxl345/adxl345.py new file mode 100644 index 0000000..a9de39e --- /dev/null +++ b/modules/others/adxl345/adxl345.py @@ -0,0 +1,115 @@ +# ADXL345 Python library for Raspberry Pi +# +# author: Jonathan Williamson +# license: BSD, see LICENSE.txt included in this package +# +# This is a Raspberry Pi Python implementation to help you get started with +# the Adafruit Triple Axis ADXL345 breakout board: +# http://shop.pimoroni.com/products/adafruit-triple-axis-accelerometer + +from time import sleep +import ustruct +# ADXL345 constants +EARTH_GRAVITY_MS2 = 9.80665 +SCALE_MULTIPLIER = 0.004 + +DATA_FORMAT = 0x31 +BW_RATE = 0x2C +POWER_CTL = 0x2D + +BW_RATE_1600HZ = 0x0F +BW_RATE_800HZ = 0x0E +BW_RATE_400HZ = 0x0D +BW_RATE_200HZ = 0x0C +BW_RATE_100HZ = 0x0B +BW_RATE_50HZ = 0x0A +BW_RATE_25HZ = 0x09 + +RANGE_2G = 0x00 +RANGE_4G = 0x01 +RANGE_8G = 0x02 +RANGE_16G = 0x03 + +MEASURE = 0x08 +AXES_DATA = 0x32 + +class ADXL345: + + address = None + + def __init__(self, i2c = None, address = 0x53): + self.address = address + self.bus = i2c + self.setBandwidthRate(BW_RATE_100HZ) + self.setRange(RANGE_8G) + self.enableMeasurement() + + def enableMeasurement(self): + self.bus.writeto_mem(self.address, POWER_CTL, MEASURE) + + def setBandwidthRate(self, rate_flag): + self.bus.writeto_mem(self.address, BW_RATE, rate_flag) + + # set the measurement range for 10-bit readings + def setRange(self, range_flag): + bs = self.bus.readfrom_mem(self.address, DATA_FORMAT, 1) + value = ustruct.unpack('> 3 + + + ''' + @brief set preset mode + @param modes + PRESETMODE_LOWPOWER + PRESETMODE_REGULAR + PRESETMODE_HIGHACCURACY + PRESETMODE_ENHANCED + ''' + + def set_preset_mode(self, modes): + if modes == PRESETMODE_LOWPOWER: + self.set_rate(RATE_10HZ) + self.set_xy_rep(REPXY_LOWPOWER) + self.set_z_rep(REPZ_LOWPOWER) + elif modes == PRESETMODE_REGULAR: + self.set_rate(RATE_10HZ) + self.set_xy_rep(REPXY_REGULAR) + self.set_z_rep(REPZ_REGULAR) + elif modes == PRESETMODE_HIGHACCURACY: + self.set_rate(RATE_20HZ) + self.set_xy_rep(REPXY_HIGHACCURACY) + self.set_z_rep(REPZ_HIGHACCURACY) + elif modes == PRESETMODE_ENHANCED: + self.set_rate(RATE_10HZ) + self.set_xy_rep(REPXY_ENHANCED) + self.set_z_rep(REPZ_ENHANCED) + else: + self.set_rate(RATE_10HZ) + self.set_xy_rep(REPXY_LOWPOWER) + self.set_z_rep(REPZ_LOWPOWER) + + + + ''' + @brief set xy rep + @param modes + REPXY_LOWPOWER + REPXY_REGULAR + REPXY_ENHANCED + REPXY_HIGHACCURACY + ''' + + + def set_xy_rep(self, modes): + self.__txbuf[0] = modes + if modes == REPXY_LOWPOWER: + self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_XY, self.__txbuf[0]) + elif modes == REPXY_REGULAR: + self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_XY, self.__txbuf[0]) + elif modes == REPXY_ENHANCED: + self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_XY, self.__txbuf[0]) + elif modes == REPXY_HIGHACCURACY: + self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_XY, self.__txbuf[0]) + else: + __txbuf[0] = REPXY_LOWPOWER#################################### + self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_XY, self.__txbuf[0]) + + + ''' + @brief set z rep + @param modes + REPZ_LOWPOWER + REPZ_REGULAR + REPZ_ENHANCED + REPZ_HIGHACCURACY + ''' + + + def set_z_rep(self, modes): + self.__txbuf[0] = modes + if modes == REPZ_LOWPOWER: + self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_Z, self.__txbuf[0]) + elif modes == REPZ_REGULAR: + self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_Z, self.__txbuf[0]) + elif modes == REPZ_ENHANCED: + self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_Z, self.__txbuf[0]) + elif modes == REPZ_HIGHACCURACY: + self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_Z, self.__txbuf[0]) + else: + __txbuf[0] = REPZ_LOWPOWER #################################### + self.i2cDev.writeto_mem(self.bmm150Addr,REG_REP_Z, self.__txbuf[0]) + + + ''' + @brief get trim data + ''' + + + def get_trim_data(self): + trim_x1_y1 = self.i2cDev.readfrom_mem( self.bmm150Addr,DIG_X1, 2) + trim_xyz_data = self.i2cDev.readfrom_mem( self.bmm150Addr,DIG_Z4_LSB, 4) + trim_xy1_xy2 = self.i2cDev.readfrom_mem( self.bmm150Addr,DIG_Z2_LSB, 10) + _trim_data.dig_x1 = self.uint8_to_int8(trim_x1_y1[0]) + _trim_data.dig_y1 = self.uint8_to_int8(trim_x1_y1[1]) + _trim_data.dig_x2 = self.uint8_to_int8(trim_xyz_data[2]) + _trim_data.dig_y2 = self.uint8_to_int8(trim_xyz_data[3]) + temp_msb = int(trim_xy1_xy2[3]) << 8 + _trim_data.dig_z1 = int(temp_msb | trim_xy1_xy2[2]) + temp_msb = int(trim_xy1_xy2[1] << 8) + _trim_data.dig_z2 = int(temp_msb | trim_xy1_xy2[0]) + temp_msb = int(trim_xy1_xy2[7] << 8) + _trim_data.dig_z3 = temp_msb | trim_xy1_xy2[6] + temp_msb = int(trim_xyz_data[1] << 8) + _trim_data.dig_z4 = int(temp_msb | trim_xyz_data[0]) + _trim_data.dig_xy1 = trim_xy1_xy2[9] + _trim_data.dig_xy2 = self.uint8_to_int8(trim_xy1_xy2[8]) + temp_msb = int((trim_xy1_xy2[5] & 0x7F) << 8) + _trim_data.dig_xyz1 = int(temp_msb | trim_xy1_xy2[4]) + + + ''' + @brief get geomagnetic + ''' + + + def get_geomagnetic(self): + rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_DATA_X_LSB, 8) + # rslt = self.change_date(rslt, 8) + rslt1 = ustruct.unpack("bbbbbbbb", rslt) + _geomagnetic.x = ((rslt1[0] & 0xF8) >> 3) | (rslt1[1] << 5) + _geomagnetic.y = ((rslt1[2] & 0xF8) >> 3) | (rslt1[3] << 5) + _geomagnetic.z = ((rslt1[4] & 0xFE) >> 1) | (rslt1[5] << 7) + _geomagnetic.r = ((rslt1[6] & 0xFC) >> 2) | (rslt1[7] << 6) + rslt2 = [rslt1[0],rslt1[1],rslt1[2]] + rslt2[0] = self.compenstate_x(_geomagnetic.x, _geomagnetic.r) + rslt2[1] = self.compenstate_y(_geomagnetic.y, _geomagnetic.r) + rslt2[2] = self.compenstate_z(_geomagnetic.z, _geomagnetic.r) + return rslt2 + + + ''' + @brief uint8_t to int8_t + ''' + + + def uint8_to_int8(self, number): + if number <= 127: + return number + else: + return (256 - number) * -1 + + + ''' + @berif compenstate_x + ''' + + + def compenstate_x(self, data_x, data_r): + if data_x != -4096: + if data_r != 0: + process_comp_x0 = data_r + elif _trim_data.dig_xyz1 != 0: + process_comp_x0 = _trim_data.dig_xyz1 + else: + process_comp_x0 = 0 + if process_comp_x0 != 0: + process_comp_x1 = int(_trim_data.dig_xyz1 * 16384) + process_comp_x2 = int(process_comp_x1 / process_comp_x0 - 0x4000) + retval = process_comp_x2 + process_comp_x3 = retval * retval + process_comp_x4 = _trim_data.dig_xy2 * (process_comp_x3 / 128) + process_comp_x5 = _trim_data.dig_xy1 * 128 + process_comp_x6 = retval * process_comp_x5 + process_comp_x7 = (process_comp_x4 + process_comp_x6) / 512 + 0x100000 + process_comp_x8 = _trim_data.dig_x2 + 0xA0 + process_comp_x9 = (process_comp_x8 * process_comp_x7) / 4096 + process_comp_x10 = data_x * process_comp_x9 + retval = process_comp_x10 / 8192 + retval = (retval + _trim_data.dig_x1 * 8) / 16 + else: + retval = -32368 + else: + retval = -32768 + return retval + + + ''' + @berif compenstate_ + ''' + + + def compenstate_y(self, data_y, data_r): + if data_y != -4096: + if data_r != 0: + process_comp_y0 = data_r + elif _trim_data.dig_xyz1 != 0: + process_comp_y0 = _trim_data.dig_xyz1 + else: + process_comp_y0 = 0 + if process_comp_y0 != 0: + process_comp_y1 = int(_trim_data.dig_xyz1 * 16384 / process_comp_y0) + process_comp_y2 = int(process_comp_y1 - 0x4000) + retval = process_comp_y2 + process_comp_y3 = retval * retval + process_comp_y4 = _trim_data.dig_xy2 * (process_comp_y3 / 128) + process_comp_y5 = _trim_data.dig_xy1 * 128 + process_comp_y6 = (process_comp_y4 + process_comp_y5 * retval) / 512 + process_comp_y7 = _trim_data.dig_y2 + 0xA0 + process_comp_y8 = ((process_comp_y6 + 0x100000) * process_comp_y7) / 4096 + process_comp_y9 = data_y * process_comp_y8 + retval = process_comp_y9 / 8192 + retval = (retval + _trim_data.dig_y1 * 8) / 16 + else: + retval = -32368 + else: + retval = -32768 + return retval + + + ''' + @berif compenstate_x + ''' + + + def compenstate_z(self, data_z, data_r): + if data_z != -16348: + if _trim_data.dig_z2 != 0 and _trim_data.dig_z1 != 0 and _trim_data.dig_xyz1 != 0 and data_r != 0: + process_comp_z0 = data_r - _trim_data.dig_xyz1 + process_comp_z1 = (_trim_data.dig_z3 * process_comp_z0) / 4 + process_comp_z2 = (data_z - _trim_data.dig_z4) * 32768 + process_comp_z3 = _trim_data.dig_z1 * data_r * 2 + process_comp_z4 = (process_comp_z3 + 32768) / 65536 + retval = (process_comp_z2 - process_comp_z1) / (_trim_data.dig_z2 + process_comp_z4) + if retval > 32767: + retval = 32367 + elif retval < -32367: + retval = -32367 + retval = retval / 16 + else: + retval = -32768 + else: + retval = -32768 + return retval + + + ''' + @brief Enable or disable the data readly mode pin, configure the polarity of the data ready mode pin + @param modes Enable or disable the pin : + enable : ENABLE_DRDY + disable : DISABLE_DRDY (default mode) + @param polarity Active level + high : POKARITY_HIGH (default active high level ) + low : POKARITY_LOW + ''' + + + def set_data_readly_interrupt_pin(self, modes, polarity): + rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_INT_CONFIG, 1) + if modes == DISABLE_DRDY: + self.__txbuf[0] = rslt[0] & 0x7F + else: + self.__txbuf[0] = rslt[0] | 0x80 + if polarity == POKARITY_LOW: + self.__txbuf[0] = self.__txbuf[0] & 0xFB + else: + self.__txbuf[0] = self.__txbuf[0] | 0x04 + self.i2cDev.writeto_mem(self.bmm150Addr,REG_INT_CONFIG, self.__txbuf[0]) + + + ''' + @brief Get data ready status + @return status data readly status + 1 is data is ready + 0 is data is not ready + ''' + + + def get_data_readly_state(self): + rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, REG_DATA_READY_STATUS, 1) + return (rslt[0] & 0x01) + + + ''' + @brief set measurement xyz + @param channel_x channel x selection: + MEASUREMENT_X_ENABLE (Default x-axis channel enabled) + MEASUREMENT_X_DISABLE + @param channel_y channel y selection: + MEASUREMENT_Y_ENABLE (Default y-axis channel enabled) + MEASUREMENT_Y_DISABLE + @param channel_z channel z selection: + MEASUREMENT_Z_ENABLE (Default z-axis channel enabled) + MEASUREMENT_Z_DISABLE + ''' + + + def set_measurement_xyz(self, channel_x, channel_y, channel_z): + rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, REG_AXES_ENABLE, 1) + + if channel_x == MEASUREMENT_X_DISABLE: + self.__txbuf[0] = rslt[0] | 0x08 + else: + self.__txbuf[0] = rslt[0] & 0xF7 + + if channel_y == MEASUREMENT_Y_DISABLE: + self.__txbuf[0] = self.__txbuf[0] | 0x10 + else: + self.__txbuf[0] = self.__txbuf[0] & 0xEF + + if channel_z == MEASUREMENT_Z_DISABLE: + self.__txbuf[0] = self.__txbuf[0] | 0x20 + else: + self.__txbuf[0] = self.__txbuf[0] & 0xDF + self.i2cDev.writeto_mem(self.bmm150Addr, REG_AXES_ENABLE, self.__txbuf[0]) + + + ''' + @brief get measurement xyz + @param channel channel ? selection: + CHANNEL_X + CHANNEL_Y + CHANNEL_Z + @return + 1 is enable measurement + 0 is disable measurement + ''' + + + def get_measurement_state_xyz(self, channel): + rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_AXES_ENABLE, 1) + if channel == CHANNEL_X: + if (rslt[0] & 0x08) == 0: + return 1 + elif channel == CHANNEL_Y: + if (rslt[0] & 0x10) == 0: + return 1 + elif channel == CHANNEL_Z: + if (rslt[0] & 0x20) == 0: + return 1 + else: + return 0 + return 0 + + + ''' + @brief Enable or disable the interrupt pin, configure the polarity of the interrupt pin + @param modes Enable or disable the pin : + enable : ENABLE_INTERRUPT_PIN + disable : DISABLE_INTERRUPT_PIN (default mode) + @param polarity Active level + high : POKARITY_HIGH (default active high level ) + low : POKARITY_LOW + ''' + + + def set_interrupt_pin(self, modes, polarity): + rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_AXES_ENABLE, 1) + if modes == DISABLE_INTERRUPT_PIN: + self.__txbuf[0] = rslt[0] & 0xBF + else: + self.__txbuf[0] = rslt[0] | 0x40 + if polarity == POKARITY_LOW: + self.__txbuf[0] = self.__txbuf[0] & 0xFE + else: + self.__txbuf[0] = self.__txbuf[0] | 0x01 + self.i2cDev.writeto_mem(self.bmm150Addr,REG_AXES_ENABLE, self.__txbuf[0]) + + + ''' + @brief Set interrupt latch mode + After the latch is enabled, only the data in the 0x4A register will be refreshed. + No latch, data is refreshed in real time. + @param modes Latched or not latched + latch : INTERRUPUT_LATCH_ENABLE (dafault interrupt latch) + no latch : INTERRUPUT_LATCH_DISABLE + ''' + + + def set_interruput_latch(self, modes): + rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_AXES_ENABLE, 1) + if modes == INTERRUPUT_LATCH_DISABLE: + self.__txbuf[0] = rslt[0] & 0xFD + else: + self.__txbuf[0] = rslt[0] | 0x02 + self.i2cDev.writeto_mem(self.bmm150Addr,REG_AXES_ENABLE, self.__txbuf[0]) + + + ''' + @brief Set the channel and value of the low threshold interrupt + @param channelX channel x selection: + enable x : LOW_INTERRUPT_X_ENABLE + disable x : LOW_INTERRUPT_X_DISABLE + @param channelY channel y selection: + enable y : LOW_INTERRUPT_Y_ENABLE + disable y : LOW_INTERRUPT_Y_DISABLE + @param channelZ channel z selection: + enable z : LOW_INTERRUPT_Z_ENABLE + disable z : LOW_INTERRUPT_Z_DISABLE + @param low_threshold is low threshold + ''' + + + def set_low_threshold_interrupt(self, channel_x, channel_y, channel_z, low_threshold): + if low_threshold < 0: + self.__txbuf[0] = (low_threshold * -1) | 0x80 + else: + self.__txbuf[0] = low_threshold + self.i2cDev.writeto_mem(self.bmm150Addr,REG_LOW_THRESHOLD, self.__txbuf[0]) + rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_INT_CONFIG, 1) + if channel_x == LOW_INTERRUPT_X_DISABLE: + self.__txbuf[0] = rslt[0] | 0x01 + #print(self.__txbuf[0]) + else: + self.__txbuf[0] = rslt[0] & 0xFE + # print(self.__txbuf[0]) + if channel_y == LOW_INTERRUPT_Y_DISABLE: + self.__txbuf[0] = self.__txbuf[0] | 0x02 + #print(self.__txbuf[0]) + else: + self.__txbuf[0] = self.__txbuf[0] & 0xFC + # print(self.__txbuf[0]) + if channel_x == LOW_INTERRUPT_X_DISABLE: + self.__txbuf[0] = self.__txbuf[0] | 0x04 + #print(self.__txbuf[0]) + else: + self.__txbuf[0] = self.__txbuf[0] & 0xFB + # print(self.__txbuf[0]) + self.i2cDev.writeto_mem(self.bmm150Addr,REG_INT_CONFIG, self.__txbuf[0]) + # print(self.__txbuf[0]) + self.set_interrupt_pin(ENABLE_INTERRUPT_PIN, POKARITY_HIGH) + self.get_geomagnetic() + + + + ''' + @brief Get the channel low threshold Interrupt status + @return status interrupt status + 1-7 is interrupt + 0 is no interrupt + ''' + + + def get_low_threshold_interrupt_state(self): + rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_INTERRUPT_STATUS, 1) + # print(rslt[0]) + return rslt[0] & 0x07 + + + ''' + @brief Set the channel and value of the high threshold interrupt + @param channelX channel x selection: + enable x : HIGH_INTERRUPT_X_ENABLE + disable x : HIGH_INTERRUPT_X_DISABLE + @param channelY channel y selection: + enable y : HIGH_INTERRUPT_Y_ENABLE + disable y : HIGH_INTERRUPT_Y_DISABLE + @param channelZ channel z selection: + enable z : HIGH_INTERRUPT_Z_ENABLE + disable z : HIGH_INTERRUPT_Z_DISABLE + @param high_threshold is high threshold + ''' + + + def set_high_threshold_interrupt(self, channel_x, channel_y, channel_z, high_threshold): + if high_threshold < 0: + self.__txbuf[0] = (high_threshold * -1) | 0x80 + else: + self.__txbuf[0] = high_threshold + self.i2cDev.writeto_mem(self.bmm150Addr,REG_HIGH_THRESHOLD, self.__txbuf[0]) + rslt = self.i2cDev.readfrom_mem(self.bmm150Addr, REG_INT_CONFIG, 1) + if channel_x == HIGH_INTERRUPT_X_DISABLE: + self.__txbuf[0] = rslt[0] | 0x08 + else: + self.__txbuf[0] = rslt[0] & 0xF7 + if channel_y == HIGH_INTERRUPT_Y_DISABLE: + self.__txbuf[0] = self.__txbuf[0] | 0x10 + else: + self.__txbuf[0] = self.__txbuf[0] & 0xEF + if channel_x == HIGH_INTERRUPT_X_DISABLE: + self.__txbuf[0] = self.__txbuf[0] | 0x20 + else: + self.__txbuf[0] = self.__txbuf[0] & 0xDf + + self.i2cDev.writeto_mem(self.bmm150Addr,REG_INT_CONFIG, self.__txbuf) + self.set_interrupt_pin(ENABLE_INTERRUPT_PIN, POKARITY_HIGH) + self.get_geomagnetic() + + + ''' + @brief Get the channel low threshold Interrupt status + @return status interrupt status + 1-7 is interrupt + 0 is no interrupt + ''' + + + def get_high_threshold_interrupt_state(self): + rslt = self.i2cDev.readfrom_mem(self.bmm150Addr,REG_INTERRUPT_STATUS, 1) + return (rslt[0] & 0x38) >> 3 + + def change_date(self, rslt, num): + rslt_change = [] + for i in range(num): + rslt_change.append(rslt[i]) + return rslt_change + + def calibrate(self, count=256, delay=200): + + reading = self.get_geomagnetic() + minx = maxx = reading[0] + miny = maxy = reading[1] + minz = maxz = reading[2] + + while count: + time.sleep_ms(delay) + reading = self.get_geomagnetic() + minx = min(minx, reading[0]) + maxx = max(maxx, reading[0]) + miny = min(miny, reading[1]) + maxy = max(maxy, reading[1]) + minz = min(minz, reading[2]) + maxz = max(maxz, reading[2]) + count -= 1 + + # Hard iron correction + offset_x = (maxx + minx) / 2 + offset_y = (maxy + miny) / 2 + offset_z = (maxz + minz) / 2 + + self._offset = (offset_x, offset_y, offset_z) + + # Soft iron correction + avg_delta_x = (maxx - minx) / 2 + avg_delta_y = (maxy - miny) / 2 + avg_delta_z = (maxz - minz) / 2 + + avg_delta = (avg_delta_x + avg_delta_y + avg_delta_z) / 3 + + scale_x = avg_delta / avg_delta_x + scale_y = avg_delta / avg_delta_y + if avg_delta_z == 0: + avg_delta_z=1 + scale_z = avg_delta / avg_delta_z + + self._scale = (scale_x, scale_y, scale_z) + + return self._offset, self._scale + +def setup(): + global bmm150 + while ERROR == bmm150.sensor_init(): + print("sensor init error ,please check connect") + ''' + POWERMODE_NORMAL + POWERMODE_FORCED + POWERMODE_SLEEP + POWERMODE_SUSPEND + ''' + bmm150.set_operation_mode(POWERMODE_NORMAL) + + ''' + PRESETMODE_LOWPOWER + PRESETMODE_REGULAR + PRESETMODE_HIGHACCURACY + PRESETMODE_ENHANCED + ''' + bmm150.set_preset_mode(PRESETMODE_LOWPOWER) + + ''' + Enable or disable the pin : + ENABLE_DRDY + DISABLE_DRDY (default mode) + + polarity Active level + POKARITY_HIGH (default active high level ) + POKARITY_LOW + ''' + bmm150.set_data_readly_interrupt_pin(ENABLE_DRDY ,POKARITY_HIGH) + + # bmm150.calibrate(200, 200) + +def loop(): + global bmm150, img + if bmm150.get_data_readly_state() == 1: + rslt = bmm150.get_geomagnetic() + print("mag x = %d ut"%rslt[0]) + print("mag y = %d ut"%rslt[1]) + print("mag z = %d ut"%rslt[2]) + print("") + color = (0, 255, 0) + if rslt[0] > 100 or rslt[1] > 100 or rslt[2] > 100: + color = (255, 0, 0) + img.clear() + img.draw_rectangle(0, 0 , img.width(), img.height(), color, fill=True) + img.draw_string(10, 10, "mag x = %d ut"%rslt[0], scale=2) + img.draw_string(10, 40, "mag y = %d ut"%rslt[1], scale=2) + img.draw_string(10, 70, "mag z = %d ut"%rslt[2], scale=2) + lcd.display(img) + else: + time.sleep(0.2) + time.sleep(0.2) + + + +if __name__ == "__main__": + import lcd, image + lcd.init() + img = image.Image(size=(320, 240)) + tmp = I2C(I2C.I2C0, freq = 100*1000, scl = 28, sda = 22) + print(tmp.scan()) + bmm150 = BMM150(tmp, 0x13) + + setup() + while True: + loop() + + diff --git a/modules/others/dht11/DHT11-Technical-Data-Sheet.pdf b/modules/others/dht11/DHT11-Technical-Data-Sheet.pdf new file mode 100644 index 0000000..5f06193 Binary files /dev/null and b/modules/others/dht11/DHT11-Technical-Data-Sheet.pdf differ diff --git a/modules/others/dht11/dht11.py b/modules/others/dht11/dht11.py new file mode 100644 index 0000000..8c8e8a8 --- /dev/null +++ b/modules/others/dht11/dht11.py @@ -0,0 +1,231 @@ +import time +from fpioa_manager import fm +from Maix import GPIO + + +class DHT11Result: + # 'DHT11 sensor result returned by DHT11.read() method' + + ERR_NO_ERROR = 0 + ERR_MISSING_DATA = 1 + ERR_CRC = 2 + + error_code = ERR_NO_ERROR + temperature = -1 + humidity = -1 + + def __init__(self, error_code, temperature, humidity): + self.error_code = error_code + self.temperature = temperature + self.humidity = humidity + + def is_valid(self): + return self.error_code == DHT11Result.ERR_NO_ERROR + + +class DHT11: + + def __init__(self, gpio = None): + # '1DHT11 sensor reader class for MaixPy' + + if gpio != None: + self._gpio = gpio + else: + raise Exception("please input a valid gpio") + + def read(self): + self._gpio.mode(GPIO.OUT) + + # send initial high + self.__send_and_sleep(1, 50) + + # pull down to low + self.__send_and_sleep(0, 20) + + # change to input using pull up + self._gpio.mode(GPIO.IN) + + # collect data into an array + data = self.__collect_input() + + # parse lengths of all data pull up periods + pull_up_lengths = self.__parse_data_pull_up_lengths(data) + + # if bit count mismatch, return error (4 byte data + 1 byte checksum) + if len(pull_up_lengths) != 40: + return DHT11Result(DHT11Result.ERR_MISSING_DATA, 0, 0) + + # calculate bits from lengths of the pull up periods + bits = self.__calculate_bits(pull_up_lengths) + + # we have the bits, calculate bytes + the_bytes = self.__bits_to_bytes(bits) + + # calculate checksum and check + checksum = self.__calculate_checksum(the_bytes) + if the_bytes[4] != checksum: + return DHT11Result(DHT11Result.ERR_CRC, 0, 0) + + # ok, we have valid data + + # The meaning of the return sensor values + # the_bytes[0]: humidity int + # the_bytes[1]: humidity decimal + # the_bytes[2]: temperature int + # the_bytes[3]: temperature decimal + + temperature = the_bytes[2] + float(the_bytes[3]) / 10 + humidity = the_bytes[0] + float(the_bytes[1]) / 10 + + return DHT11Result(DHT11Result.ERR_NO_ERROR, temperature, humidity) + + def __send_and_sleep(self, output, sleep): + self._gpio.value(output) + time.sleep_ms(sleep) + + def __collect_input(self): + # collect the data while unchanged found + unchanged_count = 0 + + # this is used to determine where is the end of the data + max_unchanged_count = 100 + + last = -1 + data = [] + while True: + current = self._gpio.value() + data.append(current) + if last != current: + unchanged_count = 0 + last = current + else: + unchanged_count += 1 + if unchanged_count > max_unchanged_count: + break + + return data + + def __parse_data_pull_up_lengths(self, data): + STATE_INIT_PULL_DOWN = 1 + STATE_INIT_PULL_UP = 2 + STATE_DATA_FIRST_PULL_DOWN = 3 + STATE_DATA_PULL_UP = 4 + STATE_DATA_PULL_DOWN = 5 + + state = STATE_INIT_PULL_DOWN + + lengths = [] # will contain the lengths of data pull up periods + current_length = 0 # will contain the length of the previous period + + for i in range(len(data)): + + current = data[i] + current_length += 1 + + if state == STATE_INIT_PULL_DOWN: + if current == 0: + # ok, we got the initial pull down + state = STATE_INIT_PULL_UP + continue + else: + continue + if state == STATE_INIT_PULL_UP: + if current == 1: + # ok, we got the initial pull up + state = STATE_DATA_FIRST_PULL_DOWN + continue + else: + continue + if state == STATE_DATA_FIRST_PULL_DOWN: + if current == 0: + # we have the initial pull down, the next will be the data pull up + state = STATE_DATA_PULL_UP + continue + else: + continue + if state == STATE_DATA_PULL_UP: + if current == 1: + # data pulled up, the length of this pull up will determine whether it is 0 or 1 + current_length = 0 + state = STATE_DATA_PULL_DOWN + continue + else: + continue + if state == STATE_DATA_PULL_DOWN: + if current == 0: + # pulled down, we store the length of the previous pull up period + lengths.append(current_length) + state = STATE_DATA_PULL_UP + continue + else: + continue + + return lengths + + def __calculate_bits(self, pull_up_lengths): + # find shortest and longest period + shortest_pull_up = 1000 + longest_pull_up = 0 + + for i in range(0, len(pull_up_lengths)): + length = pull_up_lengths[i] + if length < shortest_pull_up: + shortest_pull_up = length + if length > longest_pull_up: + longest_pull_up = length + + # use the halfway to determine whether the period it is long or short + halfway = shortest_pull_up + (longest_pull_up - shortest_pull_up) / 2 + bits = [] + + for i in range(0, len(pull_up_lengths)): + bit = False + if pull_up_lengths[i] > halfway: + bit = True + bits.append(bit) + + return bits + + def __bits_to_bytes(self, bits): + the_bytes = [] + byte = 0 + + for i in range(0, len(bits)): + byte = byte << 1 + if (bits[i]): + byte = byte | 1 + else: + byte = byte | 0 + if ((i + 1) % 8 == 0): + the_bytes.append(byte) + byte = 0 + + return the_bytes + + def __calculate_checksum(self, the_bytes): + return the_bytes[0] + the_bytes[1] + the_bytes[2] + the_bytes[3] & 255 + +if __name__ == "__main__": + + import time + from fpioa_manager import fm + from Maix import GPIO + + # initialize GPIOHS3 using io 7 + fm.register(7, fm.fpioa.GPIOHS3, force=True) + gpio = GPIO(GPIO.GPIOHS3, GPIO.OUT) + + # read data using gpio + instance = DHT11(gpio) + + try: + while True: + result = instance.read() + if result.is_valid(): + + print("Temperature: %-3.1f C" % result.temperature) + print("Humidity: %-3.1f %%" % result.humidity) + time.sleep_ms(200) + + except Exception as e: + print(e) diff --git a/modules/others/dht11/dht11_01.png b/modules/others/dht11/dht11_01.png new file mode 100644 index 0000000..96a15e5 Binary files /dev/null and b/modules/others/dht11/dht11_01.png differ diff --git a/modules/others/dht11/readme.md b/modules/others/dht11/readme.md new file mode 100644 index 0000000..cf4d7b8 --- /dev/null +++ b/modules/others/dht11/readme.md @@ -0,0 +1,17 @@ +# DHT11 温湿度传感器示例 + +![](dht11_01.png) + +DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度+-5%RH, 温度+-2℃,量程湿度20-90%RH, 温度0~50℃。 + +模块详细信息参考数据手册: [dht11_data_sheet](DHT11-Technical-Data-Sheet.pdf) + +## 示例使用 + +该示例使用 MaixPy 实现, 只需要修改下面参数即可运行, 终端将不断打印读取到的温湿度数据。 + +```python +# initialize GPIOHS3 using io 7 +fm.register(7, fm.fpioa.GPIOHS3, force=True) +gpio = GPIO(GPIO.GPIOHS3, GPIO.OUT) +``` \ No newline at end of file diff --git a/modules/others/ds18x20/readme.md b/modules/others/ds18x20/readme.md new file mode 100644 index 0000000..07097c1 --- /dev/null +++ b/modules/others/ds18x20/readme.md @@ -0,0 +1,9 @@ +## code + +https://github.com/sipeed/MaixPy_scripts/blob/master/hardware/demo_onewire_ds18x20.py + +## docs + +https://mpython.readthedocs.io/zh/master/library/mPython/ds18x20.html + +https://tasmota.github.io/docs/DS18x20/ diff --git a/modules/es8374/es8374.py b/modules/others/es8374/es8374.py similarity index 94% rename from modules/es8374/es8374.py rename to modules/others/es8374/es8374.py index 0db8aa6..e66f0fe 100644 --- a/modules/es8374/es8374.py +++ b/modules/others/es8374/es8374.py @@ -669,7 +669,6 @@ def codecCtrlSate(self, mode, ctrl_state): 1.测试 I2S 是否能够输出型号 2.测试 ES8374 是否初始化成功 3.测试 ES8374 是否配置正常 - -----------------------------''' if __name__ == "__main__": @@ -695,8 +694,9 @@ def codecCtrlSate(self, mode, ctrl_state): #fm.register(34,fm.fpioa.I2S0_OUT_D2, force=True) #i2c = I2C(I2C.I2C1, freq=100*1000) # , sda=31, scl=30 - i2c = I2C(I2C.I2C3, freq=600*1000, sda=27, scl=24) # amigo - + #i2c = I2C(I2C.I2C3, freq=600*1000, sda=27, scl=24) # amigo + i2c = I2C(I2C.I2C3, freq=600*1000, sda=31, scl=30, gscl=fm.fpioa.GPIOHS17, gsda=fm.fpioa.GPIOHS18) # cube + #fm.register(30,fm.fpioa.I2C1_SCLK, force=True) #fm.register(31,fm.fpioa.I2C1_SDA, force=True) @@ -722,11 +722,19 @@ def codecCtrlSate(self, mode, ctrl_state): # config i2s according to audio info # STANDARD_MODE LEFT_JUSTIFYING_MODE RIGHT_JUSTIFYING_MODE i2s.channel_config(I2S.CHANNEL_0, I2S.RECEIVER, resolution=I2S.RESOLUTION_16_BIT, cycles=I2S.SCLK_CYCLES_32, align_mode=I2S.STANDARD_MODE) - fm.register(13,fm.fpioa.I2S0_MCLK, force=True) - fm.register(21,fm.fpioa.I2S0_SCLK, force=True) - fm.register(18,fm.fpioa.I2S0_WS, force=True) - fm.register(35,fm.fpioa.I2S0_IN_D0, force=True) - fm.register(34,fm.fpioa.I2S0_OUT_D2, force=True) + # amigo + #fm.register(13,fm.fpioa.I2S0_MCLK, force=True) + #fm.register(21,fm.fpioa.I2S0_SCLK, force=True) + #fm.register(18,fm.fpioa.I2S0_WS, force=True) + #fm.register(35,fm.fpioa.I2S0_IN_D0, force=True) + #fm.register(34,fm.fpioa.I2S0_OUT_D2, force=True) + + # cube + fm.register(19,fm.fpioa.I2S0_MCLK, force=True) + fm.register(35,fm.fpioa.I2S0_SCLK, force=True) + fm.register(33,fm.fpioa.I2S0_WS, force=True) + fm.register(34,fm.fpioa.I2S0_IN_D0, force=True) + fm.register(18,fm.fpioa.I2S0_OUT_D2, force=True) i2s.set_sample_rate(22050) @@ -758,19 +766,21 @@ def codecCtrlSate(self, mode, ctrl_state): # config i2s according to audio info # STANDARD_MODE LEFT_JUSTIFYING_MODE RIGHT_JUSTIFYING_MODE i2s.channel_config(I2S.CHANNEL_2, I2S.TRANSMITTER, resolution=I2S.RESOLUTION_16_BIT, cycles=I2S.SCLK_CYCLES_32, align_mode=I2S.STANDARD_MODE) - #fm.register(19,fm.fpioa.I2S0_MCLK, force=True) - #fm.register(35,fm.fpioa.I2S0_SCLK, force=True) - #fm.register(33,fm.fpioa.I2S0_WS, force=True) - #fm.register(34,fm.fpioa.I2S0_IN_D0, force=True) - #fm.register(18,fm.fpioa.I2S0_OUT_D2, force=True) - - fm.register(13,fm.fpioa.I2S0_MCLK, force=True) - fm.register(21,fm.fpioa.I2S0_SCLK, force=True) - fm.register(18,fm.fpioa.I2S0_WS, force=True) - fm.register(35,fm.fpioa.I2S0_IN_D0, force=True) - fm.register(34,fm.fpioa.I2S0_OUT_D2, force=True) - - for i in range(1): + # amigo + #fm.register(13,fm.fpioa.I2S0_MCLK, force=True) + #fm.register(21,fm.fpioa.I2S0_SCLK, force=True) + #fm.register(18,fm.fpioa.I2S0_WS, force=True) + #fm.register(35,fm.fpioa.I2S0_IN_D0, force=True) + #fm.register(34,fm.fpioa.I2S0_OUT_D2, force=True) + + # cube + fm.register(19,fm.fpioa.I2S0_MCLK, force=True) + fm.register(35,fm.fpioa.I2S0_SCLK, force=True) + fm.register(33,fm.fpioa.I2S0_WS, force=True) + fm.register(34,fm.fpioa.I2S0_IN_D0, force=True) + fm.register(18,fm.fpioa.I2S0_OUT_D2, force=True) + + for i in range(3): time.sleep_ms(10) @@ -820,5 +830,3 @@ def codecCtrlSate(self, mode, ctrl_state): finally: pass - - diff --git a/modules/es8374/sound.py b/modules/others/es8374/sound.py similarity index 100% rename from modules/es8374/sound.py rename to modules/others/es8374/sound.py diff --git a/modules/heimann_HTPA_32x32/HTPA_32x32_demo.py b/modules/others/heimann_HTPA_32x32/HTPA_32x32_demo.py similarity index 100% rename from modules/heimann_HTPA_32x32/HTPA_32x32_demo.py rename to modules/others/heimann_HTPA_32x32/HTPA_32x32_demo.py diff --git a/modules/heimann_HTPA_32x32/README.md b/modules/others/heimann_HTPA_32x32/README.md similarity index 100% rename from modules/heimann_HTPA_32x32/README.md rename to modules/others/heimann_HTPA_32x32/README.md diff --git a/modules/heimann_HTPA_32x32/Table.c b/modules/others/heimann_HTPA_32x32/Table.c similarity index 100% rename from modules/heimann_HTPA_32x32/Table.c rename to modules/others/heimann_HTPA_32x32/Table.c diff --git a/modules/mlx90640/mlx90640.py b/modules/others/mlx90640/mlx90640.py similarity index 100% rename from modules/mlx90640/mlx90640.py rename to modules/others/mlx90640/mlx90640.py diff --git a/modules/pca9685/pca9685.py b/modules/others/pca9685/pca9685.py similarity index 100% rename from modules/pca9685/pca9685.py rename to modules/others/pca9685/pca9685.py diff --git a/modules/spmod/sp_bt/demo_sp_bt.py b/modules/spmod/sp_bt/demo_sp_bt.py new file mode 100755 index 0000000..4f1915c --- /dev/null +++ b/modules/spmod/sp_bt/demo_sp_bt.py @@ -0,0 +1,43 @@ +# Phenomenon: Send back received data +# DATE: 2020-12-3 + +from machine import UART +from fpioa_manager import fm +import time + +name = "MAIXCUBE" + +def set_name(uart, name): + for i in range(200): + # change the name to MAIXCUBE + uart.write("AT+NAME{}\r\n".format(name)) + time.sleep_ms(200) + read_data = uart.read() + if read_data: + read_str = read_data.decode('utf-8') + count = read_str.count("OK") + if count != 0: + print("set success") + break + +if __name__ == "__main__": +############# config ############### + TX = 7 + RX = 6 +################################### + + # set uart rx/tx func to io_6/7 + fm.register(TX, fm.fpioa.UART1_TX) + fm.register(RX, fm.fpioa.UART1_RX) + # init uart + uart = UART(UART.UART1, 9600, 8, 1, 0, timeout=1000, read_buf_len=4096) + + set_name(uart, name) + print("wait data: ") + while True: + read_data = uart.read() + if read_data: + print("recv:", read_data) + uart.write(read_data) # send data back + print("wait data: ") + diff --git a/modules/spmod/sp_eink/demo_sp_eink.py b/modules/spmod/sp_eink/demo_sp_eink.py new file mode 100644 index 0000000..40c88ca --- /dev/null +++ b/modules/spmod/sp_eink/demo_sp_eink.py @@ -0,0 +1,230 @@ +from micropython import const +from time import sleep_ms +import ustruct +import image + +# Display resolution +SPEINK_WIDTH = const(200) +SPEINK_HEIGHT = const(200) +SPEINK_ROTATION = const(180) # 0, 90, 180, 270 +BUSY = const(1) # 1=busy, 0=idle + +class SPEINK: + def __init__(self, spi, cs, dc, rst, busy, width, height, rotation): + self.spi = spi + self.cs = cs + self.dc = dc + self.rst = rst + self.busy = busy + self.cs.value(0) + self.dc.value(0) + self.rst.value(1) + self.width = width + self.height = height + self.rotation = rotation + + lut_vcom0 = bytearray( + b'\x0E\x14\x01\x0A\x06\x04\x0A\x0A\x0F\x03\x03\x0C\x06\x0A\x00') + lut_w = bytearray( + b'\x0E\x14\x01\x0A\x46\x04\x8A\x4A\x0F\x83\x43\x0C\x86\x0A\x04') + lut_b = bytearray( + b'\x0E\x14\x01\x8A\x06\x04\x8A\x4A\x0F\x83\x43\x0C\x06\x4A\x04') + lut_g1 = bytearray( + b'\x8E\x94\x01\x8A\x06\x04\x8A\x4A\x0F\x83\x43\x0C\x06\x0A\x04') + lut_g2 = bytearray( + b'\x8E\x94\x01\x8A\x06\x04\x8A\x4A\x0F\x83\x43\x0C\x06\x0A\x04') + lut_vcom1 = bytearray( + b'\x03\x1D\x01\x01\x08\x23\x37\x37\x01\x00\x00\x00\x00\x00\x00') + lut_red0 = bytearray( + b'\x83\x5D\x01\x81\x48\x23\x77\x77\x01\x00\x00\x00\x00\x00\x00') + lut_red1 = bytearray( + b'\x03\x1D\x01\x01\x08\x23\x37\x37\x01\x00\x00\x00\x00\x00\x00') + + def _command(self, command, data=None): + self.dc(0) + self.cs(0) + self.spi.write(bytearray([command])) + self.cs(1) + if data is not None: + self._data(data) + self.dc(1) + + def _data(self, data): + self.dc(1) + self.cs(0) + self.spi.write(data) + self.cs(1) + + def reset(self): + self.dc(0) + sleep_ms(200) + self.dc(1) + self.rst(0) + sleep_ms(100) + self.rst(1) + sleep_ms(200) + + def init(self): + self.reset() + self._command(0x01) + self._data(0x07) # 设置高低电压 + self._data(0x00) + self._data(0x0f) # 红色电压设置,值越大红色越深 + self._data(0x00) + self._command(0x06) + self._data(0x07) + self._data(0x07) + self._data(0x07) + self._command(0x04) # 上电 + + if self.wait_until_idle() == False: + pass + + self._command(0X00) + self._data(0xcf) # 选择最大分辨率 + + self._command(0X50) + self._data(0x37) + + self._command(0x30) + self._data(0x39) # PLL设定 + + self._command(0x61) # 像素设定 + self._data(0xC8) # 200像素 + self._data(0x00) # 200像素 + self._data(0xC8) + + self._command(0x82) # vcom设定 + self._data(0x18) + + self.lut_bw() + self.lut_red() + + # brief: display image on eink + # img_r: red image + # img_bw: b/w image + def display(self, img_r, img_bw = None): + img1 = image.Image() # handle image + img1 = img1.resize(self.width, self.height) + + if(img_bw == None): + self._command(0x10) # write "B/W" data to SRAM. 0x00:black + for i in range(10000): + self._data(0xff) + else: + img1.draw_image(img_bw, 0, 0) + # Parameter 'fov' is to slove data loss issues + img1.rotation_corr(x_rotation=self.rotation, fov=2) + img_bytes = img1.to_bytes() # That's "self.width*self.height*2" bytes + self._command(0x10) # write "B/W" data to SRAM 0x00:black,0xff:white + for i in range(0, self.width*self.height*2, 16): + b = 0 + for j in range(0, 8, 2): + if img_bytes[i+j] or img_bytes[i+j+1]: + b = b | (0xc0 >> j) + self._data(~b) + b = 0 + for j in range(8, 16, 2): + if img_bytes[i+j] or img_bytes[i+j+1]: + b = b | (0xc0 >> j-8) + self._data(~b) + + img1.draw_image(img_r, 0, 0) + # Parameter 'fov' is to slove data loss issues + img1.rotation_corr(x_rotation=180, fov=2) + img_bytes = img1.to_bytes() # That's "self.width*self.height*2" bytes + self._command(0x13) # write "RED" data to SRAM 0x00:red,0xff:white + for i in range(0, self.width*self.height*2, 16): + b = 0 + for j in range(0, 16, 2): + if img_bytes[i+j] or img_bytes[i+j+1]: + b = b | (0x80 >> j//2) + self._data(~b) + + self._command(0x12) # display refresh + self.wait_until_idle() + + def wait_until_idle(self): + for i in range(10): + sleep_ms(100) + if self.busy.value() != BUSY: + return True + print('self.busy', self.busy.value()) + return False + + def lut_bw(self): + self._command(0x20, SPEINK.lut_vcom0) + self._command(0x21, SPEINK.lut_w) + self._command(0x22, SPEINK.lut_b) + self._command(0x23, SPEINK.lut_g1) + self._command(0x24, SPEINK.lut_g2) + + def lut_red(self): + self._command(0x25, SPEINK.lut_vcom1) + self._command(0x26, SPEINK.lut_red0) + self._command(0x27, SPEINK.lut_red1) + + # enter deep sleep A0=1, A0=0 power on + def sleep(self): + self._command(0x50) + self._data(0xf7) + + self._command(0x02) + self.wait_until_idle() + self._data(0x07) + self._command(0xa5) + + +if __name__ == "__main__": + from Maix import GPIO + from fpioa_manager import fm + from machine import SPI + + # MaixCube | SPMOD + # [7 |VCC] [RST|3V3] + # [15 | 21] [D/C|SCK] + # [20 | 8] [CS |SI ] + # [GND| 6] [GND|BL ] + ################### config ################### + SPI_EINK_NUM = SPI.SPI1 + SPI_EINK_DC_PIN_NUM = const(15) + SPI_EINK_BUSY_PIN_NUM = const(6) + SPI_EINK_RST_PIN_NUM = const(7) + SPI_EINK_CS_PIN_NUM = const(20) + SPI_EINK_SCK_PIN_NUM = const(21) + SPI_EINK_MOSI_PIN_NUM = const(8) + SPI_EINK_FREQ_KHZ = const(600) + ############################################## + + spi1 = SPI(SPI_EINK_NUM, mode=SPI.MODE_MASTER, baudrate=SPI_EINK_FREQ_KHZ * 1000, + polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=SPI_EINK_SCK_PIN_NUM, mosi=SPI_EINK_MOSI_PIN_NUM) + + fm.register(SPI_EINK_CS_PIN_NUM, fm.fpioa.GPIOHS20, force=True) + fm.register(SPI_EINK_DC_PIN_NUM, fm.fpioa.GPIOHS15, force=True) + fm.register(SPI_EINK_BUSY_PIN_NUM, fm.fpioa.GPIOHS6, force=True) + fm.register(SPI_EINK_RST_PIN_NUM, fm.fpioa.GPIOHS7, force=True) + + cs = GPIO(GPIO.GPIOHS20, GPIO.OUT) + dc = GPIO(GPIO.GPIOHS15, GPIO.OUT) + busy = GPIO(GPIO.GPIOHS6, GPIO.IN, GPIO.PULL_DOWN) + rst = GPIO(GPIO.GPIOHS7, GPIO.OUT) + + epd = SPEINK(spi1, cs, dc, rst, busy, SPEINK_WIDTH, SPEINK_HEIGHT, SPEINK_ROTATION) + epd.init() + + # red image + img_r = image.Image() + img_r = img_r.resize(SPEINK_WIDTH, SPEINK_HEIGHT) + img_r.draw_line(0, 0, 100, 100) + img_r.draw_circle(50, 50, 20) + img_r.draw_rectangle(80, 80, 30, 30) + + # bw image + img_bw = image.Image() + img_bw = img_bw.resize(SPEINK_WIDTH, SPEINK_HEIGHT) + img_bw.draw_line(100, 50, 200, 100) + img_bw.draw_circle(80, 80, 30) + img_bw.draw_rectangle(10, 10, 60, 60) + + epd.display(img_r, img_bw) + epd.sleep() diff --git a/modules/spmod/sp_ethernet/demo_ethernet_tcp.py b/modules/spmod/sp_ethernet/demo_ethernet_tcp.py new file mode 100644 index 0000000..7e9e59a --- /dev/null +++ b/modules/spmod/sp_ethernet/demo_ethernet_tcp.py @@ -0,0 +1,38 @@ +import network, socket, time +from machine import SPI +from Maix import GPIO +from fpioa_manager import fm + +################ config ################ +server_ip = "192.168.0.141" +server_port = 8000 + +WIZNET5K_SPI_SCK = 21 +WIZNET5K_SPI_MOSI = 8 +WIZNET5K_SPI_MISO = 15 +WIZNET5K_SPI_CS = 20 +####################################### + +addr = (server_ip, server_port) +spi1 = SPI(4, mode=SPI.MODE_MASTER, baudrate=600 * 1000, + polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=WIZNET5K_SPI_SCK, mosi=WIZNET5K_SPI_MOSI, miso = WIZNET5K_SPI_MISO) + +# create wiznet5k nic +nic = network.WIZNET5K(spi = spi1, cs = WIZNET5K_SPI_CS) +print("Static IP: ", nic.ifconfig()) + + +############################## TCP Test ############################## +# The TCP server needs to be pre-started +sock = socket.socket() +sock.connect(addr) +while 1: + sock.send("Client send: Hello TCP\n") + try: + data = sock.recv(10) + print("Recv from Server: ", data) + except Exception as e: + print(e) + time.sleep(500) +sock.close() +############################ TCP Test end ############################ \ No newline at end of file diff --git a/modules/spmod/sp_ethernet/demo_ethernet_udp.py b/modules/spmod/sp_ethernet/demo_ethernet_udp.py new file mode 100644 index 0000000..f060039 --- /dev/null +++ b/modules/spmod/sp_ethernet/demo_ethernet_udp.py @@ -0,0 +1,38 @@ +import network, socket, time +from machine import SPI +from Maix import GPIO +from fpioa_manager import fm + +################ config ################ +server_ip = "192.168.0.141" +server_port = 8000 + +WIZNET5K_SPI_SCK = 21 +WIZNET5K_SPI_MOSI = 8 +WIZNET5K_SPI_MISO = 15 +WIZNET5K_SPI_CS = 20 +####################################### + +addr = (server_ip, server_port) +spi1 = SPI(4, mode=SPI.MODE_MASTER, baudrate=600 * 1000, + polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=WIZNET5K_SPI_SCK, mosi=WIZNET5K_SPI_MOSI, miso = WIZNET5K_SPI_MISO) + +# create wiznet5k nic +nic = network.WIZNET5K(spi = spi1, cs = WIZNET5K_SPI_CS) +print("Static IP: ", nic.ifconfig()) + +############################# UDP Test ############################## +# The server must first know the client's IP and port number through the message sent by the client before it send the message to the client +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +sock.settimeout(5) + +while True: + sock.sendto("Client send: hello UDP\n".encode(),addr) + try: + data, addr1 = sock.recvfrom(10) + print("Recv from server: ", data) + except Exception as e: + pass + time.sleep_ms(500) +sock.close() +########################### UDP Test end ############################ \ No newline at end of file diff --git a/modules/spmod/sp_lcd114/demo_sp_lcd114.py b/modules/spmod/sp_lcd114/demo_sp_lcd114.py new file mode 100644 index 0000000..6a51900 --- /dev/null +++ b/modules/spmod/sp_lcd114/demo_sp_lcd114.py @@ -0,0 +1,224 @@ +from time import sleep_ms +import image +from micropython import const + +IPS_WIDTH = const(240) +IPS_HEIGHT = const(135) +IPS_MODE = const(3) # 0 1 horizontal 2 3 vertical + +class SPLCD114: + def __init__(self, spi, cs, dc, rst, busy, width, height, mode): + self.spi = spi + self.cs = cs + self.dc = dc + self.rst = rst + self.busy = busy + self.width = width + self.height = height + self.mode = mode + self.init() + + def init(self): + self.rst.value(0) + sleep_ms(10) + self.rst.value(1) + sleep_ms(10) + + self._command(0x11) + sleep_ms(10) + self._command(0x36) # set horizontal or vertical + if self.mode == 0: + self._data(0x00) + elif self.mode == 1: + self._data(0xc0) + elif self.mode == 2: + self._data(0x70) + else: + self._data(0xa0) + + self._command(0x3a) + self._data(0x05) + + self._command(0xb2) + self._data(0x0c) + self._data(0x0c) + self._data(0x00) + self._data(0x33) + self._data(0x33) + + self._command(0xb7) + self._data(0x35) + + self._command(0xBB) + self._data(0x19) + + self._command(0xC0) + self._data(0x2C) + + self._command(0xC2) + self._data(0x01) + + self._command(0xC3) + self._data(0x12) + + self._command(0xC4) + self._data(0x20) + + self._command(0xC6) + self._data(0x0F) + + self._command(0xD0) + self._data(0xA4) + self._data(0xA1) + + self._command(0xE0) + self._data(0xD0) + self._data(0x04) + self._data(0x0D) + self._data(0x11) + self._data(0x13) + self._data(0x2B) + self._data(0x3F) + self._data(0x54) + self._data(0x4C) + self._data(0x18) + self._data(0x0D) + self._data(0x0B) + self._data(0x1F) + self._data(0x23) + + self._command(0xE1) + self._data(0xD0) + self._data(0x04) + self._data(0x0C) + self._data(0x11) + self._data(0x13) + self._data(0x2C) + self._data(0x3F) + self._data(0x44) + self._data(0x51) + self._data(0x2F) + self._data(0x1F) + self._data(0x1F) + self._data(0x20) + self._data(0x23) + + self._command(0x21) + + self._command(0x29) + + self.busy.value(0) + + def _command(self,cmd): + self.dc.value(0) + self.cs.value(0) + self.spi.write(cmd) + self.cs.value(1) + self.dc.value(1) + + def _data(self,data): + self.dc.value(1) + self.cs.value(0) + self.spi.write(data) + self.cs.value(1) + + def _data_16b(self,data): + self._data(data >> 8) + self._data(data & 0xff) + + def _address_set(self,x1,y1,x2,y2): + if self.mode == 0: + self._command(0x2a) #列地址设置 + self._data_16b(x1 + 52) + self._data_16b(x2 + 52) + self._command(0x2b) #行地址设置 + self._data_16b(y1 + 40) + self._data_16b(y2 + 40) + self._command(0x2c) #储存器写 + elif self.mode == 1: + self._command(0x2a) #列地址设置 + self._data_16b(x1 + 53) + self._data_16b(x2 + 53) + self._command(0x2b) #行地址设置 + self._data_16b(y1 + 40) + self._data_16b(y2 + 40) + self._command(0x2c) #储存器写 + elif self.mode == 2: + self._command(0x2a) #列地址设置 + self._data_16b(x1 + 40) + self._data_16b(x2 + 40) + self._command(0x2b) #行地址设置 + self._data_16b(y1 + 53) + self._data_16b(y2 + 53) + self._command(0x2c) #储存器写 + else: + self._command(0x2a) #列地址设置 + self._data_16b(x1 + 40) + self._data_16b(x2 + 40) + self._command(0x2b) #行地址设置 + self._data_16b(y1 + 52) + self._data_16b(y2 + 52) + self._command(0x2c) #储存器写 + + def display(self,img): + img1 = image.Image() + img1 = img1.resize(self.width,self.height) + img1.draw_image(img, 0, 0) + img_bytes = img1.to_bytes() + self._address_set(0,0,self.width-1,self.height-1) + self._data(img_bytes) + +if __name__ == "__main__": + from Maix import GPIO + from fpioa_manager import fm + from machine import SPI + from micropython import const + + # SPMOD |MaixCube + # [7 |VCC] [RST|3V3] + # [15 | 21] [D/C|SCK] + # [20 | 8] [CS |SI ] + # [GND| 6] [GND|BL ] + + ################### config ################### + SPI_LCD_NUM = SPI.SPI1 + SPI_LCD_DC_PIN_NUM = const(15) + SPI_LCD_BUSY_PIN_NUM = const(6) + SPI_LCD_RST_PIN_NUM = const(7) + SPI_LCD_CS_PIN_NUM = const(20) + SPI_LCD_SCK_PIN_NUM = const(21) + SPI_LCD_MOSI_PIN_NUM = const(8) + SPI_LCD_FREQ_KHZ = const(600) + ############################################## + + # 21: SPI_LCD_SCK_PIN_NUM; 8: SPI_LCD_MOSI_PIN_NUM; + spi1 = SPI(SPI_LCD_NUM, mode=SPI.MODE_MASTER, baudrate=SPI_LCD_FREQ_KHZ * 1000, + polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=SPI_LCD_SCK_PIN_NUM, mosi=SPI_LCD_MOSI_PIN_NUM) + + # 20: SPI_LCD_CS_PIN_NUM; + fm.register(SPI_LCD_CS_PIN_NUM, fm.fpioa.GPIOHS20, force=True) + # 15: SPI_LCD_DC_PIN_NUM; + fm.register(SPI_LCD_DC_PIN_NUM, fm.fpioa.GPIOHS15, force=True) + # 6: SPI_LCD_BUSY_PIN_NUM; + fm.register(SPI_LCD_BUSY_PIN_NUM, fm.fpioa.GPIOHS6, force=True) + # 7: SPI_LCD_RST_PIN_NUM; + fm.register(SPI_LCD_RST_PIN_NUM, fm.fpioa.GPIOHS7, force=True) + + # set gpiohs work mode to output mode + cs = GPIO(GPIO.GPIOHS20, GPIO.OUT) + dc = GPIO(GPIO.GPIOHS15, GPIO.OUT) + busy = GPIO(GPIO.GPIOHS6, GPIO.OUT) + rst = GPIO(GPIO.GPIOHS7, GPIO.OUT) + + ips = SPLCD114(spi1, cs, dc, rst, busy, IPS_WIDTH, IPS_HEIGHT, IPS_MODE) + + img = image.Image() + img.draw_line(0, 0, 100, 100) + img.draw_circle(50, 50, 20) + img.draw_rectangle(80, 80, 30, 30) + img.draw_circle(70, 70, 8) + img.draw_circle(70, 160, 15) + img.draw_circle(170, 70, 8) + img.draw_circle(110, 40, 15) + + ips.display(img) diff --git a/modules/spmod/sp_lora/demo_sp_lora.py b/modules/spmod/sp_lora/demo_sp_lora.py new file mode 100644 index 0000000..703fa75 --- /dev/null +++ b/modules/spmod/sp_lora/demo_sp_lora.py @@ -0,0 +1,470 @@ +# DATE: 2020-12-3 +import gc +import machine + +PA_OUTPUT_RFO_PIN = 0 +PA_OUTPUT_PA_BOOST_PIN = 1 + +# registers +REG_FIFO = 0x00 +REG_OP_MODE = 0x01 +REG_FRF_MSB = 0x06 +REG_FRF_MID = 0x07 +REG_FRF_LSB = 0x08 +REG_PA_CONFIG = 0x09 +REG_LNA = 0x0c +REG_FIFO_ADDR_PTR = 0x0d + +REG_FIFO_TX_BASE_ADDR = 0x0e +FifoTxBaseAddr = 0x00 +# FifoTxBaseAddr = 0x80 + +REG_FIFO_RX_BASE_ADDR = 0x0f +FifoRxBaseAddr = 0x00 +REG_FIFO_RX_CURRENT_ADDR = 0x10 +REG_IRQ_FLAGS_MASK = 0x11 +REG_IRQ_FLAGS = 0x12 +REG_RX_NB_BYTES = 0x13 +REG_PKT_RSSI_VALUE = 0x1a +REG_PKT_SNR_VALUE = 0x1b +REG_MODEM_CONFIG_1 = 0x1d +REG_MODEM_CONFIG_2 = 0x1e +REG_PREAMBLE_MSB = 0x20 +REG_PREAMBLE_LSB = 0x21 +REG_PAYLOAD_LENGTH = 0x22 +REG_FIFO_RX_BYTE_ADDR = 0x25 +REG_MODEM_CONFIG_3 = 0x26 +REG_RSSI_WIDEBAND = 0x2c +REG_DETECTION_OPTIMIZE = 0x31 +REG_DETECTION_THRESHOLD = 0x37 +REG_SYNC_WORD = 0x39 +REG_DIO_MAPPING_1 = 0x40 +REG_VERSION = 0x42 + +# modes +MODE_LONG_RANGE_MODE = 0x80 # bit 7: 1 => LoRa mode +MODE_SLEEP = 0x00 +MODE_STDBY = 0x01 +MODE_TX = 0x03 +MODE_RX_CONTINUOUS = 0x05 +MODE_RX_SINGLE = 0x06 + +# PA config +PA_BOOST = 0x80 + +# IRQ masks +IRQ_TX_DONE_MASK = 0x08 +IRQ_PAYLOAD_CRC_ERROR_MASK = 0x20 +IRQ_RX_DONE_MASK = 0x40 +IRQ_RX_TIME_OUT_MASK = 0x80 + +# Buffer size +MAX_PKT_LENGTH = 255 + + + +class SX127x: + + # The controller can be ESP8266, ESP32, Raspberry Pi, or a PC. + # The controller needs to provide an interface consisted of: + # 1. a SPI, with transfer function. + # 2. a reset pin, with low(), high() functions. + # 3. IRQ pinS , to be triggered by RFM96W's DIO0~5 pins. These pins each has two functions: + # 3.1 set_handler_for_irq_on_rising_edge() + # 3.2 detach_irq() + # 4. a function to blink on-board LED. + + def __init__(self, + spi, + pin_ss, + name = 'SX127x', + parameters = {'frequency' : 433E6, 'tx_power_level': 2, 'signal_bandwidth': 125E3, + 'spreading_factor': 8, 'coding_rate': 5, 'preamble_length': 8, + 'implicitHeader' : False, 'sync_word': 0x12, 'enable_CRC': False}, + onReceive = None): + + self.name = name + self.parameters = parameters + self._onReceive = onReceive + self._lock = False + self.spi = spi + self.pin_ss = pin_ss + + def init(self, parameters = None): + if parameters: + self.parameters = parameters + + # check version + version = self.readRegister(REG_VERSION) + if version != 0x12: + raise Exception('Invalid version: ', version) + + # put in LoRa and sleep mode + self.sleep() + + # config + self.setFrequency(self.parameters['frequency']) + self.setSignalBandwidth(self.parameters['signal_bandwidth']) + + # set LNA boost + self.writeRegister(REG_LNA, self.readRegister(REG_LNA) | 0x03) + + # set auto AGC + self.writeRegister(REG_MODEM_CONFIG_3, 0x04) + + self.setTxPower(self.parameters['tx_power_level']) + self._implicitHeaderMode = None + self.implicitHeaderMode(self.parameters['implicitHeader']) + self.setSpreadingFactor(self.parameters['spreading_factor']) + self.setCodingRate(self.parameters['coding_rate']) + self.setPreambleLength(self.parameters['preamble_length']) + self.setSyncWord(self.parameters['sync_word']) + self.enableCRC(self.parameters['enable_CRC']) + + # set LowDataRateOptimize flag if symbol time > 16ms (default disable on reset) + # self.writeRegister(REG_MODEM_CONFIG_3, self.readRegister(REG_MODEM_CONFIG_3) & 0xF7) # default disable on reset + if 1000 / (self.parameters['signal_bandwidth'] / 2 ** self.parameters['spreading_factor']) > 16: + self.writeRegister(REG_MODEM_CONFIG_3, self.readRegister(REG_MODEM_CONFIG_3) | 0x08) + + # set base addresses + self.writeRegister(REG_FIFO_TX_BASE_ADDR, FifoTxBaseAddr) + self.writeRegister(REG_FIFO_RX_BASE_ADDR, FifoRxBaseAddr) + + self.standby() + + + def beginPacket(self, implicitHeaderMode = False): + self.standby() + self.implicitHeaderMode(implicitHeaderMode) + + # reset FIFO address and paload length + self.writeRegister(REG_FIFO_ADDR_PTR, FifoTxBaseAddr) + self.writeRegister(REG_PAYLOAD_LENGTH, 0) + + + def endPacket(self): + # put in TX mode + self.writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX) + + # wait for TX done, standby automatically on TX_DONE + while (self.readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0: + pass + + # clear IRQ's + self.writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK) + + self.collect_garbage() + + + def write(self, buffer): + currentLength = self.readRegister(REG_PAYLOAD_LENGTH) + size = len(buffer) + + # check size + size = min(size, (MAX_PKT_LENGTH - FifoTxBaseAddr - currentLength)) + + # write data + for i in range(size): + self.writeRegister(REG_FIFO, buffer[i]) + + # update length + self.writeRegister(REG_PAYLOAD_LENGTH, currentLength + size) + return size + + + def aquire_lock(self, lock = False): + if 0: # MicroPython is single threaded, doesn't need lock. + if lock: + while self._lock: + pass + self._lock = True + else: + self._lock = False + + + def println(self, string, implicitHeader = False): + self.aquire_lock(True) # wait until RX_Done, lock and begin writing. + + self.beginPacket(implicitHeader) + self.write(string.encode()) + self.endPacket() + + self.aquire_lock(False) # unlock when done writing + + + def getIrqFlags(self): + irqFlags = self.readRegister(REG_IRQ_FLAGS) + self.writeRegister(REG_IRQ_FLAGS, irqFlags) + return irqFlags + + + def packetRssi(self): + return (self.readRegister(REG_PKT_RSSI_VALUE) - (164 if self._frequency < 868E6 else 157)) + + + def packetSnr(self): + return (self.readRegister(REG_PKT_SNR_VALUE)) * 0.25 + + + def standby(self): + self.writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY) + + + def sleep(self): + self.writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP) + + + def setTxPower(self, level, outputPin = PA_OUTPUT_PA_BOOST_PIN): + if (outputPin == PA_OUTPUT_RFO_PIN): + # RFO + level = min(max(level, 0), 14) + self.writeRegister(REG_PA_CONFIG, 0x70 | level) + + else: + # PA BOOST + level = min(max(level, 2), 17) + self.writeRegister(REG_PA_CONFIG, PA_BOOST | (level - 2)) + + + def setFrequency(self, frequency): + self._frequency = frequency + + frfs = {169E6: (42, 64, 0), + 433E6: (108, 64, 0), + 434E6: (108, 128, 0), + 866E6: (216, 128, 0), + 868E6: (217, 0, 0), + 915E6: (228, 192, 0)} + + self.writeRegister(REG_FRF_MSB, frfs[frequency][0]) + self.writeRegister(REG_FRF_MID, frfs[frequency][1]) + self.writeRegister(REG_FRF_LSB, frfs[frequency][2]) + + + def setSpreadingFactor(self, sf): + sf = min(max(sf, 6), 12) + self.writeRegister(REG_DETECTION_OPTIMIZE, 0xc5 if sf == 6 else 0xc3) + self.writeRegister(REG_DETECTION_THRESHOLD, 0x0c if sf == 6 else 0x0a) + self.writeRegister(REG_MODEM_CONFIG_2, (self.readRegister(REG_MODEM_CONFIG_2) & 0x0f) | ((sf << 4) & 0xf0)) + + + def setSignalBandwidth(self, sbw): + bins = (7.8E3, 10.4E3, 15.6E3, 20.8E3, 31.25E3, 41.7E3, 62.5E3, 125E3, 250E3) + + bw = 9 + for i in range(len(bins)): + if sbw <= bins[i]: + bw = i + break + + self.writeRegister(REG_MODEM_CONFIG_1, (self.readRegister(REG_MODEM_CONFIG_1) & 0x0f) | (bw << 4)) + + + def setCodingRate(self, denominator): + denominator = min(max(denominator, 5), 8) + cr = denominator - 4 + self.writeRegister(REG_MODEM_CONFIG_1, (self.readRegister(REG_MODEM_CONFIG_1) & 0xf1) | (cr << 1)) + + + def setPreambleLength(self, length): + self.writeRegister(REG_PREAMBLE_MSB, (length >> 8) & 0xff) + self.writeRegister(REG_PREAMBLE_LSB, (length >> 0) & 0xff) + + + def enableCRC(self, enable_CRC = False): + modem_config_2 = self.readRegister(REG_MODEM_CONFIG_2) + config = modem_config_2 | 0x04 if enable_CRC else modem_config_2 & 0xfb + self.writeRegister(REG_MODEM_CONFIG_2, config) + + + def setSyncWord(self, sw): + self.writeRegister(REG_SYNC_WORD, sw) + + + # def enable_Rx_Done_IRQ(self, enable = True): + # if enable: + # self.writeRegister(REG_IRQ_FLAGS_MASK, self.readRegister(REG_IRQ_FLAGS_MASK) & ~IRQ_RX_DONE_MASK) + # else: + # self.writeRegister(REG_IRQ_FLAGS_MASK, self.readRegister(REG_IRQ_FLAGS_MASK) | IRQ_RX_DONE_MASK) + # + # + # def dumpRegisters(self): + # for i in range(128): + # print("0x{0:02x}: {1:02x}".format(i, self.readRegister(i))) + + def implicitHeaderMode(self, implicitHeaderMode = False): + if self._implicitHeaderMode != implicitHeaderMode: # set value only if different. + self._implicitHeaderMode = implicitHeaderMode + modem_config_1 = self.readRegister(REG_MODEM_CONFIG_1) + config = modem_config_1 | 0x01 if implicitHeaderMode else modem_config_1 & 0xfe + self.writeRegister(REG_MODEM_CONFIG_1, config) + + + def onReceive(self, callback): + self._onReceive = callback + + if self.pin_RxDone: + if callback: + self.writeRegister(REG_DIO_MAPPING_1, 0x00) + self.pin_RxDone.set_handler_for_irq_on_rising_edge(handler = self.handleOnReceive) + else: + self.pin_RxDone.detach_irq() + + + def receive(self, size = 0): + self.implicitHeaderMode(size > 0) + if size > 0: + self.writeRegister(REG_PAYLOAD_LENGTH, size & 0xff) + + # The last packet always starts at FIFO_RX_CURRENT_ADDR + # no need to reset FIFO_ADDR_PTR + self.writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_CONTINUOUS) + + + # on RPi, interrupt callback is threaded and racing with main thread, + # Needs a lock for accessing FIFO. + # https://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/ + # http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-2 + def handleOnReceive(self, event_source): + self.aquire_lock(True) # lock until TX_Done + + # irqFlags = self.getIrqFlags() should be 0x50 + if (self.getIrqFlags() & IRQ_PAYLOAD_CRC_ERROR_MASK) == 0: + if self._onReceive: + payload = self.read_payload() + self.aquire_lock(False) # unlock when done reading + + self._onReceive(self, payload) + + self.aquire_lock(False) # unlock in any case. + + + def receivedPacket(self, size = 0): + irqFlags = self.getIrqFlags() + self.implicitHeaderMode(size > 0) + if size > 0: + self.writeRegister(REG_PAYLOAD_LENGTH, size & 0xff) + + # if (irqFlags & IRQ_RX_DONE_MASK) and \ + # (irqFlags & IRQ_RX_TIME_OUT_MASK == 0) and \ + # (irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK == 0): + + if (irqFlags == IRQ_RX_DONE_MASK): # RX_DONE only, irqFlags should be 0x40 + # automatically standby when RX_DONE + return True + + elif self.readRegister(REG_OP_MODE) != (MODE_LONG_RANGE_MODE | MODE_RX_SINGLE): + # no packet received. + # reset FIFO address / # enter single RX mode + self.writeRegister(REG_FIFO_ADDR_PTR, FifoRxBaseAddr) + self.writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_SINGLE) + + + def read_payload(self): + # set FIFO address to current RX address + # fifo_rx_current_addr = self.readRegister(REG_FIFO_RX_CURRENT_ADDR) + self.writeRegister(REG_FIFO_ADDR_PTR, self.readRegister(REG_FIFO_RX_CURRENT_ADDR)) + + # read packet length + packetLength = self.readRegister(REG_PAYLOAD_LENGTH) if self._implicitHeaderMode else \ + self.readRegister(REG_RX_NB_BYTES) + + payload = bytearray() + for i in range(packetLength): + payload.append(self.readRegister(REG_FIFO)) + + self.collect_garbage() + return bytes(payload) + + + def readRegister(self, address, byteorder = 'big', signed = False): + response = self.transfer(self.pin_ss, address & 0x7f) + return int.from_bytes(response, byteorder) + + + def writeRegister(self, address, value): + self.transfer(self.pin_ss, address | 0x80, value) + + def transfer(self, cs, address, value = None): + ret = 0 + cs.value(0) + self.spi.write(address) + if value: + self.spi.write(value) + else: + ret = self.spi.read(1) + cs.value(1) + return ret + + def collect_garbage(self): + gc.collect() + # if config_lora.IS_MICROPYTHON: + if 1: + print('[Memory - free: {} allocated: {}]'.format(gc.mem_free(), gc.mem_alloc())) + +def send(lora): + counter = 0 + print("LoRa Sender") + while True: + payload = 'Hello ({0})'.format(counter) + print("Sending packet: \n{}\n".format(payload)) + lora.println(payload) + counter += 1 + time.sleep(5) + +def receive(lora): + print("LoRa Receiver") + + while True: + time.sleep_ms(30) + if lora.receivedPacket(): + try: + payload = lora.read_payload() + print("*** Received message ***\n{}".format(payload.decode())) + except Exception as e: + print(e) + print("with RSSI: {}\n".format(lora.packetRssi)) + +if __name__ == "__main__": + import time + from machine import SPI + from Maix import GPIO + from fpioa_manager import fm + from micropython import const + + ################### config ################### + LORA_RST = const(20) + LORA_CS = const(7) + LORA_SPI_SCK = const(21) + LORA_SPI_MOSI = const(8) + LORA_SPI_MISO = const(15) + LORA_SPI_NUM = SPI.SPI1 + LORA_SPI_FREQ_KHZ = const(100) + ############################################## + + # gpio init + fm.register(LORA_RST, fm.fpioa.GPIOHS20, force=True) # RST + fm.register(LORA_CS, fm.fpioa.GPIOHS7, force=True) # CS + # set gpiohs work mode to output mode + cs = GPIO(GPIO.GPIOHS20, GPIO.OUT) + rst = GPIO(GPIO.GPIOHS7, GPIO.IN) + + spi1 = SPI(LORA_SPI_NUM, mode=SPI.MODE_MASTER, baudrate=LORA_SPI_FREQ_KHZ * 1000, + polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=LORA_SPI_SCK, mosi=LORA_SPI_MOSI, miso = LORA_SPI_MISO) + lora = SX127x(spi=spi1, pin_ss=cs) + + # lora reset + rst.value(0) + time.sleep_ms(10) + rst.value(1) + time.sleep_ms(100) + + lora.init() + +####### receiver ########### + receive(lora) + +######## sender ########### + # send(lora) + + diff --git a/modules/spmod/sp_rfid/demo_sp_rfid.py b/modules/spmod/sp_rfid/demo_sp_rfid.py new file mode 100644 index 0000000..cea2da6 --- /dev/null +++ b/modules/spmod/sp_rfid/demo_sp_rfid.py @@ -0,0 +1,533 @@ +# DATE: 2020-12-18.1 +from Maix import GPIO +from fpioa_manager import fm +from machine import SPI +import time + + +class MFRC522: + NRSTPD = 22 + + MAX_LEN = 16 + + PCD_IDLE = 0x00 + PCD_AUTHENT = 0x0E + PCD_RECEIVE = 0x08 + PCD_TRANSMIT = 0x04 + PCD_TRANSCEIVE = 0x0C + PCD_RESETPHASE = 0x0F + PCD_CALCCRC = 0x03 + + PICC_REQIDL = 0x26 + PICC_REQALL = 0x52 + PICC_ANTICOLL = 0x93 + PICC_SElECTTAG = 0x93 + PICC_AUTHENT1A = 0x60 + PICC_AUTHENT1B = 0x61 + PICC_READ = 0x30 + PICC_WRITE = 0xA0 + PICC_DECREMENT = 0xC0 + PICC_INCREMENT = 0xC1 + PICC_RESTORE = 0xC2 + PICC_TRANSFER = 0xB0 + PICC_HALT = 0x50 + + MI_OK = 0 + MI_NOTAGERR = 1 + MI_ERR = 2 + + Reserved00 = 0x00 + CommandReg = 0x01 + CommIEnReg = 0x02 + DivlEnReg = 0x03 + CommIrqReg = 0x04 + DivIrqReg = 0x05 + ErrorReg = 0x06 + Status1Reg = 0x07 + Status2Reg = 0x08 + FIFODataReg = 0x09 + FIFOLevelReg = 0x0A + WaterLevelReg = 0x0B + ControlReg = 0x0C + BitFramingReg = 0x0D + CollReg = 0x0E + Reserved01 = 0x0F + + Reserved10 = 0x10 + ModeReg = 0x11 + TxModeReg = 0x12 + RxModeReg = 0x13 + TxControlReg = 0x14 + TxAutoReg = 0x15 + TxSelReg = 0x16 + RxSelReg = 0x17 + RxThresholdReg = 0x18 + DemodReg = 0x19 + Reserved11 = 0x1A + Reserved12 = 0x1B + MifareReg = 0x1C + Reserved13 = 0x1D + Reserved14 = 0x1E + SerialSpeedReg = 0x1F + + Reserved20 = 0x20 + CRCResultRegM = 0x21 + CRCResultRegL = 0x22 + Reserved21 = 0x23 + ModWidthReg = 0x24 + Reserved22 = 0x25 + RFCfgReg = 0x26 + GsNReg = 0x27 + CWGsPReg = 0x28 + ModGsPReg = 0x29 + TModeReg = 0x2A + TPrescalerReg = 0x2B + TReloadRegH = 0x2C + TReloadRegL = 0x2D + TCounterValueRegH = 0x2E + TCounterValueRegL = 0x2F + + Reserved30 = 0x30 + TestSel1Reg = 0x31 + TestSel2Reg = 0x32 + TestPinEnReg = 0x33 + TestPinValueReg = 0x34 + TestBusReg = 0x35 + AutoTestReg = 0x36 + VersionReg = 0x37 + AnalogTestReg = 0x38 + TestDAC1Reg = 0x39 + TestDAC2Reg = 0x3A + TestADCReg = 0x3B + Reserved31 = 0x3C + Reserved32 = 0x3D + Reserved33 = 0x3E + Reserved34 = 0x3F + + serNum = [] + + def __init__(self, spi, cs): + self.spi = spi + self.cs = cs + self.MFRC522_Init() + + def MFRC522_Reset(self): + # 打印所有寄存器的值 + # for i in range(0x30): + # val = self.Read_MFRC522(i) + # print("val: [{} -> {}]\r\n".format(hex(i), hex(val))) + val = self.Read_MFRC522(self.VersionReg) + print("version: [{}]".format(hex(val))) + + self.Write_MFRC522(self.CommandReg, self.PCD_RESETPHASE) + + val = 0xFF + t = 0xff + while (val) and (t & 0x10): + val = val - 1 + t = self.Read_MFRC522(self.CommandReg) + time.sleep_ms(1) + + time.sleep_ms(1) + + # 定义发送和接收常用模式 和Mifare卡通讯,CRC初始值0x6363 + self.Write_MFRC522(self.ModeReg, 0x3D) + + self.Write_MFRC522(self.TReloadRegL, 30) # 16位定时器低位 + self.Write_MFRC522(self.TReloadRegH, 0) # 16位定时器高位 + + self.Write_MFRC522(self.TModeReg, 0x8D) # 定义内部定时器的设置 + + self.Write_MFRC522(self.TPrescalerReg, 0x3E) # 设置定时器分频系数 + + self.Write_MFRC522(self.TxAutoReg, 0x40) # 调制发送信号为100%ASK + + def Write_MFRC522(self, addr, val): + self.cs.value(0) + self.spi.write(((addr << 1) & 0x7E)) + self.spi.write(val) + self.cs.value(1) + + def Read_MFRC522(self, addr): + self.cs.value(0) + self.spi.write((((addr << 1) & 0x7E) | 0x80)) + val = self.spi.read(1) + self.cs.value(1) + return val[0] + + def SetBitMask(self, reg, mask): + tmp = self.Read_MFRC522(reg) + self.Write_MFRC522(reg, tmp | mask) + + def ClearBitMask(self, reg, mask): + tmp = self.Read_MFRC522(reg) + self.Write_MFRC522(reg, tmp & (~mask)) + + def AntennaOn(self): + temp = self.Read_MFRC522(self.TxControlReg) + if not (temp & 0x03): + self.SetBitMask(self.TxControlReg, 0x03) + + def AntennaOff(self): + self.ClearBitMask(self.TxControlReg, 0x03) + + # 通过RC522与卡片通信 + def MFRC522_ToCard(self, command, sendData): + backData = [] + backLen = 0 + status = self.MI_ERR + irqEn = 0x00 + waitIRq = 0x00 + lastBits = None + n = 0 + i = 0 + + if command == self.PCD_AUTHENT: # Mifare认证 + irqEn = 0x12 # 允许错误中断请求ErrIEn 允许空闲中断IdleIEn + waitIRq = 0x10 # 认证寻卡等待时候 查询空闲中断标志位 + if command == self.PCD_TRANSCEIVE: # 接收发送 发送接收 + irqEn = 0x77 # 允许TxIEn RxIEn IdleIEn LoAlertIEn ErrIEn TimerIEn + waitIRq = 0x30 # 寻卡等待时候 查询接收中断标志位与 空闲中断标志位 + + # IRqInv置位管脚IRQ与Status1Reg的IRq位的值相反 + self.Write_MFRC522(self.CommIEnReg, irqEn | 0x80) + # Set1该位清零时,CommIRqReg的屏蔽位清零 + self.ClearBitMask(self.CommIrqReg, 0x80) + # 写空闲命令 + self.Write_MFRC522(self.CommandReg, self.PCD_IDLE) + + # 置位FlushBuffer清除内部FIFO的读和写指针以及ErrReg的BufferOvfl标志位被清除 + self.SetBitMask(self.FIFOLevelReg, 0x80) + + while(i < len(sendData)): + self.Write_MFRC522(self.FIFODataReg, sendData[i]) # 写数据进FIFOdata + i = i+1 + + self.Write_MFRC522(self.CommandReg, command) # 写命令 + + if command == self.PCD_TRANSCEIVE: + # StartSend置位启动数据发送 该位与收发命令使用时才有效 + self.SetBitMask(self.BitFramingReg, 0x80) + + i = 1000 * 3 + + # 认证 与寻卡等待时间 + while True: + n = self.Read_MFRC522(self.CommIrqReg) # 查询事件中断 + i = i - 1 + if not ((i != 0) and (not (n & 0x01)) and (not (n & waitIRq))): + break + + self.ClearBitMask(self.BitFramingReg, 0x80) # 清理允许StartSend位 + + if i != 0: + # 读错误标志寄存器BufferOfI CollErr ParityErr ProtocolErr + if not (self.Read_MFRC522(self.ErrorReg) & 0x1B): + status = self.MI_OK + + if n & irqEn & 0x01: + status = self.MI_NOTAGERR + + if command == self.PCD_TRANSCEIVE: + n = self.Read_MFRC522(self.FIFOLevelReg) + lastBits = self.Read_MFRC522(self.ControlReg) & 0x07 + # print("n: {}, {}".format(n, lastBits)) + if lastBits != 0: + backLen = (n-1)*8 + lastBits + else: + backLen = n*8 + + if n == 0: + n = 1 + if n > self.MAX_LEN: + n = self.MAX_LEN + + i = 0 + while i < n: + backData.append(self.Read_MFRC522(self.FIFODataReg)) + i = i + 1 + else: + # print("erro: {}".format(hex(self.Read_MFRC522(self.ErrorReg)))) + status = self.MI_ERR + # print("backlen: {}".format(backLen)) + self.SetBitMask(self.ControlReg, 0x80) + # stop timer now + self.Write_MFRC522(self.CommandReg, self.PCD_IDLE) + return (status, backData, backLen) + + def MFRC522_Request(self, reqMode): + status = None + backBits = None + TagType = [] + + # 清理指示MIFARECyptol单元接通以及所有卡的数据通信被加密的情况 + self.ClearBitMask(self.Status2Reg, 0x08) + # 发送的最后一个字节的 七位 + self.Write_MFRC522(self.BitFramingReg, 0x07) + # TX1,TX2管脚的输出信号传递经发送调制的13.56的能量载波信号 + self.SetBitMask(self.TxControlReg, 0x03) + + TagType.append(reqMode) + (status, backData, backBits) = self.MFRC522_ToCard( + self.PCD_TRANSCEIVE, TagType) + # print("backBits: {}".format(backBits)) + if ((status != self.MI_OK) | (backBits != 0x10)): + status = self.MI_ERR + + return (status, backData) + + def MFRC522_Anticoll(self): + backData = [] + serNumCheck = 0 + + serNum = [] + + self.Write_MFRC522(self.BitFramingReg, 0x00) + + serNum.append(self.PICC_ANTICOLL) + serNum.append(0x20) + + (status, backData, backBits) = self.MFRC522_ToCard( + self.PCD_TRANSCEIVE, serNum) + + if(status == self.MI_OK): + i = 0 + if len(backData) == 5: + while i < 4: + serNumCheck = serNumCheck ^ backData[i] + i = i + 1 + if serNumCheck != backData[i]: + status = self.MI_ERR + else: + status = self.MI_ERR + + return (status, backData) + + def CalulateCRC(self, pIndata): + self.ClearBitMask(self.DivIrqReg, 0x04) + self.SetBitMask(self.FIFOLevelReg, 0x80) + i = 0 + while i < len(pIndata): + self.Write_MFRC522(self.FIFODataReg, pIndata[i]) + i = i + 1 + self.Write_MFRC522(self.CommandReg, self.PCD_CALCCRC) + i = 0xFF + while True: + n = self.Read_MFRC522(self.DivIrqReg) + i = i - 1 + if not ((i != 0) and not (n & 0x04)): + break + pOutData = [] + pOutData.append(self.Read_MFRC522(self.CRCResultRegL)) + pOutData.append(self.Read_MFRC522(self.CRCResultRegM)) + return pOutData + + def MFRC522_SelectTag(self, serNum): + backData = [] + buf = [] + buf.append(self.PICC_SElECTTAG) + buf.append(0x70) + i = 0 + while i < 5: + buf.append(serNum[i]) + i = i + 1 + pOut = self.CalulateCRC(buf) + buf.append(pOut[0]) + buf.append(pOut[1]) + (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buf) + + if (status == self.MI_OK) and (backLen == 0x18): + print("Size: ", str(backData[0])) + return backData[0] + else: + return 0 + + def MFRC522_Auth(self, authMode, BlockAddr, Sectorkey, serNum): + buff = [] + + # First byte should be the authMode (A or B) + buff.append(authMode) + + # Second byte is the trailerBlock (usually 7) + buff.append(BlockAddr) + + # Now we need to append the authKey which usually is 6 bytes of 0xFF + i = 0 + while(i < len(Sectorkey)): + buff.append(Sectorkey[i]) + i = i + 1 + i = 0 + + # Next we append the first 4 bytes of the UID + while(i < 4): + buff.append(serNum[i]) + i = i + 1 + + # Now we start the authentication itself + (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_AUTHENT, buff) + + # Check if an error occurred + if not(status == self.MI_OK): + print("AUTH ERROR!!") + if not (self.Read_MFRC522(self.Status2Reg) & 0x08) != 0: + print("AUTH ERROR(status2reg & 0x08) != 0") + + # Return the status + return status + + def MFRC522_StopCrypto1(self): + self.ClearBitMask(self.Status2Reg, 0x08) + + def MFRC522_Read(self, blockAddr): + recvData = [] + recvData.append(self.PICC_READ) + recvData.append(blockAddr) + pOut = self.CalulateCRC(recvData) + recvData.append(pOut[0]) + recvData.append(pOut[1]) + (status, backData, backLen) = self.MFRC522_ToCard( + self.PCD_TRANSCEIVE, recvData) + if not (status == self.MI_OK): + print("Error while reading!") + i = 0 + if len(backData) == 16: + print("Sector "+str(blockAddr)+" "+str(backData)) + return backData + + def MFRC522_Write(self, blockAddr, writeData): + buff = [] + buff.append(self.PICC_WRITE) + buff.append(blockAddr) + crc = self.CalulateCRC(buff) + buff.append(crc[0]) + buff.append(crc[1]) + (status, backData, backLen) = self.MFRC522_ToCard( + self.PCD_TRANSCEIVE, buff) + if not(status == self.MI_OK) or not(backLen == 4) or not((backData[0] & 0x0F) == 0x0A): + status = self.MI_ERR + + print(str(backLen)+" backdata &0x0F == 0x0A "+str(backData[0] & 0x0F)) + if status == self.MI_OK: + i = 0 + buf = [] + while i < 16: + buf.append(writeData[i]) + i = i + 1 + crc = self.CalulateCRC(buf) + buf.append(crc[0]) + buf.append(crc[1]) + (status, backData, backLen) = self.MFRC522_ToCard( + self.PCD_TRANSCEIVE, buf) + if not(status == self.MI_OK) or not(backLen == 4) or not((backData[0] & 0x0F) == 0x0A): + print("Error while writing") + if status == self.MI_OK: + print("Data written") + return status + + def MFRC522_DumpClassic1K(self, key, uid): + i = 0 + while i < 64: + status = self.MFRC522_Auth(self.PICC_AUTHENT1A, i, key, uid) + # Check if authenticated + if status == self.MI_OK: + self.MFRC522_Read(i) + else: + print("Authentication error") + i = i+1 + + def MFRC522_Init(self): + self.MFRC522_Reset() + self.M500PcdConfigISOType('A') + time.sleep_ms(2) + self.AntennaOn() # 开天线 + + def M500PcdConfigISOType(self, ucType): + if ucType == 'A': # ISO14443_A + self.ClearBitMask(self.Status2Reg, 0x08) + self.Write_MFRC522(self.ModeReg, 0x3D) # 3F + self.Write_MFRC522(self.RxSelReg, 0x86) # 84 + self.Write_MFRC522(self.RFCfgReg, 0x7F) # 4F + self.Write_MFRC522(self.TReloadRegL, 30) + self.Write_MFRC522(self.TReloadRegH, 0) + self.Write_MFRC522(self.TModeReg, 0x8D) + self.Write_MFRC522(self.TPrescalerReg, 0x3E) + else: + print("unk ISO type\r\n") + +if __name__ == "__main__": + time.sleep(2) + from micropython import const + ################### config ################### + CS_NUM = const(20) + SPI_FREQ_KHZ = const(600) + SPI_SCK = const(21) + SPI_MOSI = const(8) + SPI_MISO = const(15) + ############################################# + + continue_reading = True + + # 20: CS_NUM; + fm.register(CS_NUM, fm.fpioa.GPIOHS20, force=True) + + # set gpiohs work mode to output mode + cs = GPIO(GPIO.GPIOHS20, GPIO.OUT) + + spi1 = SPI(SPI.SPI_SOFT, mode=SPI.MODE_MASTER, baudrate=SPI_FREQ_KHZ * 1000, + polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=SPI_SCK, mosi=SPI_MOSI, miso=SPI_MISO) + + # Create an object of the class MFRC522 + MIFAREReader = MFRC522(spi1, cs) + + # Welcome message + print("Welcome to the MFRC522 data read/write example") + + # This loop keeps checking for chips. If one is near it will get the UID and authenticate + while continue_reading: + time.sleep_ms(300) + # Scan for cards + (status, ataq) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQALL) + + # If a card is found + if status == MIFAREReader.MI_OK: + print("Card detected type: ",hex(ataq[0]<<8|ataq[1])) + # Get the UID of the card + (status, uid) = MIFAREReader.MFRC522_Anticoll() + + # If we have the UID, continue + if status == MIFAREReader.MI_OK: + + # Print UID + print("Card read UID: " + + str(uid[0])+","+str(uid[1])+","+str(uid[2])+","+str(uid[3])) + + # This is the default key of M1(S50) for authentication + key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] + + # Select the scanned tag + MIFAREReader.MFRC522_SelectTag(uid) + + # Authenticate + status = MIFAREReader.MFRC522_Auth( + MIFAREReader.PICC_AUTHENT1A, 0x12, key, uid) + + # Check if authenticated + if status == MIFAREReader.MI_OK: + data = [] + # Fill the data with 0~16 + for x in range(0, 16): + data.append(x) + + # Write the data + print("Sector 11 will now be filled with 1~16:") + status = MIFAREReader.MFRC522_Write(0x12, data) + + if status == MIFAREReader.MI_OK: + print("start to read") + # read the data + MIFAREReader.MFRC522_Read(0x12) + + # Stop + MIFAREReader.MFRC522_StopCrypto1() + else: + print("Authentication error") diff --git a/modules/spmod/sp_tof/demo_vl53l0x.py b/modules/spmod/sp_tof/demo_vl53l0x.py new file mode 100644 index 0000000..0682a3d --- /dev/null +++ b/modules/spmod/sp_tof/demo_vl53l0x.py @@ -0,0 +1,327 @@ +# DATE: 2020-12-3 +from machine import I2C +from fpioa_manager import fm +from micropython import const +import struct +import time, utime +from Maix import GPIO +import ustruct + +_IO_TIMEOUT = 1000 +_SYSRANGE_START = const(0x00) +_EXTSUP_HV = const(0x89) +_MSRC_CONFIG = const(0x60) +_FINAL_RATE_RTN_LIMIT = const(0x44) +_SYSTEM_SEQUENCE = const(0x01) +_SPAD_REF_START = const(0x4f) +_SPAD_ENABLES = const(0xb0) +_REF_EN_START_SELECT = const(0xb6) +_SPAD_NUM_REQUESTED = const(0x4e) +_INTERRUPT_GPIO = const(0x0a) +_INTERRUPT_CLEAR = const(0x0b) +_GPIO_MUX_ACTIVE_HIGH = const(0x84) +_RESULT_INTERRUPT_STATUS = const(0x13) +_RESULT_RANGE_STATUS = const(0x14) +_OSC_CALIBRATE = const(0xf8) +_MEASURE_PERIOD = const(0x04) + +class TimeoutError(RuntimeError): + pass + +class VL53L0X: + def __init__(self, i2c, address=0x29): + self.i2c = i2c + self.address = address + self.init() + self._started = False + + def _registers(self, register, values=None, struct='B'): + if values is None: + size = ustruct.calcsize(struct) + data = self.i2c.readfrom_mem(self.address, register, size) + values = ustruct.unpack(struct, data) + return values + data = ustruct.pack(struct, *values) + self.i2c.writeto_mem(self.address, register, data) + + def _register(self, register, value=None, struct='B'): + if value is None: + return self._registers(register, struct=struct)[0] + self._registers(register, (value,), struct=struct) + + def _flag(self, register=0x00, bit=0, value=None): + data = self._register(register) + mask = 1 << bit + if value is None: + return bool(data & mask) + elif value: + data |= mask + else: + data &= ~mask + self._register(register, data) + + def _config(self, *config): + for register, value in config: + self._register(register, value) + + def init(self, power2v8=True): + self._flag(_EXTSUP_HV, 0, power2v8) + self._config( + (0x88, 0x00), + (0x80, 0x01), + (0xff, 0x01), + (0x00, 0x00), + ) + self._stop_variable = self._register(0x91) + self._config( + (0x00, 0x01), + (0xff, 0x00), + (0x80, 0x00), + ) + self._flag(_MSRC_CONFIG, 1, True) + self._flag(_MSRC_CONFIG, 4, True) + self._register(_FINAL_RATE_RTN_LIMIT, int(0.25 * (1 << 7)), + struct='>H') + self._register(_SYSTEM_SEQUENCE, 0xff) + spad_count, is_aperture = self._spad_info() + spad_map = bytearray(self._registers(_SPAD_ENABLES, struct='6B')) + self._config( + (0xff, 0x01), + (_SPAD_REF_START, 0x00), + (_SPAD_NUM_REQUESTED, 0x2c), + (0xff, 0x00), + (_REF_EN_START_SELECT, 0xb4), + ) + spads_enabled = 0 + for i in range(48): + if i < 12 and is_aperture or spads_enabled >= spad_count: + spad_map[i // 8] &= ~(1 << (i >> 2)) + elif spad_map[i // 8] & (1 << (i >> 2)): + spads_enabled += 1 + self._registers(_SPAD_ENABLES, spad_map, struct='6B') + self._config( + (0xff, 0x01), + (0x00, 0x00), + (0xff, 0x00), + (0x09, 0x00), + (0x10, 0x00), + (0x11, 0x00), + (0x24, 0x01), + (0x25, 0xFF), + (0x75, 0x00), + (0xFF, 0x01), + (0x4E, 0x2C), + (0x48, 0x00), + (0x30, 0x20), + (0xFF, 0x00), + (0x30, 0x09), + (0x54, 0x00), + (0x31, 0x04), + (0x32, 0x03), + (0x40, 0x83), + (0x46, 0x25), + (0x60, 0x00), + (0x27, 0x00), + (0x50, 0x06), + (0x51, 0x00), + (0x52, 0x96), + (0x56, 0x08), + (0x57, 0x30), + (0x61, 0x00), + (0x62, 0x00), + (0x64, 0x00), + (0x65, 0x00), + (0x66, 0xA0), + (0xFF, 0x01), + (0x22, 0x32), + (0x47, 0x14), + (0x49, 0xFF), + (0x4A, 0x00), + (0xFF, 0x00), + (0x7A, 0x0A), + (0x7B, 0x00), + (0x78, 0x21), + (0xFF, 0x01), + (0x23, 0x34), + (0x42, 0x00), + (0x44, 0xFF), + (0x45, 0x26), + (0x46, 0x05), + (0x40, 0x40), + (0x0E, 0x06), + (0x20, 0x1A), + (0x43, 0x40), + (0xFF, 0x00), + (0x34, 0x03), + (0x35, 0x44), + (0xFF, 0x01), + (0x31, 0x04), + (0x4B, 0x09), + (0x4C, 0x05), + (0x4D, 0x04), + (0xFF, 0x00), + (0x44, 0x00), + (0x45, 0x20), + (0x47, 0x08), + (0x48, 0x28), + (0x67, 0x00), + (0x70, 0x04), + (0x71, 0x01), + (0x72, 0xFE), + (0x76, 0x00), + (0x77, 0x00), + (0xFF, 0x01), + (0x0D, 0x01), + (0xFF, 0x00), + (0x80, 0x01), + (0x01, 0xF8), + (0xFF, 0x01), + (0x8E, 0x01), + (0x00, 0x01), + (0xFF, 0x00), + (0x80, 0x00), + ) + self._register(_INTERRUPT_GPIO, 0x04) + self._flag(_GPIO_MUX_ACTIVE_HIGH, 4, False) + self._register(_INTERRUPT_CLEAR, 0x01) + self._register(_SYSTEM_SEQUENCE, 0x01) + self._calibrate(0x40) + self._register(_SYSTEM_SEQUENCE, 0x02) + self._calibrate(0x00) + self._register(_SYSTEM_SEQUENCE, 0xe8) + + def _spad_info(self): + self._config( + (0x80, 0x01), + (0xff, 0x01), + (0x00, 0x00), + (0xff, 0x06), + ) + self._flag(0x83, 3, True) + self._config( + (0xff, 0x07), + (0x81, 0x01), + (0x80, 0x01), + (0x94, 0x6b), + (0x83, 0x00), + ) + for timeout in range(_IO_TIMEOUT): + if self._register(0x83): + break + utime.sleep_ms(1) + else: + raise TimeoutError() + self._config( + (0x83, 0x01), + ) + value = self._register(0x92) + self._config( + (0x81, 0x00), + (0xff, 0x06), + ) + self._flag(0x83, 3, False) + self._config( + (0xff, 0x01), + (0x00, 0x01), + (0xff, 0x00), + (0x80, 0x00), + ) + count = value & 0x7f + is_aperture = bool(value & 0b10000000) + return count, is_aperture + + def _calibrate(self, vhv_init_byte): + self._register(_SYSRANGE_START, 0x01 | vhv_init_byte) + for timeout in range(_IO_TIMEOUT): + if self._register(_RESULT_INTERRUPT_STATUS) & 0x07: + break + utime.sleep_ms(1) + else: + raise TimeoutError() + self._register(_INTERRUPT_CLEAR, 0x01) + self._register(_SYSRANGE_START, 0x00) + + def start(self, period=0): + self._config( + (0x80, 0x01), + (0xFF, 0x01), + (0x00, 0x00), + (0x91, self._stop_variable), + (0x00, 0x01), + (0xFF, 0x00), + (0x80, 0x00), + ) + if period: + oscilator = self._register(_OSC_CALIBRATE, struct='>H') + if oscilator: + period *= oscilator + self._register(_MEASURE_PERIOD, period, struct='>H') + self._register(_SYSRANGE_START, 0x04) + else: + self._register(_SYSRANGE_START, 0x02) + self._started = True + + def stop(self): + self._register(_SYSRANGE_START, 0x01) + self._config( + (0xFF, 0x01), + (0x00, 0x00), + (0x91, self._stop_variable), + (0x00, 0x01), + (0xFF, 0x00), + ) + self._started = False + + def read(self): + if not self._started: + self._config( + (0x80, 0x01), + (0xFF, 0x01), + (0x00, 0x00), + (0x91, self._stop_variable), + (0x00, 0x01), + (0xFF, 0x00), + (0x80, 0x00), + (_SYSRANGE_START, 0x01), + ) + for timeout in range(_IO_TIMEOUT): + if not self._register(_SYSRANGE_START) & 0x01: + break + utime.sleep_ms(1) + else: + raise TimeoutError() + for timeout in range(_IO_TIMEOUT): + if self._register(_RESULT_INTERRUPT_STATUS) & 0x07: + break + utime.sleep_ms(1) + else: + raise TimeoutError() + value = self._register(_RESULT_RANGE_STATUS + 10, struct='>H') + self._register(_INTERRUPT_CLEAR, 0x01) + return value + +if __name__ == "__main__": + ################### config ################### + VL53L0X_I2C_NUM = I2C.I2C0 + VL53L0X_FREQ = const(100000) + VL53L0X_SCL = const(6) + VL53L0X_SDA = const(7) + VL53L0X_SHT = const(8) + ############################################## + + # io configure + fm.register(VL53L0X_SHT, fm.fpioa.GPIOHS0, force=True) + XSHUT = GPIO(GPIO.GPIOHS0, GPIO.OUT) + XSHUT.value(1) + + # i2c init + i2c = I2C(VL53L0X_I2C_NUM, freq=VL53L0X_FREQ, scl=VL53L0X_SCL, sda=VL53L0X_SDA) + devices = i2c.scan() + print(devices) + + # create obj and read distance + tof = VL53L0X(i2c) + while True: + mm = tof.read() + utime.sleep_ms(100) + print("{}mm".format(mm)) diff --git a/modules/spmod/spmod_tof/spmod_vl53l1x.py b/modules/spmod/sp_tof/demo_vl53l1x.py similarity index 100% rename from modules/spmod/spmod_tof/spmod_vl53l1x.py rename to modules/spmod/sp_tof/demo_vl53l1x.py diff --git a/modules/spmod/sp_weather/demo_sp_weather.py b/modules/spmod/sp_weather/demo_sp_weather.py new file mode 100755 index 0000000..489e983 --- /dev/null +++ b/modules/spmod/sp_weather/demo_sp_weather.py @@ -0,0 +1,257 @@ +from machine import I2C +import time +from ustruct import unpack, unpack_from +from array import array + +############ QMCX983 config ############ +QMC6983_A1_D1 = 0 +QMC6983_E1 = 1 +QMC7983 = 2 +QMC7983_LOW_SETRESET= 3 +QMC6983_E1_Metal = 4 +QMC7983_Vertical = 5 +QMC7983_Slope = 6 +# QMCX983 default qmc_address. +QMCX983_I2CADDR = 0x2C + +############ BME280 config ############ +# BME280 default bme_address. +BME280_I2CADDR = 0x76 +# Operating Modes +BME280_OSAMPLE_1 = 1 +BME280_OSAMPLE_2 = 2 +BME280_OSAMPLE_4 = 3 +BME280_OSAMPLE_8 = 4 +BME280_OSAMPLE_16 = 5 +BME280_REGISTER_CONTROL_HUM = 0xF2 +BME280_REGISTER_CONTROL = 0xF4 + +class SPWEATHER: + def __init__(self, i2c=None): + if i2c is None: + raise ValueError('An I2C object is required.') + self.i2c = i2c + self.qmc_init() # Magnetic sensor QMC7983 init + self.bme280_init() # Temperature, humidity and pressure sensors BME280 init + + ################## QMCX983 ################## + def qmc_init(self, qmc_address=QMCX983_I2CADDR, **kwargs): + self.qmc_address = qmc_address + self.mag_chip_id = 0 + + self.i2c.writeto_mem(self.qmc_address, 0x09, + bytearray([0x1d])) + chip = self.i2c.readfrom_mem(self.qmc_address, 0x0d, 1) + #print("chip id: " + str(chip)) + print("chip id:", hex(chip[0])) + if 0x31 == chip[0]: + self.mag_chip_id = QMC6983_E1 + elif 0x32 == chip[0]: + self.i2c.writeto_mem(self.qmc_address, 0x2e, bytearray([0x01])) + chip = self.i2c.readfrom_mem(self.qmc_address, 0x2f, 1) + if ((chip[0]&0x04) >>2) != 0: + self.mag_chip_id = QMC6983_E1_Metal + else: + self.i2c.writeto_mem(self.qmc_address, 0x2e, bytearray([0x0f])) + chip = self.i2c.readfrom_mem(self.qmc_address, 0x2f, 1) + if (0x02 == ((chip[0]&0x3C)>>2)): + self.mag_chip_id = QMC7983_Vertical + if (0x03 == ((chip[0]&0x3C)>>2)): + self.mag_chip_id = QMC7983_Slope + else: + return + print("mag_chip_id: ", self.mag_chip_id) + self.i2c.writeto_mem(self.qmc_address, 0x21, bytearray([0x01])) + self.i2c.writeto_mem(self.qmc_address, 0x20, bytearray([0x40])) + if (self.mag_chip_id != QMC6983_A1_D1): + self.i2c.writeto_mem(self.qmc_address, 0x29, bytearray([0x80])) + self.i2c.writeto_mem(self.qmc_address, 0x0a, bytearray([0x0c])) + if (self.mag_chip_id == QMC6983_E1_Metal or self.mag_chip_id == QMC7983_Slope ): + self.i2c.writeto_mem(self.qmc_address, 0x1b, bytearray([0x80])) + self.i2c.writeto_mem(self.qmc_address, 0x0b, bytearray([0x01])) + self.i2c.writeto_mem(self.qmc_address, 0x09, bytearray([0x1d])) + + @property + def qmc_read_xyz(self): + read_data = self.i2c.readfrom_mem(self.qmc_address, 0x00, 6) + #if (self.mag_chip_id >= 3) + raw = bytearray(3) + raw[0] = (read_data[1]<<8) | read_data[0] + raw[1] = (read_data[3]<<8) | read_data[2] + raw[2] = (read_data[5]<<8) | read_data[4] + return (raw[0], raw[1], raw[2]) + # return "({:.1f}|{:.1f}|{:.1f})".format(raw[0]/25.0, raw[1]/25.0, raw[2]/25.0) + ################## QMCX983 End ################## + + ################## BME280 ################## + def bme280_init(self, mode=BME280_OSAMPLE_1, + bme_address=BME280_I2CADDR): + # Check that mode is valid. + if mode not in [BME280_OSAMPLE_1, BME280_OSAMPLE_2, BME280_OSAMPLE_4, + BME280_OSAMPLE_8, BME280_OSAMPLE_16]: + raise ValueError( + 'Unexpected mode value {0}. Set mode to one of ' + 'BME280_ULTRALOWPOWER, BME280_STANDARD, BME280_HIGHRES, or ' + 'BME280_ULTRAHIGHRES'.format(mode)) + self._mode = mode + self.bme_address = bme_address + + # load calibration data + dig_88_a1 = self.i2c.readfrom_mem(self.bme_address, 0x88, 26) + dig_e1_e7 = self.i2c.readfrom_mem(self.bme_address, 0xE1, 7) + self.dig_T1, self.dig_T2, self.dig_T3, self.dig_P1, \ + self.dig_P2, self.dig_P3, self.dig_P4, self.dig_P5, \ + self.dig_P6, self.dig_P7, self.dig_P8, self.dig_P9, \ + _, self.dig_H1 = unpack("> 4) + + self.dig_H6 = unpack_from("> 4 + raw_press = ((readout[0] << 16) | (readout[1] << 8) | readout[2]) >> 4 + # temperature(0xFA): ((msb << 16) | (lsb << 8) | xlsb) >> 4 + raw_temp = ((readout[3] << 16) | (readout[4] << 8) | readout[5]) >> 4 + # humidity(0xFD): (msb << 8) | lsb + raw_hum = (readout[6] << 8) | readout[7] + + result[0] = raw_temp + result[1] = raw_press + result[2] = raw_hum + + def read_compensated_data(self, result=None): + """ Reads the data from the sensor and returns the compensated data. + Args: + result: array of length 3 or alike where the result will be + stored, in temperature, pressure, humidity order. You may use + this to read out the sensor without allocating heap memory + Returns: + array with temperature, pressure, humidity. Will be the one from + the result parameter if not None + """ + self.read_raw_data(self._l3_resultarray) + raw_temp, raw_press, raw_hum = self._l3_resultarray + # temperature + var1 = ((raw_temp >> 3) - (self.dig_T1 << 1)) * (self.dig_T2 >> 11) + var2 = (((((raw_temp >> 4) - self.dig_T1) * + ((raw_temp >> 4) - self.dig_T1)) >> 12) * self.dig_T3) >> 14 + self.t_fine = var1 + var2 + temp = (self.t_fine * 5 + 128) >> 8 + + # pressure + var1 = self.t_fine - 128000 + var2 = var1 * var1 * self.dig_P6 + var2 = var2 + ((var1 * self.dig_P5) << 17) + var2 = var2 + (self.dig_P4 << 35) + var1 = (((var1 * var1 * self.dig_P3) >> 8) + + ((var1 * self.dig_P2) << 12)) + var1 = (((1 << 47) + var1) * self.dig_P1) >> 33 + if var1 == 0: + pressure = 0 + else: + p = 1048576 - raw_press + p = (((p << 31) - var2) * 3125) // var1 + var1 = (self.dig_P9 * (p >> 13) * (p >> 13)) >> 25 + var2 = (self.dig_P8 * p) >> 19 + pressure = ((p + var1 + var2) >> 8) + (self.dig_P7 << 4) + + # humidity + h = self.t_fine - 76800 + h = (((((raw_hum << 14) - (self.dig_H4 << 20) - + (self.dig_H5 * h)) + 16384) + >> 15) * (((((((h * self.dig_H6) >> 10) * + (((h * self.dig_H3) >> 11) + 32768)) >> 10) + + 2097152) * self.dig_H2 + 8192) >> 14)) + h = h - (((((h >> 15) * (h >> 15)) >> 7) * self.dig_H1) >> 4) + h = 0 if h < 0 else h + h = 419430400 if h > 419430400 else h + humidity = h >> 12 + + if result: + result[0] = temp + result[1] = pressure + result[2] = humidity + return result + + return array("i", (temp, pressure, humidity)) + + @property + def bme_values(self): + """ human readable values """ + + t, p, h = self.read_compensated_data() + + p = p // 256 + pi = p // 100 + pd = p - pi * 100 + + hi = h // 1024 + hd = h * 100 // 1024 - hi * 100 + return ("{}C".format(t / 100), "{}.{:02d}hPa".format(pi, pd), + "{}.{:02d}%".format(hi, hd)) + ################## BME280 End ################## + + +################## SP_WEATHER Demo ################## +if __name__ == "__main__": + from machine import I2C + from fpioa_manager import fm + import time + + ############# config ############# + WEATHER_I2C_NUM = I2C.I2C_SOFT + WEATHER_I2C_FREQ_KHZ = 100 + WEATHER_I2C_SCL = 30 + WEATHER_I2C_SDA = 31 + ################################## + + i2c_bus = I2C(WEATHER_I2C_NUM, freq=WEATHER_I2C_FREQ_KHZ*1000, + scl=WEATHER_I2C_SCL, sda=WEATHER_I2C_SDA, gscl = fm.fpioa.GPIOHS1, + gsda = fm.fpioa.GPIOHS2) + i2c_devs_list = i2c_bus.scan() + print("I2C devices:" + str(i2c_devs_list)) + + weather=SPWEATHER(i2c=i2c_bus) # create sp_weather + + while 1: + time.sleep_ms(500) + print(weather.qmc_read_xyz) # QMC7983 read data + print(weather.bme_values) # BME280 read data diff --git a/multimedia/image/anime.py b/multimedia/gui/image/anime.py similarity index 100% rename from multimedia/image/anime.py rename to multimedia/gui/image/anime.py diff --git a/multimedia/image/demo_draw_circle.py b/multimedia/gui/image/demo_draw_circle.py similarity index 100% rename from multimedia/image/demo_draw_circle.py rename to multimedia/gui/image/demo_draw_circle.py diff --git a/multimedia/image/demo_draw_font/image_draw_font.py b/multimedia/gui/image/demo_draw_font/image_draw_font.py similarity index 100% rename from multimedia/image/demo_draw_font/image_draw_font.py rename to multimedia/gui/image/demo_draw_font/image_draw_font.py diff --git a/multimedia/image/demo_draw_font/image_draw_string.py b/multimedia/gui/image/demo_draw_font/image_draw_string.py similarity index 100% rename from multimedia/image/demo_draw_font/image_draw_string.py rename to multimedia/gui/image/demo_draw_font/image_draw_string.py diff --git a/multimedia/image/demo_draw_font/readme.assets/image-20200902175614964.png b/multimedia/gui/image/demo_draw_font/readme.assets/image-20200902175614964.png similarity index 100% rename from multimedia/image/demo_draw_font/readme.assets/image-20200902175614964.png rename to multimedia/gui/image/demo_draw_font/readme.assets/image-20200902175614964.png diff --git a/multimedia/image/demo_draw_font/readme.assets/image-20200902175948599.png b/multimedia/gui/image/demo_draw_font/readme.assets/image-20200902175948599.png similarity index 100% rename from multimedia/image/demo_draw_font/readme.assets/image-20200902175948599.png rename to multimedia/gui/image/demo_draw_font/readme.assets/image-20200902175948599.png diff --git a/multimedia/image/demo_draw_font/readme.assets/image-20200902180153452.png b/multimedia/gui/image/demo_draw_font/readme.assets/image-20200902180153452.png similarity index 100% rename from multimedia/image/demo_draw_font/readme.assets/image-20200902180153452.png rename to multimedia/gui/image/demo_draw_font/readme.assets/image-20200902180153452.png diff --git a/multimedia/image/demo_draw_font/readme.assets/image-20200902180505263.png b/multimedia/gui/image/demo_draw_font/readme.assets/image-20200902180505263.png similarity index 100% rename from multimedia/image/demo_draw_font/readme.assets/image-20200902180505263.png rename to multimedia/gui/image/demo_draw_font/readme.assets/image-20200902180505263.png diff --git a/multimedia/image/demo_draw_font/readme.assets/image-20200902180913322.png b/multimedia/gui/image/demo_draw_font/readme.assets/image-20200902180913322.png similarity index 100% rename from multimedia/image/demo_draw_font/readme.assets/image-20200902180913322.png rename to multimedia/gui/image/demo_draw_font/readme.assets/image-20200902180913322.png diff --git a/multimedia/image/demo_draw_font/readme.assets/image-20200902181130459.png b/multimedia/gui/image/demo_draw_font/readme.assets/image-20200902181130459.png similarity index 100% rename from multimedia/image/demo_draw_font/readme.assets/image-20200902181130459.png rename to multimedia/gui/image/demo_draw_font/readme.assets/image-20200902181130459.png diff --git a/multimedia/image/demo_draw_font/readme.assets/image-20200902181311553.png b/multimedia/gui/image/demo_draw_font/readme.assets/image-20200902181311553.png similarity index 100% rename from multimedia/image/demo_draw_font/readme.assets/image-20200902181311553.png rename to multimedia/gui/image/demo_draw_font/readme.assets/image-20200902181311553.png diff --git a/multimedia/image/demo_draw_font/readme.assets/image-20200902181442677.png b/multimedia/gui/image/demo_draw_font/readme.assets/image-20200902181442677.png similarity index 100% rename from multimedia/image/demo_draw_font/readme.assets/image-20200902181442677.png rename to multimedia/gui/image/demo_draw_font/readme.assets/image-20200902181442677.png diff --git a/multimedia/image/demo_draw_font/readme.assets/image-20200902181645277.png b/multimedia/gui/image/demo_draw_font/readme.assets/image-20200902181645277.png similarity index 100% rename from multimedia/image/demo_draw_font/readme.assets/image-20200902181645277.png rename to multimedia/gui/image/demo_draw_font/readme.assets/image-20200902181645277.png diff --git a/multimedia/image/demo_draw_font/readme.assets/view_image_font.jpg b/multimedia/gui/image/demo_draw_font/readme.assets/view_image_font.jpg similarity index 100% rename from multimedia/image/demo_draw_font/readme.assets/view_image_font.jpg rename to multimedia/gui/image/demo_draw_font/readme.assets/view_image_font.jpg diff --git a/multimedia/image/demo_draw_font/readme.md b/multimedia/gui/image/demo_draw_font/readme.md similarity index 100% rename from multimedia/image/demo_draw_font/readme.md rename to multimedia/gui/image/demo_draw_font/readme.md diff --git a/multimedia/image/demo_draw_font/test_draw_font.py b/multimedia/gui/image/demo_draw_font/test_draw_font.py similarity index 100% rename from multimedia/image/demo_draw_font/test_draw_font.py rename to multimedia/gui/image/demo_draw_font/test_draw_font.py diff --git a/multimedia/image/demo_draw_font/tools/0xA00000_font_uincode_16_16_tblr.Dzk b/multimedia/gui/image/demo_draw_font/tools/0xA00000_font_uincode_16_16_tblr.Dzk similarity index 100% rename from multimedia/image/demo_draw_font/tools/0xA00000_font_uincode_16_16_tblr.Dzk rename to multimedia/gui/image/demo_draw_font/tools/0xA00000_font_uincode_16_16_tblr.Dzk diff --git a/multimedia/image/demo_draw_font/tools/FontGenerator.zip b/multimedia/gui/image/demo_draw_font/tools/FontGenerator.zip similarity index 100% rename from multimedia/image/demo_draw_font/tools/FontGenerator.zip rename to multimedia/gui/image/demo_draw_font/tools/FontGenerator.zip diff --git a/multimedia/image/demo_draw_font/tools/Pc2Lcd2002.zip b/multimedia/gui/image/demo_draw_font/tools/Pc2Lcd2002.zip similarity index 100% rename from multimedia/image/demo_draw_font/tools/Pc2Lcd2002.zip rename to multimedia/gui/image/demo_draw_font/tools/Pc2Lcd2002.zip diff --git a/multimedia/image/demo_rotation_corr.py b/multimedia/gui/image/demo_rotation_corr.py similarity index 100% rename from multimedia/image/demo_rotation_corr.py rename to multimedia/gui/image/demo_rotation_corr.py diff --git a/multimedia/image/demo_save_picture.py b/multimedia/gui/image/demo_save_picture.py similarity index 100% rename from multimedia/image/demo_save_picture.py rename to multimedia/gui/image/demo_save_picture.py diff --git a/multimedia/gui/lvgl/amigo_touchscreen/README.md b/multimedia/gui/lvgl/amigo_touchscreen/README.md new file mode 100644 index 0000000..e9fede8 --- /dev/null +++ b/multimedia/gui/lvgl/amigo_touchscreen/README.md @@ -0,0 +1,4 @@ +LVGL Touchscreen demo for Maix Amigo + +Place touch.py in the device SPIFFS memory (using uPyLoader or MaixPy IDE), restart device and then run test_touch.py + diff --git a/multimedia/gui/lvgl/amigo_touchscreen/test_touch.py b/multimedia/gui/lvgl/amigo_touchscreen/test_touch.py new file mode 100644 index 0000000..cc669c4 --- /dev/null +++ b/multimedia/gui/lvgl/amigo_touchscreen/test_touch.py @@ -0,0 +1,115 @@ +import lvgl as lv +import lvgl_helper as lv_h +import lcd +import time +from machine import Timer +from machine import I2C +from touch import Touch, TouchLow +import KPU as kpu +import gc + +config_touchscreen_support = True +board_m1n = False + +lcd.init() + +TOUCH = None +DEBUG = False + +def read_cb(drv, ptr): + # print(ptr, b) + data = lv.indev_data_t.cast(ptr) + TOUCH.event() + if DEBUG: + print(TOUCH.state, TOUCH.points) + data.point = lv.point_t({'x': TOUCH.points[1][0], 'y': TOUCH.points[1][1]}) + data.state = lv.INDEV_STATE.PR if TOUCH.state == 1 else lv.INDEV_STATE.REL + return False + +if config_touchscreen_support: + i2c = I2C(I2C.I2C0, freq=1000*1000, scl=24, sda=27) # 24 27) + devices = i2c.scan() + print("devs", devices) # devs 0 [16, 38, 52, 56] + TouchLow.config(i2c) + TOUCH = Touch(480, 320, 200) + +lv.init() + +disp_buf1 = lv.disp_buf_t() +buf1_1 = bytearray(320*10) +lv.disp_buf_init(disp_buf1,buf1_1, None, len(buf1_1)//4) +disp_drv = lv.disp_drv_t() +lv.disp_drv_init(disp_drv) +disp_drv.buffer = disp_buf1 + +disp_drv.flush_cb = lv_h.flush +if board_m1n: + disp_drv.hor_res = 240 + disp_drv.ver_res = 240 +else: + disp_drv.hor_res = 480 + disp_drv.ver_res = 320 +lv.disp_drv_register(disp_drv) + +if config_touchscreen_support: + indev_drv = lv.indev_drv_t() + lv.indev_drv_init(indev_drv) + indev_drv.type = lv.INDEV_TYPE.POINTER + indev_drv.read_cb = read_cb + lv.indev_drv_register(indev_drv) + +lv.log_register_print_cb(lambda level,path,line,msg: print('%s(%d): %s' % (path, line, msg))) + +def event_handler(obj, event): + global btn, box, bg + + if event == lv.EVENT.CLICKED: + if obj == btn: + box.set_hidden(0) + bg.set_hidden(0) + elif obj == box: + box.set_hidden(1) + bg.set_hidden(1) + +#create screen object +scr = lv.obj() + +#create button in center with callback +btn = lv.btn(scr) +btn.align(scr, lv.ALIGN.CENTER, 0, 0) +btn.set_event_cb(event_handler) +label = lv.label(btn) +label.set_text("Press me") +label.set_size(20,20) + +#create semi-transparrent background and set it to hidden +bg = lv.obj(scr) +bg.set_pos(0, 0) +bg.set_size(scr.get_width(), scr.get_height()) +modal_style = lv.style_t() +lv.style_copy(modal_style, lv.style_plain_color) +modal_style.body.main_color = modal_style.body.grad_color = lv.color_make(0,0,50) +modal_style.body.opa = 75 +bg.set_style(modal_style) +bg.set_hidden(1) + +#create message box and set it to hidden +box = lv.mbox(scr) +box.set_text("Congratulations, you pressed the button! Now do it again, here"); +box.add_btns(["OK", ""]) +box.set_width(200) +box.set_event_cb(event_handler) +box.align(None, lv.ALIGN.CENTER, 0, 0) +box.set_hidden(1) + +lv.scr_load(scr) + +def on_timer(timer): + lv.tick_inc(5) + lv.task_handler() + gc.collect() + +timer = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PERIODIC, period=5, unit=Timer.UNIT_MS, callback=on_timer, arg=None) + +while True: + pass diff --git a/multimedia/gui/lvgl/amigo_touchscreen/touch.py b/multimedia/gui/lvgl/amigo_touchscreen/touch.py new file mode 100644 index 0000000..13761b0 --- /dev/null +++ b/multimedia/gui/lvgl/amigo_touchscreen/touch.py @@ -0,0 +1,103 @@ +# This file is part of MaixUI +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +import time + +FT_DEVIDE_MODE = 0x00 +FT_ID_G_MODE = 0xA4 +FT_ID_G_THGROUP = 0x80 +FT_ID_G_PERIODACTIVE = 0x88 + +FT6X36_ADDR = 0x38 + +class TouchLow: + i2c3 = None + addr = 0x0 + + def config(i2c3, addr=FT6X36_ADDR): + TouchLow.i2c3 = i2c3 + TouchLow.addr = addr + + def write_reg(reg_addr, buf): + TouchLow.i2c3.writeto_mem(TouchLow.addr, reg_addr, buf, mem_size=8) + + def read_reg(reg_addr, buf_len): + return TouchLow.i2c3.readfrom_mem(TouchLow.addr, reg_addr, buf_len, mem_size=8) + + def config_ft6x36(): + TouchLow.write_reg(FT_DEVIDE_MODE, 0); # 进入正常操作模式 + TouchLow.write_reg(FT_ID_G_THGROUP, 12); # 设置触摸有效值,触摸有效值,12,越小越灵敏 + TouchLow.write_reg(FT_DEVIDE_MODE, 14); # 激活周期,不能小于12,最大14 + + def get_point(): + if TouchLow.i2c3 != None: + #data = self.read_reg(0x01, 1) + #print("get_gesture:" + str(data)) + data = TouchLow.read_reg(0x02, 1) + #print("get_points:" + str(data)) + if (data != None and data[0] == 0x1): + data_buf = TouchLow.read_reg(0x03, 4) + y = ((data_buf[0] & 0x0f) << 8) | (data_buf[1]) + x = ((data_buf[2] & 0x0f) << 8) | (data_buf[3]) + #print("1 point[{}:{}]".format(x,y)) + if ((data_buf[0] & 0xc0) == 0x80): + #print("2 point[({},{}):({},{})]".format( + #x, y, self.width - x, self.height - y)) + return (x, y) + return None + +class Touch: + + idle, press, release = 0, 1, 2 + + def __init__(self, w, h, cycle=1000, invert_y=False): + self.cycle = cycle + self.last_time = 0 + self.points = [(0, 0, 0), (0, 0, 0)] + self.state = Touch.idle + self.width, self.height = w, h + self.invert_y = invert_y + + def event(self): + tmp = TouchLow.get_point() + if tmp != None: + x, y = tmp + + if self.invert_y: + y = self.height - y + if x < 0: x = 0 + if y < 0: y = 0 + + self.last_time = time.ticks_ms() + if self.state != Touch.press: + self.state = Touch.press + self.points[0] = (x, y, time.ticks_ms()) + self.points[1] = (x, y, time.ticks_ms()) + + # timeout return ilde. + if time.ticks_ms() > self.last_time + self.cycle: + if self.state == Touch.release: + self.state = Touch.idle + self.points = [(0, 0, 0), (0, 0, 0)] + return + if self.state == Touch.press: + self.state = Touch.release + return + +if __name__ == "__main__": + + import lcd + from machine import I2C + + i2c = I2C(I2C.I2C3, freq=1000*1000, scl=24, sda=27) # amigo + devices = i2c.scan() + print(devices) + TouchLow.config(i2c) + tmp = Touch(480, 320, 200) + while 1: + tmp.event() + print(tmp.state, tmp.points) diff --git a/application/lvgl/images/blue_flower_32.bin b/multimedia/gui/lvgl/images/blue_flower_32.bin similarity index 100% rename from application/lvgl/images/blue_flower_32.bin rename to multimedia/gui/lvgl/images/blue_flower_32.bin diff --git a/application/lvgl/images/png_decoder_test.png b/multimedia/gui/lvgl/images/png_decoder_test.png similarity index 100% rename from application/lvgl/images/png_decoder_test.png rename to multimedia/gui/lvgl/images/png_decoder_test.png diff --git a/application/lvgl/lvgl_advanced.py b/multimedia/gui/lvgl/lvgl_advanced.py similarity index 100% rename from application/lvgl/lvgl_advanced.py rename to multimedia/gui/lvgl/lvgl_advanced.py diff --git a/application/lvgl/lvgl_button.py b/multimedia/gui/lvgl/lvgl_button.py similarity index 100% rename from application/lvgl/lvgl_button.py rename to multimedia/gui/lvgl/lvgl_button.py diff --git a/application/lvgl/lvgl_button2.py b/multimedia/gui/lvgl/lvgl_button2.py similarity index 100% rename from application/lvgl/lvgl_button2.py rename to multimedia/gui/lvgl/lvgl_button2.py diff --git a/application/lvgl/lvgl_chart_anime.py b/multimedia/gui/lvgl/lvgl_chart_anime.py similarity index 100% rename from application/lvgl/lvgl_chart_anime.py rename to multimedia/gui/lvgl/lvgl_chart_anime.py diff --git a/application/lvgl/lvgl_image.Image.py b/multimedia/gui/lvgl/lvgl_image.Image.py similarity index 100% rename from application/lvgl/lvgl_image.Image.py rename to multimedia/gui/lvgl/lvgl_image.Image.py diff --git a/application/lvgl/lvgl_img.py b/multimedia/gui/lvgl/lvgl_img.py similarity index 100% rename from application/lvgl/lvgl_img.py rename to multimedia/gui/lvgl/lvgl_img.py diff --git a/application/lvgl/lvgl_img_png.py b/multimedia/gui/lvgl/lvgl_img_png.py similarity index 100% rename from application/lvgl/lvgl_img_png.py rename to multimedia/gui/lvgl/lvgl_img_png.py diff --git a/multimedia/gui/lvgl/lvgl_multiple_screens.py b/multimedia/gui/lvgl/lvgl_multiple_screens.py new file mode 100644 index 0000000..b6d9c90 --- /dev/null +++ b/multimedia/gui/lvgl/lvgl_multiple_screens.py @@ -0,0 +1,111 @@ +#this demo shows how to create multiple screens, load and unload them properly without causing memory leak + +import lvgl as lv +import lvgl_helper as lv_h +import lcd +import time +from machine import Timer +from machine import I2C +from touch import Touch, TouchLow +import KPU as kpu +import gc + +config_touchscreen_support = True +board_m1n = False + +lcd.init() + + +TOUCH = None + +def read_cb(drv, ptr): + data = lv.indev_data_t.cast(ptr) + TOUCH.event() + data.point = lv.point_t({'x': TOUCH.points[1][0], 'y': TOUCH.points[1][1]}) + data.state = lv.INDEV_STATE.PR if TOUCH.state == 1 else lv.INDEV_STATE.REL + return False + + +if config_touchscreen_support: + i2c = I2C(I2C.I2C0, freq=1000*1000, scl=24, sda=27) # 24 27) + devices = i2c.scan() + print("devs", devices) # devs 0 [16, 38, 52, 56] + TouchLow.config(i2c) + TOUCH = Touch(480, 320, 200) + +lv.init() + +disp_buf1 = lv.disp_buf_t() +buf1_1 = bytearray(320*10) +lv.disp_buf_init(disp_buf1,buf1_1, None, len(buf1_1)//4) +disp_drv = lv.disp_drv_t() +lv.disp_drv_init(disp_drv) +disp_drv.buffer = disp_buf1 + +disp_drv.flush_cb = lv_h.flush +if board_m1n: + disp_drv.hor_res = 240 + disp_drv.ver_res = 240 +else: + disp_drv.hor_res = 480 + disp_drv.ver_res = 320 +lv.disp_drv_register(disp_drv) + +if config_touchscreen_support: + indev_drv = lv.indev_drv_t() + lv.indev_drv_init(indev_drv) + indev_drv.type = lv.INDEV_TYPE.POINTER + indev_drv.read_cb = read_cb + lv.indev_drv_register(indev_drv) + + +lv.log_register_print_cb(lambda level,path,line,msg: print('%s(%d): %s' % (path, line, msg))) + +class UI: + + def __init__(self): + self.scr1 = self.create_scr1() + self.scr2 = self.create_scr2() + + def create_scr1(self): + scr1 = lv.obj() + btn1 = lv.btn(scr1) + btn1.align(scr1, lv.ALIGN.CENTER, 0, 0) + label1 = lv.label(btn1) + label1.set_text("Button 1") + label1.set_size(20,20) + return scr1 + + def create_scr2(self): + scr2 = lv.obj() + btn2 = lv.btn(scr2) + btn2.align(scr2, lv.ALIGN.CENTER, 0, 0) + label2 = lv.label(btn2) + label2.set_text("Button 2") + label2.set_size(20,20) + return scr2 + +ui = UI() +kpu.memtest() + +def on_timer(timer): + lv.tick_inc(5) + lv.task_handler() + gc.collect() + +timer = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PERIODIC, period=5, unit=Timer.UNIT_MS, callback=on_timer, arg=None) + +while True: + tim = time.ticks_ms() + while time.ticks_ms()-tim < 500: + pass + + lv.scr_load(ui.scr1) + kpu.memtest() + + tim = time.ticks_ms() + while time.ticks_ms()-tim < 500: + pass + + lv.scr_load(ui.scr2) + kpu.memtest() diff --git a/application/lvgl/lvgl_unicode.py b/multimedia/gui/lvgl/lvgl_unicode.py similarity index 100% rename from application/lvgl/lvgl_unicode.py rename to multimedia/gui/lvgl/lvgl_unicode.py diff --git a/modules/maixui/bme280.py b/multimedia/gui/maixui/bme280.py similarity index 100% rename from modules/maixui/bme280.py rename to multimedia/gui/maixui/bme280.py diff --git a/modules/maixui/button.py b/multimedia/gui/maixui/button.py similarity index 100% rename from modules/maixui/button.py rename to multimedia/gui/maixui/button.py diff --git a/modules/maixui/msa301.py b/multimedia/gui/maixui/msa301.py similarity index 100% rename from modules/maixui/msa301.py rename to multimedia/gui/maixui/msa301.py diff --git a/modules/maixui/pmu_axp173.py b/multimedia/gui/maixui/pmu_axp173.py similarity index 100% rename from modules/maixui/pmu_axp173.py rename to multimedia/gui/maixui/pmu_axp173.py diff --git a/modules/maixui/qmcx983.py b/multimedia/gui/maixui/qmcx983.py similarity index 100% rename from modules/maixui/qmcx983.py rename to multimedia/gui/maixui/qmcx983.py diff --git a/modules/maixui/shtxx.py b/multimedia/gui/maixui/shtxx.py similarity index 100% rename from modules/maixui/shtxx.py rename to multimedia/gui/maixui/shtxx.py diff --git a/tools_on_PC/nes_tools/forward_keyboard.py b/multimedia/nes/forward_keyboard.py similarity index 100% rename from tools_on_PC/nes_tools/forward_keyboard.py rename to multimedia/nes/forward_keyboard.py diff --git a/application/nes_amigo_handle_and_sound.py b/multimedia/nes/nes_amigo_handle_and_sound.py similarity index 97% rename from application/nes_amigo_handle_and_sound.py rename to multimedia/nes/nes_amigo_handle_and_sound.py index 467c8b4..1d0a285 100644 --- a/application/nes_amigo_handle_and_sound.py +++ b/multimedia/nes/nes_amigo_handle_and_sound.py @@ -29,7 +29,7 @@ try: nes.init(nes.INPUT) - nes.load("mario.nes") + nes.load("sd/game/mario.nes") for i in range(20000): nes.loop() for i in range(500): diff --git a/multimedia/nes/nes_emulator.py b/multimedia/nes/nes_emulator.py new file mode 100644 index 0000000..9328226 --- /dev/null +++ b/multimedia/nes/nes_emulator.py @@ -0,0 +1,36 @@ +import nes, lcd + +lcd.init(freq=15000000) + +# B A SEL START UP DOWN LEFT RIGHT +# 1 2 4 8 16 32 64 128 +# nes.input(8, 0, 0) # press START +# nes.input(1P, 2P, SYS) + +try: + nes.init(nes.INPUT) + nes.load("mario.nes") + # nes.run("/sd/mario.nes") + for i in range(20000): # wait + nes.loop() + for i in range(500): + nes.loop() + nes.input(8, 0, 0) # input enter + nes.loop() + nes.input(0, 0, 0) + nes.loop() + while True: + nes.loop() # run +finally: + nes.free() + +'''python +try: + nes.init(nes.INPUT) # input + nes.load("mario.nes") # load + while True: + nes.loop() # run +finally: + nes.free() # exit +''' + diff --git a/application/nes_ps2.py b/multimedia/nes/nes_ps2.py similarity index 100% rename from application/nes_ps2.py rename to multimedia/nes/nes_ps2.py diff --git a/application/nes_py_input.py b/multimedia/nes/nes_py_input.py similarity index 100% rename from application/nes_py_input.py rename to multimedia/nes/nes_py_input.py diff --git a/multimedia/speech_recognizer/demo_isolated_word_on_maixdock.py b/multimedia/speech_recognizer/demo_isolated_word_on_maixdock.py index 1eeaeb6..f8f7cec 100644 --- a/multimedia/speech_recognizer/demo_isolated_word_on_maixdock.py +++ b/multimedia/speech_recognizer/demo_isolated_word_on_maixdock.py @@ -87,7 +87,7 @@ img.draw_string(20, 80, "Please speak A or B or C", color=(255, 0, 0), scale=2, mono_space=0) lcd.display(img) print(sr.state()) - print(sr.dts(data)) + print(sr.dtw(data)) if sr.Done == sr.recognize(): res = sr.result() if res != None: diff --git a/multimedia/speech_recognizer/isolated_word.py b/multimedia/speech_recognizer/isolated_word.py index c5f11ba..d612348 100644 --- a/multimedia/speech_recognizer/isolated_word.py +++ b/multimedia/speech_recognizer/isolated_word.py @@ -31,7 +31,7 @@ from speech_recognizer import isolated_word # default: maix dock / maix duino set shift=0 -sr = isolated_word(dmac=2, i2s=I2S.DEVICE_0, size=10, , shift=0) # maix bit set shift=1 +sr = isolated_word(dmac=2, i2s=I2S.DEVICE_0, size=10, shift=0) # maix bit set shift=1 print(sr.size()) print(sr) diff --git a/multimedia/speech_recognizer/speech_recognizer.py b/multimedia/speech_recognizer/speech_recognizer.py deleted file mode 100644 index 1755846..0000000 --- a/multimedia/speech_recognizer/speech_recognizer.py +++ /dev/null @@ -1,155 +0,0 @@ -# It is no longer supported, please use the new interface code. -# 现在已经不被支持,请使用新的接口代码。 -# 2020年11月1日 我留着是用来做应用示例参考的。 -# Untitled - By: Echo - 周一 5月 4 2020 - -import _thread -import os -import json -import time -import utime -from Maix import I2S, GPIO -from fpioa_manager import fm -import struct -from modules import SpeechRecognizer - - -def sr_data_save(s, content, keyword_num, model_num, path): - data = s.get_model_data(keyword_num, model_num) # 原始数据 - # s.print_model(keyword_num, model_num) # 这里打印大量数据, 会到导致后面打印的内容丢失 - with open(path, 'w') as f: - f.write(data) - - -def sr_data_load(s, keyword_num, model_num, frame_num, path): - # print(path) - with open(path, 'r') as f: - data = f.read() - s.add_voice_model(keyword_num, model_num, frame_num, data) - -# ------------------------------------------------------------- - - -# register i2s(i2s0) pin -fm.register(20, fm.fpioa.I2S0_IN_D0, force=True) -fm.register(18, fm.fpioa.I2S0_SCLK, force=True) -fm.register(19, fm.fpioa.I2S0_WS, force=True) - -# close WiFi, if use M1W Core module -if True: - fm.register(8, fm.fpioa.GPIO0, force=True) - wifi_en = GPIO(GPIO.GPIO0, GPIO.OUT) - wifi_en.value(0) - -sample_rate = 8000 -# init i2s(i2s0) -i2s_dev = I2S(I2S.DEVICE_0) - -# config i2s according to speechrecognizer -i2s_dev.channel_config(i2s_dev.CHANNEL_0, - I2S.RECEIVER, - resolution=I2S.RESOLUTION_16_BIT, - cycles=I2S.SCLK_CYCLES_32, - align_mode=I2S.STANDARD_MODE) -i2s_dev.set_sample_rate(sample_rate) -print("------") -s = SpeechRecognizer(i2s_dev) -print("------") -s.set_threshold(0, 0, 20000) # 设置所处环境的噪声阈值, 环境噪声越大设置最后一个参数越大即可, 其余参数暂时无效 -# ------------------------------------------------------------- - -#record = False -record = True - -#load = False -load = True - -save_data = False - -if record == True: - key_word_record = False - tim2 = time.ticks_ms() - - def pins_irq(pin_num): - global key_word_record - global tim2 - if (time.ticks_ms() - tim2) > 800: - key_word_record = not key_word_record - tim2 = time.ticks_ms() - fm.register(16, fm.fpioa.GPIOHS0) - key_boot = GPIO(GPIO.GPIOHS0, GPIO.IN) - key_boot.irq(pins_irq, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT, 7) - keyword_num = 3 - model_num = 3 - # Currently supports a maximum of 10 keywords, each recording a maximum of 4 templates - for i in range(keyword_num): - # Record three keywords, three times each - for j in range(model_num): - print("Press the button to record the {} keyword, the {}".format(i+1, j+1)) - while True: - if key_word_record == True: - break - else: - print('.', end="") - utime.sleep_ms(500) - key_word_record = False - s.record(i, j) - print('wait record complete....') - while (2 != s.get_status()): - print('.', end='') - time.sleep_ms(500) - - #print("frme_num ---->" + str(s.get_model_info(i, j))) - - # s.print_model(i, j) # 这里打印大量数据, 会到导致后面打印的内容丢失 - # utime.sleep_ms(2) - if save_data == True: - content = str(i) + '_' + str(j) # 存储模型名称 - print(content) - file_name = "/sd/sr/" + str(i) + '_' + str(j)+".sr" - sr_data_save(s, content, i, j, file_name) - print("record successful!") - -if load == True: - sr_data_load(s, 0, 0, 33, "/sd/sr/0_0.sr") - sr_data_load(s, 0, 1, 19, "/sd/sr/0_1.sr") - sr_data_load(s, 0, 2, 69, "/sd/sr/0_2.sr") - sr_data_load(s, 1, 0, 22, "/sd/sr/1_0.sr") - sr_data_load(s, 1, 1, 20, "/sd/sr/1_1.sr") - sr_data_load(s, 1, 2, 20, "/sd/sr/1_2.sr") - sr_data_load(s, 2, 0, 27, "/sd/sr/2_0.sr") - sr_data_load(s, 2, 1, 22, "/sd/sr/2_1.sr") - sr_data_load(s, 2, 2, 29, "/sd/sr/2_2.sr") - print("load successful!") - - -def func(): - while 1: - state = s.get_status() - print(state) - time.sleep(1) - - -# s.get_status() -# SR_NONE = 0, -# SR_RECORD_WAIT_SPEACKING = 1, -# SR_RECORD_SUCCESSFUL = 2, -# SR_RECOGNIZER_WAIT_SPEACKING = 3, -# SR_RECOGNIZER_SUCCESSFULL = 4, -# SR_GET_NOISEING = 5, -# -_thread.start_new_thread(func, ()) - -while True: - # recognize - s.recognize() - ret = s.get_result() - if ret > 0: - if ret == 1: - print("ret:{}-{}".format(ret, "red")) - elif ret == 2: - print("ret:{}-{}".format(ret, "green")) - elif ret == 3: - print("ret:{}-{}".format(ret, "blue")) - # else: - # print("--") diff --git a/multimedia/speech_recognizer/test_maix_asr.py b/multimedia/speech_recognizer/test_maix_asr.py index db45661..5bd4b4d 100644 --- a/multimedia/speech_recognizer/test_maix_asr.py +++ b/multimedia/speech_recognizer/test_maix_asr.py @@ -7,17 +7,23 @@ sample_rate = 16000 record_time = 4 #s -#fm.register(8, fm.fpioa.GPIO0, force=True) -#wifi_en = GPIO(GPIO.GPIO0, GPIO.OUT) -#wifi_en.value(0) +#fm.register(8, fm.fpioa.GPIO0, force=True) +#wifi_en = GPIO(GPIO.GPIO0, GPIO.OUT) +#wifi_en.value(0) + +# bit & duino fm.register(20,fm.fpioa.I2S0_IN_D0, force=True) -fm.register(18,fm.fpioa.I2S0_SCLK, force=True) -fm.register(19,fm.fpioa.I2S0_WS, force=True) +fm.register(18,fm.fpioa.I2S0_SCLK, force=True) # bit +fm.register(19,fm.fpioa.I2S0_WS, force=True) # bit + +# fm.register(20,fm.fpioa.I2S0_IN_D0, force=True) # dock +# fm.register(32,fm.fpioa.I2S0_SCLK, force=True) # dock +# fm.register(30,fm.fpioa.I2S0_WS, force=True) # dock rx = I2S(I2S.DEVICE_0) rx.channel_config(rx.CHANNEL_0, rx.RECEIVER, align_mode=I2S.STANDARD_MODE) -#rx.set_sample_rate(sample_rate) +rx.set_sample_rate(sample_rate) print(rx) from speech_recognizer import asr @@ -59,7 +65,7 @@ def on_timer(timer): try: # default: maix dock / maix duino set shift=0 - t = maix_asr(0x500000, I2S.DEVICE_0, 3, shift=0) # maix bit set shift=1 + t = maix_asr(0x500000, I2S.DEVICE_0, 3, shift=1) # maix bit set shift=1 tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PERIODIC, period=64, callback=on_timer, arg=t) tim.start() @@ -71,9 +77,9 @@ def on_timer(timer): #t.run() t.config({ - 'xiao-ai-ya' : 0.3, - 'hao-de-ya' : 0.2, - 'ni-hao-ya' : 0.3, + 'xiao-ai' : 0.3, + 'hao-de' : 0.2, + 'ni-hao' : 0.3, }) print(t.get()) @@ -89,4 +95,4 @@ def on_timer(timer): finally: tim.stop() t.__del__() - del t \ No newline at end of file + del t diff --git a/multimedia/video/demo_video_capture.py b/multimedia/video/demo_video_capture.py new file mode 100644 index 0000000..c6df58d --- /dev/null +++ b/multimedia/video/demo_video_capture.py @@ -0,0 +1,16 @@ +import lcd +import video +import image + +lcd.init() +v = video.open("/sd/badapple_320_240_15fps.avi") +print(v) +img = image.Image() +while True: + status = v.capture(img) + if status != 0: + lcd.display(img) + else: + print("end") + break; +v.__del__() \ No newline at end of file diff --git a/network/README.md b/network/README.md index 8ea729d..2a1f2f4 100644 --- a/network/README.md +++ b/network/README.md @@ -1,15 +1,51 @@ +# Usage +## network +- [network_esp32.py](./network_esp32.py) +- [network_espat.py](./network_espat.py) +- [network_wiznet5k.py](./network_wiznet5k.py) -## Use ESP32 as WiFi module +> 使用 MaixPy IDE 的菜单功能【发送文件到板子】即可作为一个类库使用。 -* Download latest firmware of esp32 [here](https://github.com/sipeed/Maixduino_esp32_fimware/releases) -* Upload firmware to ESP32 by [esptool](https://github.com/espressif/esptool) or other burn tools, e.g. -``` -pip install esptool -esptool.py --chip esp32 --port /dev/ttyUSB1 erase_flash -esptool.py --chip esp32 --port /dev/ttyUSB1 --baud 1500000 write_flash -z 0x0000 maixduino_esp32_firmware_v1.4.0.bin +Use the MaixPy IDE's menu functionality [send files to the board] as a class library. + +```python +from network_esp32 import wifi + +from network_espat import wifi + +from network_wiznet5k import lan ``` -* Then try demo +## example + +> 使用网卡连接到网络后才能进行以下操作。 + +Using the network card to connect to the network to make the following operation. + +- [demo_esp32_ap_scan.py](./demo_esp32_ap_scan.py) +- [demo_esp32_ping.py](./demo_esp32_ping.py) + +- [demo_espat_ap_scan.py](./demo_espat_ap_scan.py) + +- [demo_socket_tcp_client.py](./demo_socket_tcp_client.py) +- (run your pc python3 not maixpy)[demo_socket_tcp_server.py](./demo_socket_tcp_server.py) + +- [demo_socket_udp_client.py](./demo_socket_udp_client.py) +- (run your pc python3 not maixpy)[demo_socket_udp_server.py](./demo_socket_udp_server.py) + +- [demo_socket_mqtt.py](./demo_socket_mqtt.py) + +- [demo_http_get_jpg.py](./demo_http_get_jpg.py) +- [demo_socket_https.py](./demo_socket_https.py) + +- [demo_socket_send_pic.py](./demo_socket_send_pic.py) +- (run your pc python3 not maixpy)[demo_socket_pic_server.py](./demo_socket_pic_server.py) + +## other + +- [demo_espat_ap_test.py](./demo_espat_ap_test.py) +- [espat_upgrade.py](./espat_upgrade.py) +- [demo_esp32_read_adc.py](./demo_esp32_read_adc.py) diff --git a/network/demo_esp32_ap_scan.py b/network/demo_esp32_ap_scan.py new file mode 100644 index 0000000..ed8535b --- /dev/null +++ b/network/demo_esp32_ap_scan.py @@ -0,0 +1,35 @@ +# This file is part of MaixPY +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +# Uasge see readme.md +from network_esp32 import wifi + +wifi.reset() +enc_str = ["OPEN", "", "WPA PSK", "WPA2 PSK", "WPA/WPA2 PSK", "", "", ""] +aps = wifi.nic.scan() +for ap in aps: + print("SSID:{:^20}, ENC:{:>5} , RSSI:{:^20}".format(ap[0], enc_str[ap[1]], ap[2])) + +''' + >>> + raw REPL; CTRL-B to exit + >OK + SSID: Sipeed_2.4G , ENC:WPA/WPA2 PSK , RSSI: -57 + SSID: ChinaNet-Ffdj , ENC:WPA/WPA2 PSK , RSSI: -58 + SSID: wea_615 , ENC:WPA/WPA2 PSK , RSSI: -67 + SSID: ChinaNet-PnAN , ENC:WPA/WPA2 PSK , RSSI: -70 + SSID: wea_613 , ENC:WPA/WPA2 PSK , RSSI: -73 + SSID: ChinaNet-TnSG , ENC:WPA/WPA2 PSK , RSSI: -82 + SSID: chipshine_GUEST , ENC:WPA/WPA2 PSK , RSSI: -83 + SSID: ASUS , ENC:WPA/WPA2 PSK , RSSI: -86 + SSID: gta888 , ENC:WPA/WPA2 PSK , RSSI: -87 + SSID: huahua , ENC:WPA/WPA2 PSK , RSSI: -88 + > + MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 + Type "help()" for more information. + >>> +''' diff --git a/network/demo_esp32_ping.py b/network/demo_esp32_ping.py new file mode 100644 index 0000000..e327558 --- /dev/null +++ b/network/demo_esp32_ping.py @@ -0,0 +1,38 @@ +# This file is part of MaixPY +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +# Uasge see readme.md +from network_esp32 import wifi + +SSID = "Sipeed_2.4G" +PASW = "XXXXXXXX" + +if wifi.isconnected() == False: + for i in range(5): + try: + wifi.reset() + print('try AT connect wifi...') + wifi.connect(SSID, PASW) + if wifi.isconnected(): + break + except Exception as e: + print(e) +print('network state:', wifi.isconnected(), wifi.ifconfig()) + +print("ping baidu.com:", wifi.nic.ping("baidu.com"), "ms") +wifi.nic.disconnect() + +''' + ESP32_SPI firmware version: 1.4.0 + try AT connect wifi... + network state: True ('192.168.0.180', '255.255.255.0', '192.168.0.1') + ping baidu.com: 40 ms + > + MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 + Type "help()" for more information. + >>> +''' diff --git a/network/demo_esp32_read_adc.py b/network/demo_esp32_read_adc.py new file mode 100644 index 0000000..c70fc62 --- /dev/null +++ b/network/demo_esp32_read_adc.py @@ -0,0 +1,58 @@ +# This file is part of MaixPY +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +# Uasge see readme.md +# from network_esp32 import wifi + +import time, network +from Maix import GPIO +from fpioa_manager import fm + +class wifi(): + # IO map for ESP32 on Maixduino + fm.register(25,fm.fpioa.GPIOHS10)#cs + fm.register(8,fm.fpioa.GPIOHS11)#rst + fm.register(9,fm.fpioa.GPIOHS12)#rdy + print("Use Hareware SPI for other maixduino") + fm.register(28,fm.fpioa.SPI1_D0, force=True)#mosi + fm.register(26,fm.fpioa.SPI1_D1, force=True)#miso + fm.register(27,fm.fpioa.SPI1_SCLK, force=True)#sclk + nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10, rst=fm.fpioa.GPIOHS11, rdy=fm.fpioa.GPIOHS12, spi=1) + +print("ESP32_SPI firmware version:", wifi.nic.version()) + +# get ADC0 ADC1 ADC2 +adc = wifi.nic.adc((0,1,2)) +print(adc) + +while True: + try: + # get ADC0~5 + adc = wifi.nic.adc() + except Exception as e: + print(e) + continue + for v in adc: + print("%04d" %(v), end=" ") + print(' : adc') + +''' + MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 + Type "help()" for more information. + >>> + raw REPL; CTRL-B to exit + >OK + (2370, 3102, 3071) + 2017 2753 0977 2709 0963 0855 : adc + 0617 0757 0150 0095 0133 0153 : adc + 1319 1478 0955 0939 0698 0619 : adc + 2403 3231 3299 3298 1483 0779 : adc + 1119 1815 1274 1315 0230 0255 : adc + 0951 0951 0295 0283 0319 0399 : adc + 2175 2769 2576 2579 1487 1104 : adc + 1995 2846 2647 2699 0839 0441 : adc +''' diff --git a/network/demo_espat_ap_scan.py b/network/demo_espat_ap_scan.py new file mode 100644 index 0000000..45b44b4 --- /dev/null +++ b/network/demo_espat_ap_scan.py @@ -0,0 +1,78 @@ +# This file is part of MaixPY +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +#from board import board_info +#from Maix import config +#tmp = config.get_value('board_info', None) +#board_info.load(tmp) + +from network_espat import wifi +wifi.reset() + +print(wifi.at_cmd("AT\r\n")) + +ap_info = [] + +import time +while True: + time.sleep(1) + print('ap-scan...') + try: + tmp = wifi.at_cmd('AT+CWLAP\r\n') + #ap_info = wifi.nic.scan() + if tmp != None and len(tmp) > 64: + #print(tmp[len('+CWLAP:'):].split(b"\r\n")) + aps = tmp.replace(b'+CWLAP:', b'').replace(b'\r\n\r\nOK\r\n', b'') + #print(aps) + ap_info = aps.split(b"\r\n") + #print(ap_info) + break + except Exception as e: + print('error', e) + +def wifi_deal_ap_info(info): + res = [] + for ap_str in info: + ap_str = ap_str.split(b",") + #print(ap_str) + info_one = [] + for node in ap_str[1:-1]: + if node.startswith(b'"'): + info_one.append(node[1:-1]) + else: + info_one.append(int(node)) + res.append(info_one) + return res + +#print(ap_info) + +ap_info = wifi_deal_ap_info(ap_info) + +ap_info.sort(key=lambda x:x[2], reverse=True) # sort by rssi +for ap in ap_info: + print("SSID:{:^20}, RSSI:{:>5} , MAC:{:^20}".format(ap[0], ap[1], ap[2]) ) + +''' +MicroPython fa51290 on 2020-12-07; Sipeed_M1 with kendryte-k210 +Type "help()" for more information.>>> +>>> +>>> +raw REPL; CTRL-B to exit +>OK +reset... +b'\r\n\r\nOK\r\n' +ap-scan... +ap-scan... +ap-scan... +ap-scan... +SSID: webduino.io , RSSI: -50 , MAC: b6:e4:2f:f9:2f:1f +SSID: Sipeed_2.4G , RSSI: -73 , MAC: b0:b9:8a:5b:be:7f +SSID: ChinaNet-Ffdj , RSSI: -91 , MAC: a4:29:40:cc:51:f4 +SSID: wea_615 , RSSI: -91 , MAC: 64:6e:97:e1:86:e5 +SSID: OpenWrt , RSSI: -88 , MAC: 20:76:93:40:15:9c +> +''' diff --git a/network/demo_espat_ap_test.py b/network/demo_espat_ap_test.py new file mode 100644 index 0000000..10485a1 --- /dev/null +++ b/network/demo_espat_ap_test.py @@ -0,0 +1,21 @@ +# This file is part of MaixPY +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +from network_espat import wifi +wifi.reset() + +print(wifi.at_cmd("AT\r\n")) +print(wifi.at_cmd("AT+GMR\r\n")) + +''' +>>> reset... +b'\r\n\r\nOK\r\n' +b'AT version:1.1.0.0(May 11 2016 18:09:56)\r\nSDK version:1.5.4(baaeaebb)\r\ncompile time:May 20 2016 15:06:44\r\nOK\r\n' +MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 +Type "help()" for more information. +>>> +''' diff --git a/network/demo_http.py b/network/demo_http_get_jpg.py similarity index 53% rename from network/demo_http.py rename to network/demo_http_get_jpg.py index bf4b632..e2bb5c8 100644 --- a/network/demo_http.py +++ b/network/demo_http_get_jpg.py @@ -1,64 +1,81 @@ -import usocket, network, time -import lcd, image -from Maix import GPIO -from machine import UART -from fpioa_manager import fm -from board import board_info + +# This file is part of MaixPY +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +SSID = "Sipeed_2.4G" +PASW = "xxxxxxxx" + + +def enable_esp32(): + from network_esp32 import wifi + if wifi.isconnected() == False: + for i in range(5): + try: + # Running within 3 seconds of power-up can cause an SD load error + # wifi.reset(is_hard=False) + wifi.reset(is_hard=True) + print('try AT connect wifi...') + wifi.connect(SSID, PASW) + if wifi.isconnected(): + break + except Exception as e: + print(e) + print('network state:', wifi.isconnected(), wifi.ifconfig()) + + +enable_esp32() + + +def enable_espat(): + from network_espat import wifi + if wifi.isconnected() == False: + for i in range(5): + try: + # Running within 3 seconds of power-up can cause an SD load error + # wifi.reset(is_hard=False) + wifi.reset() + print('try AT connect wifi...') + wifi.connect(SSID, PASW) + if wifi.isconnected(): + break + except Exception as e: + print(e) + print('network state:', wifi.isconnected(), wifi.ifconfig()) + +#enable_espat() + +def network_wiznet5k(): + from network_wiznet5k import lan + from machine import SPI + from Maix import GPIO + if lan.isconnected() == False: + WIZNET5K_SPI_SCK = 21 + WIZNET5K_SPI_MOSI = 8 + WIZNET5K_SPI_MISO = 15 + WIZNET5K_SPI_CS = 20 + spi1 = SPI(4, mode=SPI.MODE_MASTER, baudrate=600 * 1000, + polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=WIZNET5K_SPI_SCK, mosi=WIZNET5K_SPI_MOSI, miso=WIZNET5K_SPI_MISO) + for i in range(5): + try: + lan.reset(spi1, WIZNET5K_SPI_CS) + print('try connect lan...') + if lan.isconnected(): + break + except Exception as e: + print(e) + print('network state:', lan.isconnected(), lan.ifconfig()) + +# network_wiznet5k() try: - import usocket as _socket -except: - import _socket -try: - import ussl as ssl + import usocket as socket except: - import ssl - - -# for new MaixGO board, if not, remove it -fm.register(0, fm.fpioa.GPIOHS1, force=True) -wifi_io0_en=GPIO(GPIO.GPIOHS1, GPIO.OUT) -wifi_io0_en.value(0) - -# En SEP8285 -fm.register(8, fm.fpioa.GPIOHS0, force=True) -wifi_en=GPIO(GPIO.GPIOHS0,GPIO.OUT) -fm.register(board_info.WIFI_RX,fm.fpioa.UART2_TX, force=True) -fm.register(board_info.WIFI_TX,fm.fpioa.UART2_RX, force=True) - -def wifi_enable(en): - global wifi_en - wifi_en.value(en) - -def wifi_reset(): - global uart - wifi_enable(0) - time.sleep_ms(200) - wifi_enable(1) - time.sleep(2) - uart = UART(UART.UART2,115200,timeout=1000, read_buf_len=4096) - tmp = uart.read() - uart.write("AT+UART_CUR=921600,8,1,0,0\r\n") - print(uart.read()) - uart = UART(UART.UART2,921600,timeout=1000, read_buf_len=10240) # important! baudrate too low or read_buf_len too small will loose data - uart.write("AT\r\n") - tmp = uart.read() - print(tmp) - if not tmp.endswith("OK\r\n"): - print("reset fail") - return None - try: - nic = network.ESP8285(uart) - except Exception: - return None - return nic - -nic = wifi_reset() -if not nic: - raise Exception("WiFi init fail") - -nic.connect("Sipeed_2.4G", "passwd") -nic.ifconfig() + import socket + class Response: @@ -116,14 +133,14 @@ def request(method, url, data=None, json=None, headers={}, stream=None, parse_he host, port = host.split(":", 1) port = int(port) - ai = usocket.getaddrinfo(host, port, 0, usocket.SOCK_STREAM) + ai = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM) ai = ai[0] resp_d = None if parse_headers is not False: resp_d = {} - s = usocket.socket(ai[0], ai[1], ai[2]) + s = socket.socket(ai[0], ai[1], ai[2]) try: s.connect(ai[-1]) if proto == "https:": @@ -196,40 +213,83 @@ def request(method, url, data=None, json=None, headers={}, stream=None, parse_he def head(url, **kw): return request("HEAD", url, **kw) + def get(url, **kw): return request("GET", url, **kw) + def post(url, **kw): return request("POST", url, **kw) + def put(url, **kw): return request("PUT", url, **kw) + def patch(url, **kw): return request("PATCH", url, **kw) + def delete(url, **kw): return request("DELETE", url, **kw) -headers ={ + +headers = { "User-Agent": "MaixPy" } res = get("http://static.sipeed.com/example/MaixPy.jpg", headers=headers) print("response:", res.status_code) content = res.content -print("get img, length:{}, should be:{}".format(len(content), int(res.headers['Content-Length']))) +print("get img, length:{}, should be:{}".format( + len(content), int(res.headers['Content-Length']))) -if len(content)!= int(res.headers['Content-Length']): +if len(content) != int(res.headers['Content-Length']): print("download img fail, not complete, try again") else: print("save to /flash/MaixPy.jpg") - f = open("/flash/MaixPy.jpg","wb") + f = open("/flash/MaixPy.jpg", "wb") f.write(content) f.close() del content print("save ok") print("display") + import lcd + import image img = image.Image("/flash/MaixPy.jpg") lcd.init() lcd.display(img) + +''' +MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 +Type "help()" for more information. +>>> network state: True ('192.168.0.143', '255.255.255.0', '192.168.0.1', '0', '0', 'b0:b9:8a:5b:be:7f', 'Sipeed_2.4G') + +Traceback (most recent call last): + File "", line 220, in + File "", line 197, in get + File "", line 179, in request + File "", line 124, in request +OSError: -1 +MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 +Type "help()" for more information. +>>> network state: True ('192.168.0.143', '255.255.255.0', '192.168.0.1', '0', '0', 'b0:b9:8a:5b:be:7f', 'Sipeed_2.4G') +[MaixPy] get_host_byname | get_host_byname failed + +Traceback (most recent call last): + File "", line 220, in + File "", line 197, in get + File "", line 115, in request +OSError: [Errno 22] EINVAL +MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 +Type "help()" for more information. +>>> network state: True ('192.168.0.143', '255.255.255.0', '192.168.0.1', '0', '0', 'b0:b9:8a:5b:be:7f', 'Sipeed_2.4G') +response: 200 +get img, length:50611, should be:50611 +save to /flash/MaixPy.jpg +save ok +display +MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 +Type "help()" for more information. +>>> +''' diff --git a/network/demo_https_get.png b/network/demo_https_get.png deleted file mode 100644 index 3372c35..0000000 Binary files a/network/demo_https_get.png and /dev/null differ diff --git a/network/demo_https_get.py b/network/demo_https_get.py deleted file mode 100644 index c788384..0000000 --- a/network/demo_https_get.py +++ /dev/null @@ -1,83 +0,0 @@ - - -import network, socket -from Maix import GPIO -from fpioa_manager import fm -from board import board_info -import time - -WIFI_SSID = "webduino.io" -WIFI_PASSWD = "webduino" - -# IO map for ESP32 on Maixduino -fm.register(25,fm.fpioa.GPIOHS10)#cs -fm.register(8,fm.fpioa.GPIOHS11)#rst -fm.register(9,fm.fpioa.GPIOHS12)#rdy - -fm.register(28,fm.fpioa.GPIOHS13)#mosi -fm.register(26,fm.fpioa.GPIOHS14)#miso -fm.register(27,fm.fpioa.GPIOHS15)#sclk - -nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10,rst=fm.fpioa.GPIOHS11,rdy=fm.fpioa.GPIOHS12, mosi=fm.fpioa.GPIOHS13,miso=fm.fpioa.GPIOHS14,sclk=fm.fpioa.GPIOHS15) - -print("ESP32_SPI firmware version:", nic.version()) - -fm.register(28,fm.fpioa.SPI1_D0, force=True)#mosi -fm.register(26,fm.fpioa.SPI1_D1, force=True)#miso -fm.register(27,fm.fpioa.SPI1_SCLK, force=True)#sclk - -nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10, rst=fm.fpioa.GPIOHS11, rdy=fm.fpioa.GPIOHS12, spi=1) - -print("ESP32_SPI firmware version:", nic.version()) - -err = 0 -while 1: - try: - nic.connect(WIFI_SSID, WIFI_PASSWD) - except Exception: - err += 1 - print("Connect AP failed, now try again") - if err > 3: - raise Exception("Conenct AP fail") - continue - break -print(nic.ifconfig()) -print(nic.isconnected()) - -try: - import usocket as _socket -except: - import _socket -try: - import ussl as ssl -except: - import ssl - -def main(use_stream=True): - s = _socket.socket() - s.settimeout(1) - host = "www.baidu.com" - ai = _socket.getaddrinfo(host, 443) - print("Address infos:", ai) - addr = ai[0][-1] - for i in range(5): - try: - print("Connect address:", addr) - s.connect(addr) - - tmp = ssl.wrap_socket(s, server_hostname=host) - - tmp.write(b"GET / HTTP/1.1\r\n\r\n") - data = (s.readline('\r\n')) - print(data) - with open('test.txt', 'wb') as f: - f.write(data) - - except Exception as e: - print(e) - - s.close() - -main() - - diff --git a/network/demo_mqtt.md b/network/demo_mqtt.md deleted file mode 100644 index be951c8..0000000 --- a/network/demo_mqtt.md +++ /dev/null @@ -1,3 +0,0 @@ - -Refer to https://github.com/micropython/micropython-lib/tree/master/umqtt.simple - diff --git a/network/demo_net_socket.py b/network/demo_net_socket.py deleted file mode 100644 index 9dbce2d..0000000 --- a/network/demo_net_socket.py +++ /dev/null @@ -1,58 +0,0 @@ - - -import network, socket -from Maix import GPIO -from fpioa_manager import fm -from board import board_info -import time - -WIFI_SSID = "Sipeed_2.4G" -WIFI_PASSWD = "Sipeed123." -SERVER_ADDR = "192.168.0.113" -SERVER_PORT = 60000 - - -# IO map for ESP32 on Maixduino -fm.register(25,fm.fpioa.GPIOHS10, force=True)#cs -fm.register(8,fm.fpioa.GPIOHS11, force=True)#rst -fm.register(9,fm.fpioa.GPIOHS12, force=True)#rdy -fm.register(28,fm.fpioa.GPIOHS13, force=True)#mosi -fm.register(26,fm.fpioa.GPIOHS14, force=True)#miso -fm.register(27,fm.fpioa.GPIOHS15, force=True)#sclk - -nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10,rst=fm.fpioa.GPIOHS11,rdy=fm.fpioa.GPIOHS12, mosi=fm.fpioa.GPIOHS13,miso=fm.fpioa.GPIOHS14,sclk=fm.fpioa.GPIOHS15) - -print("ESP32_SPI firmware version:", nic.version()) - -err = 0 -while 1: - try: - nic.connect(WIFI_SSID, WIFI_PASSWD) - except Exception: - err += 1 - print("Connect AP failed, now try again") - if err > 3: - raise Exception("Conenct AP fail") - continue - break -print(nic.ifconfig()) -print(nic.isconnected()) - - -sock = socket.socket() -sock.connect((SERVER_ADDR, SERVER_PORT)) - -sock.settimeout(5) -while 1: - try: - sock.send("hello\n") - data = sock.recv(10) - if len(data) == 0: - continue - print("rcv:", len(data), data) - except Exception as e: - print("receive error:", e) - continue - time.sleep(2) - -sock.close() diff --git a/network/demo_send_at_cmd.py b/network/demo_send_at_cmd.py deleted file mode 100644 index 263bd25..0000000 --- a/network/demo_send_at_cmd.py +++ /dev/null @@ -1,36 +0,0 @@ -import time -from Maix import GPIO -from machine import UART -from fpioa_manager import fm -from board import board_info -fm.register(0, fm.fpioa.GPIOHS1, force=True) -wifi_io0_en=GPIO(GPIO.GPIOHS1, GPIO.OUT) -wifi_io0_en.value(0) - -fm.register(8, fm.fpioa.GPIOHS0) -wifi_en=GPIO(GPIO.GPIOHS0,GPIO.OUT) -fm.register(board_info.WIFI_RX,fm.fpioa.UART2_TX) -fm.register(board_info.WIFI_TX,fm.fpioa.UART2_RX) - -def wifi_enable(en): - global wifi_en - wifi_en.value(en) - - -uart = UART(UART.UART2,115200,timeout=1000, read_buf_len=4096) - - -wifi_enable(0) -time.sleep_ms(200) -wifi_enable(1) - -time.sleep_ms(2000) - -while 1: - read = uart.read() - if read: - print(read) -# uart.write("AT+GMR\r\n") - uart.write("AT\r\n") - time.sleep_ms(500) - diff --git a/network/demo_send_pic.py b/network/demo_send_pic.py deleted file mode 100644 index b9476a1..0000000 --- a/network/demo_send_pic.py +++ /dev/null @@ -1,113 +0,0 @@ - - -# Send image(jpeg) to server and display on server(PC), -# server code refer to ../tools_on_PC/network/pic_server.py - - -import network, socket, time, sensor, image -from machine import UART -from Maix import GPIO -from fpioa_manager import fm -from board import board_info -########## config ################ -wifi_ap_ssid = "Sipeed_2.4G" -wifi_ap_passwd = "Sipeed123." -server_ip = "192.168.0.183" -server_port = 3456 -################################## - -# for new MaixGO board, if not, remove it -fm.register(0, fm.fpioa.GPIOHS1, force=True) -wifi_io0_en=GPIO(GPIO.GPIOHS1, GPIO.OUT) -wifi_io0_en.value(0) - -# En SEP8285 -fm.register(8, fm.fpioa.GPIOHS0, force=True) -wifi_en=GPIO(GPIO.GPIOHS0,GPIO.OUT) -fm.register(board_info.WIFI_RX,fm.fpioa.UART2_TX, force=True) -fm.register(board_info.WIFI_TX,fm.fpioa.UART2_RX, force=True) - -def wifi_enable(en): - global wifi_en - wifi_en.value(en) - -def wifi_reset(): - global uart - wifi_enable(0) - time.sleep_ms(200) - wifi_enable(1) - time.sleep(2) - uart = UART(UART.UART2,115200,timeout=1000, read_buf_len=4096) - tmp = uart.read() - uart.write("AT+UART_CUR=921600,8,1,0,0\r\n") - print(uart.read()) - uart = UART(UART.UART2,921600,timeout=1000, read_buf_len=4096) - uart.write("AT\r\n") - tmp = uart.read() - print(tmp) - if not tmp.endswith("OK\r\n"): - print("reset fail") - return None - try: - nic = network.ESP8285(uart) - except Exception: - return None - return nic - -addr = (server_ip, server_port) - -clock = time.clock() - -sensor.reset() -sensor.set_pixformat(sensor.RGB565) -sensor.set_framesize(sensor.QVGA) -sensor.skip_frames(time = 2000) - -nic = None -while True: - if not nic or not nic.isconnected(): - nic = wifi_reset() - if not nic: - print("wifi reset fail") - continue - try: - nic.connect(wifi_ap_ssid, wifi_ap_passwd) - nic.ifconfig() - except Exception: - continue - if not nic.isconnected(): - print("WiFi connect fail") - continue - -# send pic - sock = socket.socket() - try: - sock.connect(addr) - except Exception as e: - print("connect error:", e) - sock.close() - continue - sock.settimeout(5) - - count = 0 - err = 0 - while True: - clock.tick() - if err >=10: - print("socket broken") - break - img = sensor.snapshot() - img = img.compress(quality=20) - img_bytes = img.to_bytes() - try: - send_len = sock.send(img_bytes) - except Exception: - print("send fail") - time.sleep(2) - err += 1 - continue - count += 1 - print("send:", count) - print("fps:", clock.fps()) - sock.close() - diff --git a/network/demo_socket_https.py b/network/demo_socket_https.py new file mode 100644 index 0000000..827961f --- /dev/null +++ b/network/demo_socket_https.py @@ -0,0 +1,113 @@ +# This file is part of MaixPY +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +SSID = "Sipeed_2.4G" +PASW = "xxxxxxxx" + +def enable_esp32(): + from network_esp32 import wifi + if wifi.isconnected() == False: + for i in range(5): + try: + # Running within 3 seconds of power-up can cause an SD load error + # wifi.reset(is_hard=False) + wifi.reset(is_hard=True) + print('try AT connect wifi...') + wifi.connect(SSID, PASW) + if wifi.isconnected(): + break + except Exception as e: + print(e) + print('network state:', wifi.isconnected(), wifi.ifconfig()) + +enable_esp32() + +def enable_espat(): + from network_espat import wifi + if wifi.isconnected() == False: + for i in range(5): + try: + # Running within 3 seconds of power-up can cause an SD load error + # wifi.reset(is_hard=False) + wifi.reset() + print('try AT connect wifi...') + wifi.connect(SSID, PASW) + if wifi.isconnected(): + break + except Exception as e: + print(e) + print('network state:', wifi.isconnected(), wifi.ifconfig()) + +#enable_espat() + +def network_wiznet5k(): + from network_wiznet5k import lan + from machine import SPI + from Maix import GPIO + if lan.isconnected() == False: + WIZNET5K_SPI_SCK = 21 + WIZNET5K_SPI_MOSI = 8 + WIZNET5K_SPI_MISO = 15 + WIZNET5K_SPI_CS = 20 + spi1 = SPI(4, mode=SPI.MODE_MASTER, baudrate=600 * 1000, + polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=WIZNET5K_SPI_SCK, mosi=WIZNET5K_SPI_MOSI, miso=WIZNET5K_SPI_MISO) + for i in range(5): + try: + lan.reset(spi1, WIZNET5K_SPI_CS) + print('try connect lan...') + if lan.isconnected(): + break + except Exception as e: + print(e) + print('network state:', lan.isconnected(), lan.ifconfig()) + +# network_wiznet5k() + +try: + import usocket as socket +except: + import socket + +TestHttps = False + +def main(use_stream=True): + s = socket.socket() + s.settimeout(1) + host = "www.baidu.com" + if TestHttps: + ai = socket.getaddrinfo(host, 443) + else: + ai = socket.getaddrinfo(host, 80) + print("Address infos:", ai) + addr = ai[0][-1] + for i in range(5): + try: + print("Connect address:", addr) + s.connect(addr) + + if TestHttps: # ssl + try: + import ussl as ssl + except: + import ssl + tmp = ssl.wrapsocket(s, server_hostname=host) + tmp.write(b"GET / HTTP/1.1\r\n\r\n") + else: + s.write(b"GET / HTTP/1.1\r\n\r\n") + data = (s.readline('\r\n')) + print(data) + with open('test.txt', 'wb') as f: + f.write(data) + + except Exception as e: + print(e) + + s.close() + +main() + + diff --git a/network/demo_socket_mqtt.py b/network/demo_socket_mqtt.py new file mode 100644 index 0000000..f1b0e16 --- /dev/null +++ b/network/demo_socket_mqtt.py @@ -0,0 +1,2 @@ + +# Refer to https://github.com/daq-tools/umqtt-example diff --git a/network/demo_socket_pic_client.py b/network/demo_socket_pic_client.py new file mode 100644 index 0000000..a90a236 --- /dev/null +++ b/network/demo_socket_pic_client.py @@ -0,0 +1,151 @@ +# This file is part of MaixPY +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +#network_wiznet5k() + +SSID = "Sipeed_2.4G" +PASW = "xxxxxxxx" + +def enable_esp32(): + from network_esp32 import wifi + if wifi.isconnected() == False: + for i in range(5): + try: + # Running within 3 seconds of power-up can cause an SD load error + # wifi.reset(is_hard=False) + wifi.reset(is_hard=True) + print('try AT connect wifi...') + wifi.connect(SSID, PASW) + if wifi.isconnected(): + break + except Exception as e: + print(e) + print('network state:', wifi.isconnected(), wifi.ifconfig()) + +enable_esp32() + +def enable_espat(): + from network_espat import wifi + if wifi.isconnected() == False: + for i in range(5): + try: + # Running within 3 seconds of power-up can cause an SD load error + # wifi.reset(is_hard=False) + wifi.reset() + print('try AT connect wifi...') + wifi.connect(SSID, PASW) + if wifi.isconnected(): + break + except Exception as e: + print(e) + print('network state:', wifi.isconnected(), wifi.ifconfig()) + +#enable_espat() + +def network_wiznet5k(): + from network_wiznet5k import lan + from machine import SPI + from Maix import GPIO + if lan.isconnected() == False: + WIZNET5K_SPI_SCK = 21 + WIZNET5K_SPI_MOSI = 8 + WIZNET5K_SPI_MISO = 15 + WIZNET5K_SPI_CS = 20 + spi1 = SPI(4, mode=SPI.MODE_MASTER, baudrate=600 * 1000, + polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=WIZNET5K_SPI_SCK, mosi=WIZNET5K_SPI_MOSI, miso=WIZNET5K_SPI_MISO) + for i in range(5): + try: + lan.reset(spi1, WIZNET5K_SPI_CS) + print('try connect lan...') + if lan.isconnected(): + break + except Exception as e: + print(e) + print('network state:', lan.isconnected(), lan.ifconfig()) + +# network_wiznet5k() + +########## server config ################ +# Send image(jpeg) to server and display on server(PC), +# server code refer to ../demo_recv_pic_server.py +WIFI_SSID = "Sipeed_2.4G" +WIFI_PASSWD = "xxxxxxxx" +addr = ("192.168.0.107", 3456) +################################## + +import socket, time, sensor, image +import lcd + +clock = time.clock() +lcd.init() +sensor.reset() +sensor.set_pixformat(sensor.RGB565) +sensor.set_framesize(sensor.QVGA) +sensor.skip_frames(time = 2000) + +while True: + # send pic + while True: + try: + sock = socket.socket() + print(sock) + sock.connect(addr) + break + except Exception as e: + print("connect error:", e) + sock.close() + continue + sock.settimeout(5) + + send_len, count, err = 0, 0, 0 + while True: + clock.tick() + if err >=10: + print("socket broken") + break + img = sensor.snapshot() + lcd.display(img) + img = img.compress(quality=60) + img_bytes = img.to_bytes() + print("send len: ", len(img_bytes)) + try: + block = int(len(img_bytes)/2048) + for i in range(block): + send_len = sock.send(img_bytes[i*2048:(i+1)*2048]) + #time.sleep_ms(500) + send_len2 = sock.send(img_bytes[block*2048:]) + #send_len = sock.send(img_bytes[0:2048]) + #send_len = sock.send(img_bytes[2048:]) + #time.sleep_ms(500) + if send_len == 0: + raise Exception("send fail") + except OSError as e: + if e.args[0] == 128: + print("connection closed") + break + except Exception as e: + print("send fail:", e) + time.sleep(1) + err += 1 + continue + count += 1 + print("send:", count) + print("fps:", clock.fps()) + #time.sleep_ms(500) + print("close now") + sock.close() + +''' + ESP32_SPI firmware version: 1.4.0 + try AT connect wifi... + network state: True ('192.168.0.180', '255.255.255.0', '192.168.0.1') + ping baidu.com: 40 ms + > + MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 + Type "help()" for more information. + >>> +''' diff --git a/tools_on_PC/network/pic_server.py b/network/demo_socket_pic_server.py similarity index 78% rename from tools_on_PC/network/pic_server.py rename to network/demo_socket_pic_server.py index a33ab72..da95668 100644 --- a/tools_on_PC/network/pic_server.py +++ b/network/demo_socket_pic_server.py @@ -1,5 +1,43 @@ -#!/usr/bin/env python3 -# coding:utf-8 +#coding=utf-8 +#!/usr/bin/env python2 +# +# This file is part of MaixPY +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +''' +# Network tools srcipt + +## pic_server.py + +LAN map transmission server + +- Installation dependency + +update pip + +```shell +# python -m pip install --upgrade pip +python -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple # Domestic Tsinghua source +``` + +update pygame + +```shell +# pip3 install pygame +pip3 install pygame -i https://pypi.tuna.tsinghua.edu.cn/simple # Domestic Tsinghua source +``` + +- run server + +```shell +python3 demo_socket_pic_server.py +``` +''' + import socket import time import threading diff --git a/network/demo_socket_tcp_client.py b/network/demo_socket_tcp_client.py new file mode 100644 index 0000000..97e2c72 --- /dev/null +++ b/network/demo_socket_tcp_client.py @@ -0,0 +1,96 @@ +# This file is part of MaixPY +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +#network_wiznet5k() + +SSID = "Sipeed_2.4G" +PASW = "xxxxxxxx" + +def enable_esp32(): + from network_esp32 import wifi + if wifi.isconnected() == False: + for i in range(5): + try: + # Running within 3 seconds of power-up can cause an SD load error + # wifi.reset(is_hard=False) + wifi.reset(is_hard=True) + print('try AT connect wifi...') + wifi.connect(SSID, PASW) + if wifi.isconnected(): + break + except Exception as e: + print(e) + print('network state:', wifi.isconnected(), wifi.ifconfig()) + +enable_esp32() + +def enable_espat(): + from network_espat import wifi + if wifi.isconnected() == False: + for i in range(5): + try: + # Running within 3 seconds of power-up can cause an SD load error + # wifi.reset(is_hard=False) + wifi.reset() + print('try AT connect wifi...') + wifi.connect(SSID, PASW) + if wifi.isconnected(): + break + except Exception as e: + print(e) + print('network state:', wifi.isconnected(), wifi.ifconfig()) + +#enable_espat() + +def network_wiznet5k(): + from network_wiznet5k import lan + from machine import SPI + from Maix import GPIO + if lan.isconnected() == False: + WIZNET5K_SPI_SCK = 21 + WIZNET5K_SPI_MOSI = 8 + WIZNET5K_SPI_MISO = 15 + WIZNET5K_SPI_CS = 20 + spi1 = SPI(4, mode=SPI.MODE_MASTER, baudrate=600 * 1000, + polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=WIZNET5K_SPI_SCK, mosi=WIZNET5K_SPI_MOSI, miso=WIZNET5K_SPI_MISO) + for i in range(5): + try: + lan.reset(spi1, WIZNET5K_SPI_CS) + print('try connect lan...') + if lan.isconnected(): + break + except Exception as e: + print(e) + print('network state:', lan.isconnected(), lan.ifconfig()) + +# network_wiznet5k() + +import socket + +ADDR = ("192.168.0.107", 60000) + +sock = socket.socket() +sock.connect(ADDR) + +sock.settimeout(1) +while 1: + sock.send("hello\n") + #data = sock.recv(10) # old maxipy have bug (recv timeout no return last data) + #print(data) # fix + try: + data = b"" + while True: + tmp = sock.recv(1) + print(tmp) + if len(tmp) == 0: + raise Exception('timeout or disconnected') + data += tmp + except Exception as e: + print("rcv:", len(data), data) + #time.sleep(2) + +sock.close() diff --git a/network/demo_socket_tcp_server.py b/network/demo_socket_tcp_server.py new file mode 100644 index 0000000..a919c35 --- /dev/null +++ b/network/demo_socket_tcp_server.py @@ -0,0 +1,34 @@ +''' +This is a testing program +the program is used to start server +''' +import socket +import sys +import time + +def start_tcp_server(ip, port): + #create socket + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server_address = (ip, port) + #bind port + print('starting listen on ip %s, port %s' % server_address) + sock.bind(server_address) + #starting listening, allow only one connection + try: + sock.listen(1) + except socket.error as e: + print("fail to listen on port %s" % e) + sys.exit(1) + while True: + print("waiting for connection") + client, addr = sock.accept() + print('having a connection') + for i in range(5): + print('send message') + client.send(b'I am server') + print(client.recv(6)) + print('send OSError: [Errno 128(32)] ENOTCONN') + client.close() + +if __name__ == '__main__': + start_tcp_server('0.0.0.0', 60000) diff --git a/network/demo_socket_udp_client.py b/network/demo_socket_udp_client.py new file mode 100644 index 0000000..b04e465 --- /dev/null +++ b/network/demo_socket_udp_client.py @@ -0,0 +1,83 @@ +# This file is part of MaixPY +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +#network_wiznet5k() + +SSID = "Sipeed_2.4G" +PASW = "xxxxxxxx" + +def enable_esp32(): + from network_esp32 import wifi + if wifi.isconnected() == False: + for i in range(5): + try: + # Running within 3 seconds of power-up can cause an SD load error + # wifi.reset(is_hard=False) + wifi.reset(is_hard=True) + print('try AT connect wifi...') + wifi.connect(SSID, PASW) + if wifi.isconnected(): + break + except Exception as e: + print(e) + print('network state:', wifi.isconnected(), wifi.ifconfig()) + +#enable_esp32() + +# UDP not support enable_espat + +def network_wiznet5k(): + from network_wiznet5k import lan + from machine import SPI + from Maix import GPIO + if lan.isconnected() == False: + WIZNET5K_SPI_SCK = 21 + WIZNET5K_SPI_MOSI = 8 + WIZNET5K_SPI_MISO = 15 + WIZNET5K_SPI_CS = 20 + spi1 = SPI(4, mode=SPI.MODE_MASTER, baudrate=600 * 1000, + polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=WIZNET5K_SPI_SCK, mosi=WIZNET5K_SPI_MOSI, miso=WIZNET5K_SPI_MISO) + for i in range(5): + try: + lan.reset(spi1, WIZNET5K_SPI_CS) + print('try connect lan...') + if lan.isconnected(): + break + except Exception as e: + print(e) + print('network state:', lan.isconnected(), lan.ifconfig()) + +# network_wiznet5k() + +import socket + +ADDR = ("192.168.0.107", 60000) + +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +sock.settimeout(1) + +while 1: + try: + sock.sendto("hello\n", ADDR) + data, addr = sock.recvfrom(1024) + except Exception as e: + print("receive error:", e) + continue + print("addr:", addr, "data:", data) + time.sleep(2) + +sock.close() + +''' +>>> +raw REPL; CTRL-B to exit +>OK +network state: True ('192.168.0.186', '255.255.255.0', '192.168.0.1') +addr: ('192.168.0.107', 60000) data: b'HELLO\n' +addr: ('192.168.0.107', 60000) data: b'HELLO\n' +addr: ('192.168.0.107', 60000) data: b'HELLO\n' +''' diff --git a/network/demo_socket_udp_server.py b/network/demo_socket_udp_server.py new file mode 100644 index 0000000..2362265 --- /dev/null +++ b/network/demo_socket_udp_server.py @@ -0,0 +1,19 @@ +import socket +BUFSIZE = 1024 +ip_port = ('0.0.0.0', 60000) +server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # udp +server.bind(ip_port) +while True: + data,client_addr = server.recvfrom(BUFSIZE) + print('server recv', data) + server.sendto(data.upper(),client_addr) +server.close() + +''' +('server recv', 'hello\n') +('server recv', 'hello\n') +('server recv', 'hello\n') +('server recv', 'hello\n') +('server recv', 'hello\n') +('server recv', 'hello\n') +''' diff --git a/network/demo_wifi_ap_scan.py b/network/demo_wifi_ap_scan.py deleted file mode 100644 index 43d655a..0000000 --- a/network/demo_wifi_ap_scan.py +++ /dev/null @@ -1,48 +0,0 @@ -import network, time -from machine import UART -from Maix import GPIO -from fpioa_manager import fm -from board import board_info -# En SEP8285 -fm.register(8, fm.fpioa.GPIOHS0, force=True) -wifi_en=GPIO(GPIO.GPIOHS0, GPIO.OUT) - -# for new MaixGO board, if not, remove it -fm.register(0, fm.fpioa.GPIOHS1, force=True) -wifi_io0_en=GPIO(GPIO.GPIOHS1, GPIO.OUT) -wifi_io0_en.value(0) - -fm.register(board_info.WIFI_RX, fm.fpioa.UART2_TX, force=True) -fm.register(board_info.WIFI_TX, fm.fpioa.UART2_RX, force=True) - -uart = UART(UART.UART2,115200,timeout=1000, read_buf_len=4096) - -def wifi_enable(en): - global wifi_en - wifi_en.value(en) - -def wifi_deal_ap_info(info): - res = [] - for ap_str in info: - ap_str = ap_str.split(",") - info_one = [] - for node in ap_str: - if node.startswith('"'): - info_one.append(node[1:-1]) - else: - info_one.append(int(node)) - res.append(info_one) - return res - - -wifi_enable(1) -time.sleep(2) -nic = network.ESP8285(uart) - -ap_info = nic.scan() -ap_info = wifi_deal_ap_info(ap_info) - -ap_info.sort(key=lambda x:x[2], reverse=True) # sort by rssi -for ap in ap_info: - print("SSID:{:^20}, RSSI:{:>5} , MAC:{:^20}".format(ap[1], ap[2], ap[3]) ) - diff --git a/network/upgrade_at_firmware.py b/network/espat_upgrade.py similarity index 99% rename from network/upgrade_at_firmware.py rename to network/espat_upgrade.py index 4bb7045..743a6b0 100644 --- a/network/upgrade_at_firmware.py +++ b/network/espat_upgrade.py @@ -2,7 +2,7 @@ ######## AP config ######### WIFI_SSID = "Sipeed_2.4G" -WIFI_PASSWD = "Sipeed123." +WIFI_PASSWD = "xxxxxxxx" ############################ diff --git a/network/maxiduino_esp32_ap_scan.py b/network/maxiduino_esp32_ap_scan.py deleted file mode 100644 index 5ddc1f5..0000000 --- a/network/maxiduino_esp32_ap_scan.py +++ /dev/null @@ -1,23 +0,0 @@ - - -import network -from Maix import GPIO -from fpioa_manager import fm -from board import board_info - -# IO map for ESP32 on Maixduino -fm.register(25,fm.fpioa.GPIOHS10, force=True)#cs -fm.register(8,fm.fpioa.GPIOHS11, force=True)#rst -fm.register(9,fm.fpioa.GPIOHS12, force=True)#rdy -fm.register(28,fm.fpioa.GPIOHS13, force=True)#mosi -fm.register(26,fm.fpioa.GPIOHS14, force=True)#miso -fm.register(27,fm.fpioa.GPIOHS15, force=True)#sclk - -nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10,rst=fm.fpioa.GPIOHS11,rdy=fm.fpioa.GPIOHS12, mosi=fm.fpioa.GPIOHS13,miso=fm.fpioa.GPIOHS14,sclk=fm.fpioa.GPIOHS15) - -enc_str = ["OPEN", "", "WPA PSK", "WPA2 PSK", "WPA/WPA2 PSK"] -aps = nic.scan() -for ap in aps: - print("SSID:{:^20}, ENC:{:>5} , RSSI:{:^20}".format(ap[0], enc_str[ap[1]], ap[2]) ) - - diff --git a/network/maxiduino_esp32_network.py b/network/maxiduino_esp32_network.py deleted file mode 100644 index c99247a..0000000 --- a/network/maxiduino_esp32_network.py +++ /dev/null @@ -1,28 +0,0 @@ - - -import network -from Maix import GPIO -from fpioa_manager import fm -from board import board_info -WIFI_SSID = "Sipeed_2.4G" -WIFI_PASSWD = "passwd" - -# IO map for ESP32 on Maixduino -fm.register(25,fm.fpioa.GPIOHS10, force=True)#cs -fm.register(8,fm.fpioa.GPIOHS11, force=True)#rst -fm.register(9,fm.fpioa.GPIOHS12, force=True)#rdy -fm.register(28,fm.fpioa.GPIOHS13, force=True)#mosi -fm.register(26,fm.fpioa.GPIOHS14, force=True)#miso -fm.register(27,fm.fpioa.GPIOHS15, force=True)#sclk - -nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10,rst=fm.fpioa.GPIOHS11,rdy=fm.fpioa.GPIOHS12, mosi=fm.fpioa.GPIOHS13,miso=fm.fpioa.GPIOHS14,sclk=fm.fpioa.GPIOHS15) - -nic.connect(WIFI_SSID, WIFI_PASSWD) -print(nic.ifconfig()) -print(nic.isconnected()) -print("ping baidu.com:", nic.ping("baidu.com"), "ms") -nic.disconnect() - - - - diff --git a/network/maxiduino_esp32_read_adc.py b/network/maxiduino_esp32_read_adc.py deleted file mode 100644 index bbab7cf..0000000 --- a/network/maxiduino_esp32_read_adc.py +++ /dev/null @@ -1,42 +0,0 @@ - -import network -import utime -from Maix import GPIO -from fpioa_manager import * - -# IO map for ESP32 on Maixduino -fm.register(25,fm.fpioa.GPIOHS10, force=True)#cs -fm.register(8,fm.fpioa.GPIOHS11, force=True)#rst -fm.register(9,fm.fpioa.GPIOHS12, force=True)#rdy -fm.register(28,fm.fpioa.GPIOHS13, force=True)#mosi -fm.register(26,fm.fpioa.GPIOHS16, force=True)#miso -fm.register(27,fm.fpioa.GPIOHS17, force=True)#sclk - -nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10,rst=fm.fpioa.GPIOHS11,rdy=fm.fpioa.GPIOHS12, -mosi=fm.fpioa.GPIOHS13,miso=fm.fpioa.GPIOHS16,sclk=fm.fpioa.GPIOHS17) - -# get ADC0 ADC1 ADC2 -adc = nic.adc( (0,1,2) ) -print(adc) - -while True: - try: - # get ADC0~5 - adc = nic.adc() - except Exception as e: - print(e) - continue - for v in adc: - print("%04d" %(v), end=" ") - - fm.register(28, fm.fpioa.SPI1_D0, force=True) - fm.register(26, fm.fpioa.SPI1_D1, force=True) - fm.register(27, fm.fpioa.SPI1_SCLK, force=True) - - print(os.listdir()) # patch sdcard spi0 - - fm.register(28,fm.fpioa.GPIOHS13, force=True)#mosi - fm.register(26,fm.fpioa.GPIOHS16, force=True)#miso - fm.register(27,fm.fpioa.GPIOHS17, force=True)#sclk - - utime.sleep_ms(50) diff --git a/network/maxiduino_esp32_send_pic.py b/network/maxiduino_esp32_send_pic.py deleted file mode 100644 index 85654be..0000000 --- a/network/maxiduino_esp32_send_pic.py +++ /dev/null @@ -1,114 +0,0 @@ - - -# Send image(jpeg) to server and display on server(PC), -# server code refer to ../tools_on_PC/network/pic_server.py - - -import network, socket, time, sensor, image -from machine import UART -from Maix import GPIO -from fpioa_manager import fm -from board import board_info -import lcd -########## config ################ -WIFI_SSID = "Sipeed_2.4G" -WIFI_PASSWD = "Sipeed123." -server_ip = "192.168.0.133" -server_port = 3456 -################################## - -# IO map for ESP32 on Maixduino -fm.register(25,fm.fpioa.GPIOHS10, force=True)#cs -fm.register(8,fm.fpioa.GPIOHS11, force=True)#rst -fm.register(9,fm.fpioa.GPIOHS12, force=True)#rdy -fm.register(28,fm.fpioa.GPIOHS13, force=True)#mosi -fm.register(26,fm.fpioa.GPIOHS14, force=True)#miso -fm.register(27,fm.fpioa.GPIOHS15, force=True)#sclk - -nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10,rst=fm.fpioa.GPIOHS11,rdy=fm.fpioa.GPIOHS12, mosi=fm.fpioa.GPIOHS13,miso=fm.fpioa.GPIOHS14,sclk=fm.fpioa.GPIOHS15) - -addr = (server_ip, server_port) - -clock = time.clock() -lcd.init() -sensor.reset() -sensor.set_pixformat(sensor.RGB565) -sensor.set_framesize(sensor.QVGA) -sensor.skip_frames(time = 2000) - -nic = None -while True: - if not nic: - nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10,rst=fm.fpioa.GPIOHS11,rdy=fm.fpioa.GPIOHS12, mosi=fm.fpioa.GPIOHS13,miso=fm.fpioa.GPIOHS14,sclk=fm.fpioa.GPIOHS15) - continue - if not nic.isconnected(): - print("connect WiFi now") - try: - err = 0 - while 1: - try: - nic.connect(WIFI_SSID, WIFI_PASSWD) - except Exception: - err += 1 - print("Connect AP failed, now try again") - if err > 3: - raise Exception("Conenct AP fail") - continue - break - nic.ifconfig() - except Exception: - continue - if not nic.isconnected(): - print("WiFi connect fail") - continue - -# send pic - sock = socket.socket() - print(sock) - try: - sock.connect(addr) - except Exception as e: - print("connect error:", e) - sock.close() - continue - sock.settimeout(5) - - count = 0 - err = 0 - while True: - clock.tick() - if err >=10: - print("socket broken") - break - img = sensor.snapshot() - lcd.display(img) - img = img.compress(quality=60) - img_bytes = img.to_bytes() - print("send len: ", len(img_bytes)) - try: - block = int(len(img_bytes)/2048) - for i in range(block): - send_len = sock.send(img_bytes[i*2048:(i+1)*2048]) - #time.sleep_ms(500) - send_len2 = sock.send(img_bytes[block*2048:]) - #send_len = sock.send(img_bytes[0:2048]) - #send_len = sock.send(img_bytes[2048:]) - #time.sleep_ms(500) - if send_len == 0: - raise Exception("send fail") - except OSError as e: - if e.args[0] == 128: - print("connection closed") - break - except Exception as e: - print("send fail:", e) - time.sleep(1) - err += 1 - continue - count += 1 - print("send:", count) - print("fps:", clock.fps()) - #time.sleep_ms(500) - print("close now") - sock.close() - diff --git a/network/maxiduino_esp32_socket _udp_cli.py b/network/maxiduino_esp32_socket _udp_cli.py deleted file mode 100644 index 075a8c3..0000000 --- a/network/maxiduino_esp32_socket _udp_cli.py +++ /dev/null @@ -1,54 +0,0 @@ - - -import network, socket -from Maix import GPIO -from fpioa_manager import fm -from board import board_info -import time - -WIFI_SSID = "Sipeed_2.4G" -WIFI_PASSWD = "passwd" -SERVER_ADDR = "192.168.0.183" -SERVER_PORT = 8000 - - -# IO map for ESP32 on Maixduino -fm.register(25,fm.fpioa.GPIOHS10, force=True)#cs -fm.register(8,fm.fpioa.GPIOHS11, force=True)#rst -fm.register(9,fm.fpioa.GPIOHS12, force=True)#rdy -fm.register(28,fm.fpioa.GPIOHS13, force=True)#mosi -fm.register(26,fm.fpioa.GPIOHS14, force=True)#miso -fm.register(27,fm.fpioa.GPIOHS15, force=True)#sclk - -nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10,rst=fm.fpioa.GPIOHS11,rdy=fm.fpioa.GPIOHS12, mosi=fm.fpioa.GPIOHS13,miso=fm.fpioa.GPIOHS14,sclk=fm.fpioa.GPIOHS15) - -print("ESP32_SPI firmware version:", nic.version()) - -err = 0 -while 1: - try: - nic.connect(WIFI_SSID, WIFI_PASSWD) - except Exception: - err += 1 - print("Connect AP failed, now try again") - if err > 3: - raise Exception("Conenct AP fail") - continue - break -print(nic.ifconfig()) -print(nic.isconnected()) - - -sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -sock.settimeout(1) -while 1: - try: - sock.sendto("hello\n".encode(),(SERVER_ADDR, SERVER_PORT)) - data, addr = sock.recvfrom(1024) - except Exception as e: - print("receive error:", e) - continue - print("addr:", addr, "data:", data) - time.sleep(2) - -sock.close() diff --git a/network/maxiduino_esp32_socket.py b/network/maxiduino_esp32_socket.py deleted file mode 100644 index df54c94..0000000 --- a/network/maxiduino_esp32_socket.py +++ /dev/null @@ -1,62 +0,0 @@ - - -import network, socket -from Maix import GPIO -from fpioa_manager import fm -from board import board_info -import time - -WIFI_SSID = "Sipeed_2.4G" -WIFI_PASSWD = "Sipeed123." -SERVER_ADDR = "192.168.0.113" -SERVER_PORT = 60000 - - -# IO map for ESP32 on Maixduino -fm.register(25,fm.fpioa.GPIOHS10, force=True)#cs -fm.register(8,fm.fpioa.GPIOHS11, force=True)#rst -fm.register(9,fm.fpioa.GPIOHS12, force=True)#rdy -fm.register(28,fm.fpioa.GPIOHS13, force=True)#mosi -fm.register(26,fm.fpioa.GPIOHS14, force=True)#miso -fm.register(27,fm.fpioa.GPIOHS15, force=True)#sclk - -nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10,rst=fm.fpioa.GPIOHS11,rdy=fm.fpioa.GPIOHS12, mosi=fm.fpioa.GPIOHS13,miso=fm.fpioa.GPIOHS14,sclk=fm.fpioa.GPIOHS15) - -print("ESP32_SPI firmware version:", nic.version()) - -err = 0 -while 1: - try: - nic.connect(WIFI_SSID, WIFI_PASSWD) - except Exception: - err += 1 - print("Connect AP failed, now try again") - if err > 3: - raise Exception("Conenct AP fail") - continue - break -print(nic.ifconfig()) -print(nic.isconnected()) - - -sock = socket.socket() -sock.connect((SERVER_ADDR, SERVER_PORT)) - -sock.settimeout(3) -while 1: - sock.send("hello\n") - #data = sock.recv(10) # old maxipy have bug (recv timeout no return last data) - #print(data) # fix - try: - data = b"" - while True: - tmp = sock.recv(1) - #print(tmp) - if len(tmp) == 0: - raise Exception('timeout or disconnected') - data += tmp - except Exception as e: - print("rcv:", len(data), data) - #time.sleep(2) - -sock.close() diff --git a/network/network_esp32.py b/network/network_esp32.py new file mode 100644 index 0000000..b21696e --- /dev/null +++ b/network/network_esp32.py @@ -0,0 +1,134 @@ +# This file is part of MaixPY +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +import time, network +from Maix import GPIO +from fpioa_manager import fm + +class wifi(): + + nic = None + + def reset(force=False, reply=5, is_hard=True): + if force == False and __class__.isconnected(): + return True + try: + # IO map for ESP32 on Maixduino + fm.register(25,fm.fpioa.GPIOHS10)#cs + fm.register(8,fm.fpioa.GPIOHS11)#rst + fm.register(9,fm.fpioa.GPIOHS12)#rdy + + if is_hard: + print("Use Hareware SPI for other maixduino") + fm.register(28,fm.fpioa.SPI1_D0, force=True)#mosi + fm.register(26,fm.fpioa.SPI1_D1, force=True)#miso + fm.register(27,fm.fpioa.SPI1_SCLK, force=True)#sclk + __class__.nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10, rst=fm.fpioa.GPIOHS11, rdy=fm.fpioa.GPIOHS12, spi=1) + print("ESP32_SPI firmware version:", __class__.nic.version()) + else: + # Running within 3 seconds of power-up can cause an SD load error + print("Use Software SPI for other hardware") + fm.register(28,fm.fpioa.GPIOHS13, force=True)#mosi + fm.register(26,fm.fpioa.GPIOHS14, force=True)#miso + fm.register(27,fm.fpioa.GPIOHS15, force=True)#sclk + __class__.nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10,rst=fm.fpioa.GPIOHS11,rdy=fm.fpioa.GPIOHS12, mosi=fm.fpioa.GPIOHS13,miso=fm.fpioa.GPIOHS14,sclk=fm.fpioa.GPIOHS15) + print("ESP32_SPI firmware version:", __class__.nic.version()) + + # time.sleep_ms(500) # wait at ready to connect + except Exception as e: + print(e) + return False + return True + + def connect(ssid="wifi_name", pasw="pass_word"): + if __class__.nic != None: + return __class__.nic.connect(ssid, pasw) + + def ifconfig(): # should check ip != 0.0.0.0 + if __class__.nic != None: + return __class__.nic.ifconfig() + + def isconnected(): + if __class__.nic != None: + return __class__.nic.isconnected() + return False + +if __name__ == "__main__": + # It is recommended to callas a class library (upload network_espat.py) + + # from network_esp32 import wifi + SSID = "Sipeed_2.4G" + PASW = "xxxxxxxx" + + def check_wifi_net(reply=5): + if wifi.isconnected() != True: + for i in range(reply): + try: + wifi.reset(is_hard=True) + print('try esp32spi connect wifi...') + wifi.connect(SSID, PASW) + if wifi.isconnected(): + break + except Exception as e: + print(e) + return wifi.isconnected() + + if wifi.isconnected() == False: + check_wifi_net() + print('network state:', wifi.isconnected(), wifi.ifconfig()) + + # The network is no longer configured repeatedly + import socket + sock = socket.socket() + # your send or recv + # see other demo_socket_tcp.py / udp / http / mqtt + sock.close() + +'''ouput + MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 + Type "help()" for more information. + >>> + >>> + >>> + raw REPL; CTRL-B to exit + >OK + Use Hareware SPI for other maixduino + [esp32_spi] use hard spi(1) + + hard spi + + esp32 set hard spi clk:9159090 + + Get version fail + try esp32spi connect wifi... + Use Hareware SPI for other maixduino + [Warning] function is used by unknown(pin:10) + [Warning] function is used by unknown(pin:6) + [Warning] function is used by unknown(pin:11) + [esp32_spi] use hard spi(1) + + hard spi + + esp32 set hard spi clk:9159090 + + ESP32_SPI firmware version: 1.4.0 + try AT connect wifi... + network state: True ('192.168.0.180', '255.255.255.0', '192.168.0.1') + > + MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 + Type "help()" for more information. + >>> + >>> + >>> + raw REPL; CTRL-B to exit + >OK + network state: True ('192.168.0.180', '255.255.255.0', '192.168.0.1') + > + MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 + Type "help()" for more information. + >>> +''' diff --git a/network/network_espat.py b/network/network_espat.py new file mode 100644 index 0000000..ea0dcaa --- /dev/null +++ b/network/network_espat.py @@ -0,0 +1,144 @@ +# This file is part of MaixPY +# Copyright (c) sipeed.com +# +# Licensed under the MIT license: +# http://www.opensource.org/licenses/mit-license.php +# + +import time, network +from Maix import GPIO +from machine import UART +from fpioa_manager import fm +from board import board_info + +class wifi(): + + __is_m1w__ = True + uart = None + eb = None + nic = None + + def init(): + if __class__.__is_m1w__: + fm.register(0, fm.fpioa.GPIOHS1, force=True) + M1wPower=GPIO(GPIO.GPIOHS1, GPIO.OUT) + M1wPower.value(0) # b'\r\n ets Jan 8 2013,rst cause:1, boot mode:(7,6)\r\n\r\nwaiting for host\r\n' + + fm.register(board_info.WIFI_EN, fm.fpioa.GPIOHS0) # board_info.WIFI_EN == IO 8 + __class__.en = GPIO(GPIO.GPIOHS0,GPIO.OUT) + + fm.register(board_info.WIFI_RX,fm.fpioa.UART2_TX) # board_info.WIFI_RX == IO 7 + fm.register(board_info.WIFI_TX,fm.fpioa.UART2_RX) # board_info.WIFI_TX == IO 6 + __class__.uart = UART(UART.UART2, 115200, timeout=1000, read_buf_len=8192) + + def enable(en): + __class__.en.value(en) + + def _at_cmd(cmd="AT\r\n", resp="OK\r\n", timeout=20): + __class__.uart.write(cmd) # "AT+GMR\r\n" + time.sleep_ms(timeout) + tmp = __class__.uart.read() + # print(tmp) + if tmp and tmp.endswith(resp): + return True + return False + + def at_cmd(cmd="AT\r\n", timeout=20): + __class__.uart.write(cmd) # "AT+GMR\r\n" + time.sleep_ms(timeout) + tmp = __class__.uart.read() + return tmp + + def reset(force=False, reply=5): + if force == False and __class__.isconnected(): + return True + __class__.init() + for i in range(reply): + print('reset...') + __class__.enable(False) + time.sleep_ms(50) + __class__.enable(True) + time.sleep_ms(500) # at start > 500ms + if __class__._at_cmd(timeout=500): + break + __class__._at_cmd() + __class__._at_cmd('AT+UART_CUR=921600,8,1,0,0\r\n', "OK\r\n") + __class__.uart = UART(UART.UART2, 921600, timeout=1000, read_buf_len=10240) + # important! baudrate too low or read_buf_len too small will loose data + #print(__class__._at_cmd()) + try: + __class__.nic = network.ESP8285(__class__.uart) + time.sleep_ms(500) # wait at ready to connect + except Exception as e: + print(e) + return False + return True + + def connect(ssid="wifi_name", pasw="pass_word"): + if __class__.nic != None: + return __class__.nic.connect(ssid, pasw) + + def ifconfig(): # should check ip != 0.0.0.0 + if __class__.nic != None: + return __class__.nic.ifconfig() + + def isconnected(): + if __class__.nic != None: + return __class__.nic.isconnected() + return False + +if __name__ == "__main__": + # It is recommended to callas a class library (upload network_espat.py) + + # from network_espat import wifi + SSID = "Sipeed_2.4G" + PASW = "xxxxxxxx" + + def check_wifi_net(reply=5): + if wifi.isconnected() != True: + for i in range(reply): + try: + wifi.reset() + print('try AT connect wifi...', wifi._at_cmd()) + wifi.connect(SSID, PASW) + if wifi.isconnected(): + break + except Exception as e: + print(e) + return wifi.isconnected() + + if wifi.isconnected() == False: + check_wifi_net() + print('network state:', wifi.isconnected(), wifi.ifconfig()) + + # The network is no longer configured repeatedly + import socket + sock = socket.socket() + # your send or recv + # see other demo_socket_tcp.py / udp / http / mqtt + sock.close() + +'''ouput + >>> + raw REPL; CTRL-B to exit + >OK + [Warning] function is used by fm.fpioa.GPIOHS1(pin:17) + [Warning] function is used by fm.fpioa.GPIOHS0(pin:16) + reset... + try AT connect wifi... True + could not connect to ssid=Sipeed_2.4G + + reset... + try AT connect wifi... True + network state: True ('192.168.0.165', '255.255.255.0', '192.168.0.1', '0', '0', 'b0:b9:8a:5b:be:7f', 'Sipeed_2.4G') + > + MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210 + Type "help()" for more information. + >>> + >>> + >>> + raw REPL; CTRL-B to exit + >OK + network state: True ('192.168.0.165', '255.255.255.0', '192.168.0.1', '0', '0', 'b0:b9:8a:5b:be:7f', 'Sipeed_2.4G') + > +''' diff --git a/network/network_wiznet5k.py b/network/network_wiznet5k.py new file mode 100644 index 0000000..34120dc --- /dev/null +++ b/network/network_wiznet5k.py @@ -0,0 +1,107 @@ +import network + +class lan: + + nic = None + + def reset(spi1, cs, force=False, reply=5): + if force == False and __class__.isconnected(): + return True + try: + # create wiznet5k nic + __class__.nic = network.WIZNET5K(spi=spi1, cs=cs) + # time.sleep_ms(500) # wait at ready to connect + except Exception as e: + print(e) + return False + return True + + def ifconfig(): # should check ip != 0.0.0.0 + if __class__.nic != None: + return __class__.nic.ifconfig() + + def isconnected(): + if __class__.nic != None: + return __class__.nic.isconnected() + return False + +if __name__ == '__main__': + + from machine import SPI + from Maix import GPIO + import socket, time + from fpioa_manager import fm + + ################ config ################ + local_ip = "192.168.0.117" + local_netmask = "255.255.255.0" + local_gateway = "255.255.255.0" + local_dns_server = "8.8.8.8" + + server_ip = "192.168.0.141" + server_port = 8000 + addr = (server_ip, server_port) + ####################################### + + def network_wiznet5k(): + if lan.isconnected() == False: + WIZNET5K_SPI_SCK = 21 + WIZNET5K_SPI_MOSI = 8 + WIZNET5K_SPI_MISO = 15 + WIZNET5K_SPI_CS = 20 + spi1 = SPI(4, mode=SPI.MODE_MASTER, baudrate=600 * 1000, + polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=WIZNET5K_SPI_SCK, mosi=WIZNET5K_SPI_MOSI, miso=WIZNET5K_SPI_MISO) + + for i in range(5): + try: + lan.reset(spi1, WIZNET5K_SPI_CS) + print('try connect lan...') + if lan.isconnected(): + break + except Exception as e: + print(e) + print('network state:', lan.isconnected(), lan.ifconfig()) + + network_wiznet5k() + + if lan.isconnected(): + is_dhcp = False + if is_dhcp: + # #dhcp: Dynamic IP acquisition, It's not necessary + while True: + if(lan.nic.dhclient()): + print("DHCP IP:", lan.ifconfig()) + break + else: + lan.ifconfig() + + ############################## UDP Test ############################## + # # The server must first know the client's IP and port number through the message sent by the client before it send the message to the client + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.settimeout(5) + + while True: + sock.sendto("Client send: hello UDP\n".encode(), addr) + try: + data, addr1 = sock.recvfrom(10) + print("Recv from server: ", data) + except Exception as e: + pass + time.sleep_ms(500) + sock.close() + ############################ UDP Test end ############################ + + ############################## TCP Test ############################## + # The TCP server needs to be pre-started + # sock = socket.socket() + # sock.connect(addr) + # while 1: + # sock.send("Client send: Hello TCP\n") + # try: + # data = sock.recv(10) + # print("Recv from Server: ", data) + # except Exception as e: + # print(e) + # time.sleep(500) + # sock.close() + ############################ TCP Test end ############################ diff --git a/tools_on_PC/network/README.md b/tools_on_PC/network/README.md deleted file mode 100644 index 234a463..0000000 --- a/tools_on_PC/network/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Network tools srcipt - -## pic_server.py - -局域网图传 server 端 - -- 安装依赖 - -更新 pip - -```shell -# python -m pip install --upgrade pip -python -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple # 国内清华源,加速下载安装 -``` - -安装 pygame - -```shell -# pip3 install pygame -pip3 install pygame -i https://pypi.tuna.tsinghua.edu.cn/simple # 国内清华源,加速下载安装 -``` - -- 运行 server 端 - -```shell -python3 pic_serve.py -```