liushuai 9 mesiacov pred
commit
70482f2e55
100 zmenil súbory, kde vykonal 8245 pridanie a 0 odobranie
  1. 6 0
      .gitignore
  2. 1892 0
      CocoPi.py
  3. 1 0
      CocoPi_intro_manual.html
  4. 1 0
      CocoPi_online_programming.html
  5. 569 0
      main.py
  6. 62 0
      preset/app/01_camera.py
  7. 95 0
      preset/app/02_photoViewer.py
  8. 16 0
      preset/app/03_colorDetection.py
  9. 123 0
      preset/app/04_recorder.py
  10. 162 0
      preset/app/05_audioPlayer.py
  11. 28 0
      preset/app/06_musicPlayer.py
  12. 37 0
      preset/app/07_videoPlayer.py
  13. 71 0
      preset/app/08_timeCounter.py
  14. 11 0
      preset/app/09_localTimeClock.py
  15. 58 0
      preset/app/10_servoControl.py
  16. 93 0
      preset/app/11_motorControl.py
  17. 32 0
      preset/app/12_pictureLoopPlay.py
  18. 27 0
      preset/app/13_qrCodeScanner.py
  19. 57 0
      preset/app/14_humanDetection.py
  20. 49 0
      preset/app/15_faceDetection.py
  21. 171 0
      preset/app/16_faceComparison.py
  22. 77 0
      preset/app/17_objectRecognition.py
  23. 77 0
      preset/app/18_edgeDetection.py
  24. 73 0
      preset/app/19_handWrittenDigiRecognition.py
  25. 106 0
      preset/app/20_carLicensePlateRecognition.py
  26. 66 0
      preset/app/21_maskDetection.py
  27. 76 0
      preset/app/22_gestureRecognition.py
  28. 71 0
      preset/app/23_fingerGuessing.py
  29. 189 0
      preset/app/24_connectWiFi.py
  30. 220 0
      preset/app/25_aboutCocoPi.py
  31. 101 0
      preset/app/26_internetCamera.py
  32. 70 0
      preset/app/27_internetWeatherPrediction.py
  33. 142 0
      preset/app/28_internetTimeClock.py
  34. 53 0
      preset/app/29_environmentDetection.py
  35. 286 0
      preset/app/30_training_data_collect.py
  36. 262 0
      preset/app/31_training_deploy_model.py
  37. 230 0
      preset/app/32_mnistModelTraining.py
  38. 138 0
      preset/app/33_mnistCameraTest.py
  39. 231 0
      preset/app/34_CocoGPT.py
  40. 216 0
      preset/app/35_CocoTerminal.py
  41. 309 0
      preset/app/36_pictureAnalysis.py
  42. 299 0
      preset/app/37_speechToImageSynthesis.py
  43. 274 0
      preset/app/38_jumpbot.py
  44. 294 0
      preset/app/39_gluttonousSnake.py
  45. 61 0
      preset/app/40_soundLoudnessAnalysis.py
  46. 70 0
      preset/app/41_soundSpectrumAnalysis.py
  47. 39 0
      preset/app/checkout.py
  48. 130 0
      preset/app/git.py
  49. 5 0
      preset/app/ota.py
  50. 47 0
      preset/app/pull.py
  51. 23 0
      preset/app/reset.py
  52. 10 0
      preset/app/swremote.py
  53. 18 0
      preset/config/banner
  54. 198 0
      preset/config/update.py
  55. BIN
      preset/drivers/ASR/CocoPi_Asr_Model/CocoPi_Asr_Model_V2.1.bin
  56. 40 0
      preset/drivers/ASR/CocoPi_Asr_Model/CocoPi_Asr_Model_V2.1.param
  57. BIN
      preset/drivers/ASR/Pinyin_Lexicon/Pinyin_Lexicon.bin
  58. BIN
      preset/drivers/ASR/Pinyin_Lexicon/Pinyin_Lexicon.sfst
  59. BIN
      preset/drivers/ASR/Pinyin_Lexicon/Pinyin_Lexicon.sym
  60. BIN
      preset/drivers/ASR/Pinyin_Lexicon/Pinyin_Lexicon_Words.bin
  61. BIN
      preset/drivers/ASR/Pinyin_Lexicon/Pinyin_Lexicon_Words_utf.bin
  62. BIN
      preset/drivers/CR5205/CR5205.dtb
  63. BIN
      preset/drivers/CR5205/libisp_ini.so
  64. BIN
      preset/drivers/CR9685/CR9685.dtb
  65. BIN
      preset/drivers/CR9685/libisp_ini.so
  66. BIN
      preset/drivers/HCSR04/hcsr04.ko
  67. BIN
      preset/drivers/UVC/_coco_camera.so
  68. 183 0
      preset/drivers/pylib/GPTrequest.py
  69. BIN
      preset/img/animal/animal1.jpg
  70. BIN
      preset/img/animal/animal10.jpg
  71. BIN
      preset/img/animal/animal11.jpg
  72. BIN
      preset/img/animal/animal12.jpg
  73. BIN
      preset/img/animal/animal13.jpg
  74. BIN
      preset/img/animal/animal14.jpg
  75. BIN
      preset/img/animal/animal15.jpg
  76. BIN
      preset/img/animal/animal16.jpg
  77. BIN
      preset/img/animal/animal17.jpg
  78. BIN
      preset/img/animal/animal18.jpg
  79. BIN
      preset/img/animal/animal19.jpg
  80. BIN
      preset/img/animal/animal2.jpg
  81. BIN
      preset/img/animal/animal20.jpg
  82. BIN
      preset/img/animal/animal21.jpg
  83. BIN
      preset/img/animal/animal22.jpg
  84. BIN
      preset/img/animal/animal23.jpg
  85. BIN
      preset/img/animal/animal24.jpg
  86. BIN
      preset/img/animal/animal25.jpg
  87. BIN
      preset/img/animal/animal26.jpg
  88. BIN
      preset/img/animal/animal27.jpg
  89. BIN
      preset/img/animal/animal28.jpg
  90. BIN
      preset/img/animal/animal29.jpg
  91. BIN
      preset/img/animal/animal3.jpg
  92. BIN
      preset/img/animal/animal30.jpg
  93. BIN
      preset/img/animal/animal31.jpg
  94. BIN
      preset/img/animal/animal32.jpg
  95. BIN
      preset/img/animal/animal33.jpg
  96. BIN
      preset/img/animal/animal34.jpg
  97. BIN
      preset/img/animal/animal35.jpg
  98. BIN
      preset/img/animal/animal36.jpg
  99. BIN
      preset/img/animal/animal4.jpg
  100. BIN
      preset/img/animal/animal5.jpg

+ 6 - 0
.gitignore

@@ -0,0 +1,6 @@
+audio
+fonts
+model
+server
+training
+video

+ 1892 - 0
CocoPi.py

@@ -0,0 +1,1892 @@
+'''
+=========================================================
+    ______                         ______
+   /\  _  \                       /\  _  \  __
+   \ \ \/\_\    ____    ____   ___\ \ \_\ \/\_\
+    \ \ \/_/_  / __ \  / __ \ / __'\ \  __/\/_/_
+     \ \ \_\ \/\ \_\ \/\ \__//\ \_\ \ \ \/   /\ \
+      \ \____/\ \____/\ \____\ \____/\ \_\   \ \_\
+       \/___/  \/___/  \/____/\/___/  \/_/    \/_/
+  __
+ /\ \       __                           ----------------
+ \ \ \     /\_\    ____  __  __  __  _    pi.cocorobo.cn
+  \ \ \    \/_/_ /  _  \/\ \/\ \/\ \/ \  ----------------
+   \ \ \____ /\ \/\ \/\ \ \ \_\ \/>  </   SYSTEM VERSION
+    \ \_____\\ \_\ \_\ \_\ \____//\_/\_\  -- 24.07.05 ---
+     \/_____/ \/_/\/_/\/_/\/___/ \//\/_/ ----------------
+
+=========================================================
+'''
+#########################################################
+# ------------------------------------------------------
+#|          封装包内容:         |        类名称:      |
+#|-------------------------------|----------------------|
+#|  2023.02.16:                  |                      |
+#|  【添加】                     |                      |
+#|  1、AHT20温湿度传感器         |    AHT20             |
+#|  2、MPU6050陀螺仪六轴传感器   |    MPU6050           |
+#|  3、板载4颗按钮A、B、C、D     |    BUTTON            |
+#|  4、光线强度传感器            |    LIGHTINTENSITY    |
+#|  5、板载LED灯!                |    LED               |
+#|  6、直流电机                  |    DCMOTOR           |
+#|  7、模拟舵机                  |    SERVO             |
+#|------------------------------------------------------|
+#|  2023.02.27:                  |                      |
+#|  【修复完善】                 |    BUTTON、LED       |
+#|  【添加】                     |    WIFI              |
+#|------------------------------------------------------|
+#|  2023.03.09:                 |                      |
+#|  【修复完善】                 |    LED               |
+#|------------------------------------------------------|
+#|  2023.03.14:                  |                      |
+#|  【修复完善】                 |    SERVO             |
+#|-------------------------------------------------------
+#|  2023.06.01:                  |                      |
+#|  【替换】                     |    BUTTON            |
+#|  【替换】                     |    LED               |
+#|  【替换】                     |    DCMOTOR           |
+#|  【替换】                     |    SERVO             |
+#|  【添加】                     |    RGB               |
+#|  【添加】                     |    ADC               |
+#|  【添加】                     |    DAC               |
+#|  【添加】                     |    INPUT             |
+#|  【添加】                     |    OUT               |
+#|  【添加】                     |    UvcVideo          |
+#|-------------------------------------------------------
+#|  2023.06.15:                  |                      |
+#|  【更改】                     |    STM8S             |
+#|-------------------------------------------------------
+#|  2023.08.17:                  |                      |
+#|  【更改】                     |    DCMOTOR           |
+#|-------------------------------------------------------
+#|  2023.08.25:                  |                      |
+#|  【更改】                     |    BUZZER            |
+#|-------------------------------------------------------
+#|  2023.09.28:                  |                      |
+#|  【更改】                     |    QMI8658           |
+#########################################################
+#|-------------------------------------------------------
+#|  2024.02.22:                  |                      |
+#|  【更改】                     |    QMI8658           |
+#########################################################
+#|  2024.02.28:                  |                      |
+#|  【更改】                     |    STM8S             |
+#########################################################
+#|  2024.03.07:                  |                      |
+#|  【添加】                     |    GPTrequest        |
+#########################################################
+#|  2024.03.11:                  |                      |
+#|  【修改】                     |    LED               |
+#|  【修改】                     |    DCMOTOR           |
+#########################################################
+#|  2024.03.22:                  |                      |
+#|  【增加】                     |    RTC               |
+#|  【增加】                     |    PCA9685           |
+#########################################################
+#|  2024.04.10:                  |                      |
+#|  【修改】                     |    GPTrequest        |
+#########################################################
+#|  2024.07.05:                  |                      |
+#|  【增加】                     |    LazyImport        |
+#|      【针对】                 |    GPTrequest        |
+#|      【针对】                 |    uuid              |
+#|      【针对】                 |    json              |
+#|      【针对】                 |    base64            |
+#|  【修改】                     |    STM8S             |
+#|  【修改】                     |    DCMOTOR           |
+#|  【修改】                     |    multiFuncGpio     |
+#|  【增加】                     |    DS3231            |
+#|  【增加】                     |    SPI_WS2812        |
+#|  【增加】                     |    HCSR04            |
+#|  【增加】                     |    extDcMotor        |
+#|  【增加】                     |    extServo          |
+#|  【增加】                     |    extGpio           |
+#|  【拆分】                     |    GPTrequest        |
+#########################################################
+
+
+from smbus2 import SMBus
+import time
+import math
+from maix import gpio
+import os
+import SUNXI_GPIO
+from maix import camera
+import time
+import sys
+#20240715
+import threading
+sys.path.append('/root/preset/server')
+
+##################################
+#     1、AHT20温湿度传感器       #
+##################################
+
+AHT20_I2CADDR = 0x38
+AHT20_CMD_SOFTRESET = [0xBA]
+AHT20_CMD_INITIALIZE = [0xBE, 0x08, 0x00]
+AHT20_CMD_MEASURE = [0xAC, 0x33, 0x00]
+AHT20_STATUSBIT_BUSY = 7                    # The 7th bit is the Busy indication bit. 1 = Busy, 0 = not.
+AHT20_STATUSBIT_CALIBRATED = 3              # The 3rd bit is the CAL (calibration) Enable bit. 1 = Calibrated, 0 = not
+
+class AHT20:
+    # Usage: AHT20 crc8 checker. 
+    # A total of 6 * 8 bits data need to check. G(x) = x8 + x5 + x4 + 1 -> 0x131(0x31), Initial value = 0xFF. No XOROUT. 
+    N_DATA = 6
+    # 1 * 8 bits CRC
+    N_CRC = 1
+    # Initial value. Equal to bit negation the first data (status of AHT20)
+    INIT = 0xFF
+    # Useful value to help calculate
+    LAST_8_bit = 0xFF
+    # Devide number retrieve from CRC-8 MAXIM G(x) = x8 + x5 + x4 + 1
+    CRC_DEVIDE_NUMBER = 0x131
+    
+    # I2C communication driver for AHT20, using only smbus2
+    def __init__(self, BusNum=2):
+        # Initialize AHT20
+        self.BusNum = BusNum
+        self.cmd_soft_reset()
+
+        # Check for calibration, if not done then do and wait 10 ms
+        if not self.get_status_calibrated == 1:
+            self.cmd_initialize()
+            while not self.get_status_calibrated() == 1:
+                time.sleep(0.01)
+                
+    def get_normalized_bit(self,value, bit_index):
+        # Return only one bit from value indicated in bit_index
+        return (value >> bit_index) & 1
+        
+    def cmd_soft_reset(self):
+        # Send the command to soft reset
+        with SMBus(self.BusNum) as i2c_bus:
+            i2c_bus.write_i2c_block_data(AHT20_I2CADDR, 0x0, AHT20_CMD_SOFTRESET)
+        time.sleep(0.04)    # Wait 40 ms after poweron
+        return True
+
+    def cmd_initialize(self):
+        # Send the command to initialize (calibrate)
+        with SMBus(self.BusNum) as i2c_bus:
+            i2c_bus.write_i2c_block_data(AHT20_I2CADDR, 0x0 , AHT20_CMD_INITIALIZE)
+        return True
+
+    def cmd_measure(self):
+        # Send the command to measure
+        with SMBus(self.BusNum) as i2c_bus:
+            i2c_bus.write_i2c_block_data(AHT20_I2CADDR, 0, AHT20_CMD_MEASURE)
+        time.sleep(0.08)    # Wait 80 ms after measure
+        return True
+
+    def get_status(self):
+        # Get the full status byte
+        with SMBus(self.BusNum) as i2c_bus:
+            return i2c_bus.read_i2c_block_data(AHT20_I2CADDR, 0x0, 1)[0]
+        return True
+
+    def get_status_calibrated(self):
+        # Get the calibrated bit
+        return self.get_normalized_bit(self.get_status(), AHT20_STATUSBIT_CALIBRATED)
+
+    def get_status_busy(self):
+        # Get the busy bit
+        return self.get_normalized_bit(self.get_status(), AHT20_STATUSBIT_BUSY)
+            
+    def get_measure(self):
+        # Get the full measure
+
+        # Command a measure
+        self.cmd_measure()
+
+        # Check if busy bit = 0, otherwise wait 80 ms and retry
+        while self.get_status_busy() == 1:
+            time.sleep(0.08) # Wait 80 ns
+        
+        # TODO: do CRC check
+
+        # Read data and return it
+        with SMBus(self.BusNum) as i2c_bus:
+            return i2c_bus.read_i2c_block_data(AHT20_I2CADDR, 0x0, 7)
+
+    def mod2_division_8bits(self,a, b, number_of_bytes, init_value):
+        "calculate mod2 division in 8 bits. a mod b. init_value is for crc8 init value."
+        head_of_a = 0x80
+        # Processiong a
+        a = a << 8
+        # Preprocessing head_of_a
+        for i in range(0, number_of_bytes):
+            head_of_a = head_of_a << 8
+            b = b << 8
+            init_value = init_value << 8
+        a = a ^ init_value
+        while (head_of_a > 0x80):
+            # Find a 1
+            if (head_of_a & a):
+                head_of_a = head_of_a >> 1
+                b = b >> 1
+                a = a ^ b
+            else:
+                head_of_a = head_of_a >> 1
+                b = b >> 1
+            # This will show calculate the remainder
+            # print("a:{0}\thead of a:{1}\tb:{2}".format(
+            #     bin(a), bin(head_of_a), bin(b)))
+        return a
+
+    def AHT20_crc8_calculate(self,all_data_int):
+        init_value = INIT
+        # Preprocess all the data and CRCCode from AHT20
+        data_from_AHT20 = 0x00
+        # Preprocessing the first data (status)
+        # print(bin(data_from_AHT20))
+        for i_data in range(0, len(all_data_int)):
+            data_from_AHT20 = (data_from_AHT20 << 8) | all_data_int[i_data]
+        # print(bin(data_from_AHT20))
+        mod_value = self.mod2_division_8bits(
+            data_from_AHT20, CRC_DEVIDE_NUMBER, len(all_data_int), init_value)
+        # print(mod_value)
+        return mod_value
+
+
+    def AHT20_crc8_check(self,all_data_int):
+        """
+        The input data shoule be:
+        Status Humidity0 Humidity1 Humidity2|Temperature0 Temperature1 Temperature2 CRCCode.
+        In python's int64.
+        """
+        mod_value = self.AHT20_crc8_calculate(all_data_int[:-1])
+        if (mod_value == all_data_int[-1]):
+            return True
+        else:
+            return False
+
+    def get_measure_CRC8(self):
+        """
+        This function will calculate crc8 code with G(x) = x8 + x5 + x4 + 1 -> 0x131(0x31), Initial value = 0xFF. No XOROUT.
+        return: all_data (1 bytes status + 2.5 byes humidity + 2.5 bytes temperature + 1 bytes crc8 code), isCRC8_pass
+        """
+        all_data = self.get_measure()
+        isCRC8_pass = self.AHT20_crc8_check(all_data)
+
+        return all_data, isCRC8_pass
+
+    def get_temperature(self):
+        # Get a measure, select proper bytes, return converted data
+        measure = self.get_measure()
+        measure = ((measure[3] & 0xF) << 16) | (measure[4] << 8) | measure[5]
+        measure = measure / (pow(2,20))*200-50
+        return measure
+        
+    def get_temperature_crc8(self):
+        isCRC8Pass = False
+        while (not isCRC8Pass): 
+            measure, isCRC8Pass = self.get_measure_CRC8()
+            time.sleep(80 * 10**-3)
+        measure = ((measure[3] & 0xF) << 16) | (measure[4] << 8) | measure[5]
+        measure = measure / (pow(2,20))*200-50
+        return measure
+
+    def get_humidity(self):
+        # Get a measure, select proper bytes, return converted data
+        measure = self.get_measure()
+        measure = (measure[1] << 12) | (measure[2] << 4) | (measure[3] >> 4)
+        measure = measure * 100 / pow(2,20)
+        return measure
+
+    def get_humidity_crc8(self):
+        isCRC8Pass = False
+        while (not isCRC8Pass): 
+            measure, isCRC8Pass = self.get_measure_CRC8()
+            time.sleep(80 * 10**-3)
+        measure = (measure[1] << 12) | (measure[2] << 4) | (measure[3] >> 4)
+        measure = measure * 100 / pow(2,20)
+        return measure
+
+##################################
+#   2、MPU6050陀螺仪六轴传感器   #
+##################################
+
+SLAVE_ADDR = 0x68
+
+PWR_MGMT_1 = 0x6B
+PWR_MGMT_2 = 0x6C
+WHO_AM_I = 0x75
+
+GYRO_X = 0x43
+GYRO_Y = 0x45
+GYRO_Z = 0x47
+
+ACCL_X = 0x3B
+ACCL_Y = 0x3D
+ACCL_Z = 0x3F
+
+class MPU6050:
+    def __init__(self, BusNum=2):
+        # Initialize mpu6050
+        self.BusNum = BusNum
+        self.cmd_soft_reset()
+        
+    def cmd_soft_reset(self):
+        # Send the command to soft reset
+        with SMBus(self.BusNum) as bus:
+            bus.write_byte_data(SLAVE_ADDR, PWR_MGMT_1, 0)
+        time.sleep(0.04)    # Wait 40 ms after poweron
+
+    def read_byte(self,addr):
+        with SMBus(self.BusNum) as bus:
+            return bus.read_byte_data(SLAVE_ADDR,addr)
+
+    def read_word(self,addr):
+        with SMBus(self.BusNum) as bus:
+            h = bus.read_byte_data(SLAVE_ADDR, addr)
+            l = bus.read_byte_data(SLAVE_ADDR, addr+1)
+        val = (h << 8) + l
+        return val
+
+    def read_word_i2c(self,addr):
+        val = self.read_word(addr)
+        if (val >= 0x8000):
+            return -((65535 - val) + 1)
+        else:
+            return val
+
+    def dist(self,x, y):
+        return math.sqrt((x*x) + (y*y))
+
+    def get_x_rotat(self,x,y, z):
+        rad = math.atan2(y,self.dist(x, z))
+        return math.degrees(rad)
+
+    def get_y_rotat(self,x, y, z):
+        rad = math.atan2(x,self.dist(y, z))
+        return -math.degrees(rad)
+
+    def read_gyro(self):
+        GYR_X = self.read_word_i2c(GYRO_X)
+        GYR_Y = self.read_word_i2c(GYRO_Y)
+        GYR_Z = self.read_word_i2c(GYRO_Z)
+
+        #print ("GYRO -> X:{:04.2f} Y:{:04.2f} Z:{:04.2f}".format((GYR_X/131), (GYR_Y/131), (GYR_Z/131)))
+        return (GYR_X/131), (GYR_Y/131), (GYR_Z/131)
+
+    def read_acc(self):
+        ACC_X = self.read_word_i2c(ACCL_X)
+        ACC_Y = self.read_word_i2c(ACCL_Y)
+        ACC_Z = self.read_word_i2c(ACCL_Z)
+
+        CALC_ACC_X = ACC_X/16384.0
+        CALC_ACC_Y = ACC_Y/16384.0
+        CALC_ACC_Z = ACC_Z/16384.0
+
+        #print ("ACCL -> X:{:04.2f} Y:{:04.2f} Z:{:04.2f}".format(CALC_ACC_X, CALC_ACC_Y, CALC_ACC_Z))
+        #print("ROTATE -> X:{:04.2f} Y:{:04.2f}\n".format(get_x_rotat(CALC_ACC_X, CALC_ACC_Y, CALC_ACC_Z), get_y_rotat(CALC_ACC_X, CALC_ACC_Y, CALC_ACC_Z)))
+        return CALC_ACC_X, CALC_ACC_Y, CALC_ACC_Z,self.get_x_rotat(CALC_ACC_X, CALC_ACC_Y, CALC_ACC_Z),self.get_y_rotat(CALC_ACC_X, CALC_ACC_Y, CALC_ACC_Z)
+    
+    def get_gyro_x(self):
+        return self.read_gyro()[0]
+    
+    def get_gyro_y(self):
+        return self.read_gyro()[1]
+    
+    def get_gyro_z(self):
+        return self.read_gyro()[2]
+    
+    def get_acc_x(self):
+        return self.read_acc()[0]
+    
+    def get_acc_y(self):
+        return self.read_acc()[1]
+    
+    def get_acc_z(self):
+        return self.read_acc()[2]
+    
+    def get_angle_x(self):
+        return self.read_acc()[3]
+    
+    def get_angle_y(self):
+        return self.read_acc()[4]
+
+##################################
+#    3、板载4颗按钮A、B、C、D    #
+##################################
+class BUTTON:
+    def __init__(self, gpioId):
+        self.gpio=224+gpioId
+        SUNXI_GPIO.setcfg(self.gpio, SUNXI_GPIO.IN)
+
+    def is_pressed(self):
+        self.getValue=SUNXI_GPIO.input(self.gpio)
+        if self.getValue != 1:
+            return True
+        else:
+            return False
+
+##################################
+#       4、光线强度传感器        #
+##################################
+class LIGHTINTENSITY:
+    def __init__(self, addr=b"0x05070080") -> None:
+        self.addr = addr
+        self.path = "/sys/class/sunxi_dump/dump"
+        self.file = open(self.path, "wb+")
+        self.last = self.value()
+    def value(self):
+        self.file.write(b"0x05070080")
+        self.file.seek(0)
+        return int(self.file.read()[:-1], 16)
+    def __del__(self):
+        try:
+            if self.file:
+                self.file.close()
+                del self.file
+        except Exception as e:
+            pass
+
+##################################
+#         5、板载LED灯           #
+##################################
+class LED:
+    def __init__(self, gpioId=69):
+        self.gpioId=gpioId
+        SUNXI_GPIO.setcfg(self.gpioId, SUNXI_GPIO.OUT)
+    def out(self,value):
+        if value==0 or value==1:
+            self.value=1-value
+        else:
+            self.value=0
+        SUNXI_GPIO.output(self.gpioId,self.value)
+
+##################################
+#          6、QMI8658            #
+##################################
+class QMI8658(object):
+    def __init__(self, smbus=2, address=0X6B):
+        self._address = address
+        import smbus2
+        self._bus = smbus2.SMBus(smbus)
+        bRet = self.WhoAmI()
+        if bRet:
+            self.Read_Revision()
+        else:
+            return None
+        self.Config_apply()
+
+    def _read_byte(self, cmd):
+        rec = self._bus.read_i2c_block_data(int(self._address), int(cmd), 1)
+        return rec[0]
+
+    def _read_block(self, reg, length=1):
+        rec = self._bus.read_i2c_block_data(int(self._address), int(reg), length)
+        return rec
+
+    def _read_u16(self, cmd):
+        LSB = self._bus.read_i2c_block_data(int(self._address), int(cmd), 1)
+        MSB = self._bus.read_i2c_block_data(int(self._address), int(cmd)+1, 1)
+        return (MSB[0] << 8) + LSB[0]
+
+    def _write_byte(self, cmd, val):
+        self._bus.write_i2c_block_data(int(self._address), int(cmd), bytes([int(val)]))
+
+    def WhoAmI(self):
+        bRet = False
+        if (0x05) == self._read_byte(0x00):
+            bRet = True
+        return bRet
+
+    def Read_Revision(self):
+        return self._read_byte(0x01)
+
+    def Config_apply(self):
+        self._write_byte(0x02, 0x40)
+        self._write_byte(0x08, 0x03)
+        self._write_byte(0x03, 0x04)
+        self._write_byte(0x04, 0x64)
+        self._write_byte(0x06, 0x11)
+
+    def Read_Raw_XYZ(self):
+        xyz = [0, 0, 0, 0, 0, 0]
+        vals={}
+        raw_timestamp = self._read_block(0x30, 3)
+        raw_acc_xyz = self._read_block(0x35, 6)
+        raw_gyro_xyz = self._read_block(0x3b, 6)
+        raw_xyz = self._read_block(0x35, 12)
+        timestamp = (raw_timestamp[2] << 16) | (
+            raw_timestamp[1] << 8) | (raw_timestamp[0])
+        for i in range(6):
+            xyz[i] = (raw_xyz[(i*2)+1] << 8) | (raw_xyz[i*2])
+            if xyz[i] >= 32767:
+                xyz[i] = xyz[i]-65535
+        vals["AcX"]=xyz[0]
+        vals["AcY"]=xyz[1]
+        vals["AcZ"]=xyz[2]
+        vals["GyX"]=xyz[3]
+        vals["GyY"]=xyz[4]
+        vals["GyZ"]=xyz[5]
+        return vals
+
+    def Read_XYZ(self):
+        xyz = [0, 0, 0, 0, 0, 0]
+        raw_xyz = self.Read_Raw_XYZ()
+        #QMI8658AccRange_8g
+        acc_lsb_div = (1 << 12)
+        #QMI8658GyrRange_512dps
+        gyro_lsb_div = 64
+        for i in range(3):
+            xyz[i] = raw_xyz[i]/acc_lsb_div  # (acc_lsb_div/1000.0)
+            xyz[i+3] = raw_xyz[i+3]*1.0/gyro_lsb_div
+        return xyz
+    
+    def get_accel(self, samples=10, calibration=None):
+        result = {}
+        for _ in range(samples):
+            v = self.Read_Raw_XYZ()
+            for m in v.keys():
+                result[m] = result.get(m, 0) + v[m] / samples
+        if calibration:
+            for m in calibration.keys():
+                if m == "AcZ":
+                    pass
+                else:
+                    result[m] -= calibration[m]
+        return result
+
+    def calibrate(self, threshold=50):
+        print('Calibrating QMI8658... ', end='')
+        while True:
+            v1 = self.get_accel(100)
+            v2 = self.get_accel(100)
+            if all(abs(v1[m] - v2[m]) < threshold for m in v1.keys()):
+                print('Done.')
+                return v1
+            
+    def getPitchYawRollGxGyGz(self,calibration):
+        caliData=self.get_accel(10, calibration)
+        pitch=caliData["AcX"]/182.04
+        yaw=caliData["AcY"]/182.04
+        roll=caliData["AcZ"]/182.04
+        groX=caliData["GyX"]
+        groY=caliData["GyY"]
+        groZ=caliData["GyZ"]
+        if roll<0:
+            if pitch >=0:
+                pitch=180-pitch
+            elif pitch <0:
+                pitch=(180+pitch)*(-1)
+            if yaw >=0:
+                yaw=180-yaw
+            elif pitch <0:
+                yaw=(180+yaw)*(-1)
+        return [pitch,yaw,roll,groX,groY,groZ]
+
+
+##################################
+#          7、STM8S              #
+##################################
+import smbus2
+import time
+
+class stm8s(object):
+
+    bus = smbus2.SMBus(2) # 2 indicates /dev/i2c-2
+    address = 0x50
+
+    # 0x00 # 触发配置
+    # 0x01 # 重置配置
+    # 0x02 # pwm0 历史配置
+    # 0x03 # pwm1 历史配置
+
+    # 引脚配置模式有 1. pwm 2. gpio ouput gpio input 3. adc 4.ws2812_singe 5 ws2812_multi
+    def __init__(self):
+        self.reset()
+        time.sleep(0.05)
+        pass
+    
+    def clear(self):
+        self.write(1, 1)
+        self.reset()
+        time.sleep(0.05)
+    
+    def write(self, addr, val):
+        for i in range(0, 3):
+            try:
+                self.bus.write_byte_data(self.address, addr, val)
+                time.sleep(0.001) # 1ms
+                # print(addr, val) # debug
+                return True
+            except Exception:
+                time.sleep(0.01)
+                continue
+        return False
+    
+    def fastWrite(self,addr,valBlock):
+        try:
+            self.bus.write_i2c_block_data(self.address,addr,valBlock)
+            return True
+        except Exception:
+            return False
+
+    def read(self, addr):
+        for i in range(0, 3):
+            try:
+                tmp = self.bus.read_byte_data(self.address, addr)
+                time.sleep(0.001) # 1ms
+                # print(addr, tmp) # debug
+                return tmp
+            except Exception:
+                time.sleep(0.01)
+                continue
+        return None
+
+    def reset(self):
+        self.write(0, 1)
+        time.sleep(0.05) # 重启并配置需要时间
+
+    def dump(self):
+        for i in range(0, 32):
+            print(i, self.read(i))
+
+class singleRgb(stm8s):
+    def __init__(self):
+        self.valR=0
+        self.valG=0
+        self.valB=0
+        self.brightness=255
+        self.show()
+    
+    def setColor(self,r,g,b):
+        if(r>=0 and r<=255):
+            self.valR=int(r*self.brightness/255)
+        else:
+            self.valR=0
+        if(g>=0 and g<=255):
+            self.valG=int(g*self.brightness/255)
+        else:
+            self.valG=0
+        if(b>=0 and b<=255):
+            self.valB=int(b*self.brightness/255)
+        else:
+            self.valB=0
+            
+    def setBrightness(self,brightness):
+        if(brightness>=0 and brightness<=255):
+            self.brightness=brightness
+        else:
+            self.brightness=0
+    
+    def show(self):
+        self.write(31, self.valB)
+        self.write(30, self.valG)
+        self.write(29, self.valR)
+        self.write(28, 6)
+
+class dcMotor(stm8s):
+    def __init__(self,id):
+        self.id=id
+
+    def m1a(self,val=0):
+        self.write(4,5)    #M1A
+        #self.write(5,0)
+        #self.write(6,0)
+        self.write(7,val)
+        
+    def m1b(self,val=0):
+        self.write(8,5)    #M1B
+        #self.write(9,0)
+        #self.write(10,0)
+        self.write(11,val)
+        
+    def m2a(self,val=0):
+        self.write(12,5)    #M2A
+        #self.write(13,0)
+        #self.write(14,0)
+        self.write(15,val)
+        
+    def m2b(self,val=0):
+        self.write(16,5)    #M2B
+        #self.write(17,0)
+        #self.write(18,0)
+        self.write(19,val)
+        
+    def dcMotorCtrl(self,dir,speed):
+        dir=1-dir
+        if(0<speed and speed<255):
+            if(self.id ==1):                #Motor1
+                if(dir==0):
+                    self.m1a(speed)
+                    self.m1b(255)
+                else:
+                    self.m1a(255)
+                    self.m1b(speed)
+            elif(self.id ==2):
+                if(dir==0):
+                    self.m2a(speed)
+                    self.m2b(255)
+                else:
+                    self.m2a(255)
+                    self.m2b(speed)
+        elif(0==speed):
+            if(self.id ==1):                #Motor1
+                if(dir==0):
+                    self.m1a(255)
+                    self.m1b(255)
+                else:
+                    self.m1a(255)
+                    self.m1b(255)
+            elif(self.id ==2):
+                if(dir==0):
+                    self.m2a(255)
+                    self.m2b(255)
+                else:
+                    self.m2a(255)
+                    self.m2b(255)
+        elif(speed==255):
+            if(self.id ==1):                #Motor1
+                if(dir==0):
+                    self.m1a(0)
+                    self.m1b(255)
+                else:
+                    self.m1a(255)
+                    self.m1b(0)
+            elif(self.id ==2):
+                if(dir==0):
+                    self.m2a(0)
+                    self.m2b(255)
+                else:
+                    self.m2a(255)
+                    self.m2b(0)
+        else:
+            pass
+            
+class multiFuncGpio(stm8s):
+    def __init__(self,id=0,mode=0):
+        self.id=id
+        self.rgbId=0
+        self.brightness=255
+        self.mode=mode
+        self.write(20+self.id*4,self.mode)
+        self.rgbSerial=[0,0,0]*10
+        time.sleep(0.05)
+    ##################################################
+    # mode |  0  |  1  |  2  |  3  |  4  |  5  |  6  |      
+    #-------------------------------------------------
+    # Func |free |servo|INPUT| OUT | ADC | PWM | BEEP|
+    ##################################################
+    # mode=0,为空闲状态,引脚不执行任何功能
+    # mode=1,为控制舵机模式,值控制范围为0°~180°
+    # mode=2,为数字输入模式,返回值0或1
+    # mode=3,为数字输出模式,输出值为0或1
+    # mode=4,为ADC采样模式,返回值为0~1023
+    # mode=5,为PWM输出模式,输出值范围为0~255
+    # mode=6,为控制蜂鸣器模式,控制范围为20hz~12000hz
+    # mode=7,为控制灯带模式,暂未实现
+    # id=0,控制多功能引脚1,向20号寄存器写入模式数据
+    # id=1,控制多功能引脚2,向24号寄存器写入模式数据
+    
+    def servoCtrl(self,angle):
+        if ((angle>=0) and (angle<=180)):
+            self.write(23+self.id*4,angle)
+        else:
+            pass
+            
+    def digitalRead(self):
+        try:
+            self.gpioVal= self.read(23+ self.id*4)
+            if(self.gpioVal != None):
+                return self.gpioVal
+        except:
+            print("ERROR 233")
+    
+    def digitalWrite(self,val):
+        if ((val>=0) and (val<=1)):
+            self.write(23+self.id*4,val)
+        else:
+            pass
+            
+    def analogRead(self):
+        try:
+            self.adcValH= self.read(22+ self.id*4)
+            self.adcValL= self.read(23+ self.id*4)
+            if (self.adcValH != None and self.adcValL != None):
+            # adcValH adcValL 大小端合并 16bit
+                self.adcVal = self.adcValL + (self.adcValH << 8)
+                return self.adcVal
+        except:
+            print("ERROR 2333")
+        
+    def analogWrite(self,val):
+        if ((val>=0) and (val<=255)):
+            self.write(23+self.id*4,val)
+        else:
+            pass
+            
+    
+    def beep(self,frequency):
+        if ((frequency>=20) and (frequency<=12000)):
+            self.write(22+self.id*4,frequency>>8)
+            self.write(23+self.id*4,frequency&0b11111111)
+        else:
+            pass
+        
+    def pixelInit_(self):
+        for i in range(16):
+            self.setPixelColor(i,0,0,0)
+            self.pixelShow()
+        self.write(23+self.id*4,1)
+    
+    def setBrightness(self,brightness):
+        if(brightness>=0 and brightness<=255):
+            self.brightness=brightness
+        else:
+            self.brightness=0
+    
+    def setPixelColor(self,rgbId,r,g,b):
+        if(rgbId >=0 and rgbId <=15):
+            self.rgbId=rgbId    #rgbId范围:0~15
+        else:
+            self.rgbId=0
+        if(r>=0 and r<=255):
+            self.valR=int(r*self.brightness/255)
+        else:
+            self.valR=0
+        if(g>=0 and g<=255):
+            self.valG=int(g*self.brightness/255)
+        else:
+            self.valG=0
+        if(b>=0 and b<=255):
+            self.valB=int(b*self.brightness/255)
+        else:
+            self.valB=0
+    
+    #self.id的值为0或1,用于控制灯带缓冲区(S1或者S2引脚)
+    def pixelShow(self):
+        self.write(32+ self.id*48+self.rgbId*3, self.valR)    
+        self.write(33+ self.id*48+self.rgbId*3, self.valG)
+        self.write(34+ self.id*48+self.rgbId*3, self.valB)
+    def setRgbSerialColor(self,rgbId,r,g,b):
+        if(rgbId >=0 and rgbId <=15):
+            self.rgbId=rgbId    #rgbId范围:0~15
+        else:
+            self.rgbId=0
+        if(r>=0 and r<=255):
+            self.valR=int(r*self.brightness/255)
+        else:
+            self.valR=0
+        if(g>=0 and g<=255):
+            self.valG=int(g*self.brightness/255)
+        else:
+            self.valG=0
+        if(b>=0 and b<=255):
+            self.valB=int(b*self.brightness/255)
+        else:
+            self.valB=0
+        self.rgbSerial[self.rgbId*3]=self.valR
+        self.rgbSerial[self.rgbId*3+1]=self.valG
+        self.rgbSerial[self.rgbId*3+2]=self.valB
+    
+    def rgbSerialShow(self):
+        self.fastWrite(32+self.id*48,self.rgbSerial)
+        self.write(23+self.id*4,1)
+        
+
+##################################
+#          8、UvcVideo           #
+##################################
+
+class UvcVideo(camera.MaixVideo):
+
+    def __init__(self, source="/dev/videoX"):
+        self.source = source
+        super(UvcVideo, self).__init__()
+        import os, time
+        usb_path = '/sys/devices/platform/soc/usbc0/otg_role'
+        # 确认 usb_path 内容为 usb_host 如果不是,自动设置为 usb_host
+        if os.popen('cat %s' % usb_path).read().strip() != 'usb_host':
+            os.system('echo "usb_host" > %s' % usb_path)
+            time.sleep(2) # 要设置 2s 左右才能初始化工作,否则会报 VIDIOC_S_FMT 失败。
+
+    def config(self, size=None, video=2, horizontal=0, vertical=0):
+        if size == None:
+            size = (320, 240)
+        super(UvcVideo, self).config(size)
+        print('[camera] config input size(%d, %d, %d)' %
+            (self.width(), self.height(), video))
+        if self.cam:
+            self.cam = None
+        try:
+            import _coco_camera
+            self.cam = _coco_camera.Camera(self.width(), self.height(), video, horizontal, vertical)
+        except Exception as e:
+            print(e)
+            self.cam = None
+
+    def read(self):
+        if self.cam == None:
+            self.config()
+        if self.cam:
+            ret, frame = self.cam.read()
+            if ret:
+                return frame  # bytes
+            else:
+                try:
+                    self.config()
+                except Exception as e:
+                    print(e)
+        return None
+
+    def __del__(self):
+        if self.cam:
+            self.cam = None
+
+
+
+##################################
+#          9、DS3231             #
+##################################
+
+
+from math import  floor
+
+class DS3231(object):
+    # create RTC instance
+    def __init__(self):
+        self.bus = smbus2.SMBus(2) # 2 indicates /dev/i2c-2
+        self.address = 0x68
+    
+    def bcd_to_int(self,bcd, n=2):
+        """Decode n least significant packed binary coded decimal digits to binary.
+        Return binary result.
+        n defaults to 2 (BCD digits).
+        n=0 decodes all digits.
+        """
+        return int(('%x' % bcd)[-n:])
+
+
+    def int_to_bcd(self,x, n=2):
+        """
+        Encode the n least significant decimal digits of x
+        to packed binary coded decimal (BCD).
+        Return packed BCD value.
+        n defaults to 2 (digits).
+        n=0 encodes all digits.
+        """
+        return int(str(x)[-n:], 0x10)
+    
+    
+    def read(self, addr):
+        for i in range(0, 3):
+            try:
+                tmp = self.bus.read_byte_data(self.address, addr)
+                time.sleep(0.001) # 1ms
+                # print(addr, tmp) # debug
+                return tmp
+            except Exception:
+                time.sleep(0.01)
+                continue
+        return None
+
+    def write(self, addr, val):
+        for i in range(0, 3):
+            try:
+                self.bus.write_byte_data(self.address, addr, val)
+                #time.sleep(0.001) # 1ms
+                # print(addr, val) # debug
+                return True
+            except Exception:
+                time.sleep(0.001)
+                continue
+        return False
+
+    # set times functions ----------------------------------------
+    def setYear(self, year): 
+        # only last two digits (last two digits are used if longer)
+        self.write(0x06, self.int_to_bcd(year%100))
+
+    def setMonth(self, month):
+        if not 1 <= month <= 12:
+            raise ValueError('Month is out of range [1,12].')
+        self.write(0x05,self.int_to_bcd(month))
+    
+    def setDay(self, day):
+        if not 1 <= day <= 31:
+            raise ValueError('Day is out of range [1,31].')
+        self.write(0x04,self.int_to_bcd(day))
+    
+    def setDayOfWeek(self, dayOfWeek):
+        if not 1 <= dayOfWeek <= 7:
+            raise ValueError('Day of week is out of range [1,7].')
+        self.write(0x03,self.int_to_bcd(dayOfWeek))
+        
+    def setHour(self, hour):
+        if not 0 <= hours < 24:
+            raise ValueError('Hours is out of range [0,23].')
+        self.write(0x02,self.int_to_bcd(hour)& 0x3F)
+        
+    def setMinutes(self, minutes):
+        if not 0 <= minutes < 59:
+            raise ValueError('Minutes is out of range [0,59].')
+        self.write(0x01,self.int_to_bcd(minutes))
+    
+    def setSeconds(self, seconds):
+        if not 0 <= seconds < 60:
+            raise ValueError('Seconds is out of range [0,59].')
+        self.write(0x00,self.int_to_bcd(seconds))
+        
+    def setDateTime(self, year, month, day, dayOfWeek, hour, minutes, seconds): 
+        # set all the date and times (year is last two digits of year)
+        self.setYear(year)
+        self.setMonth(month)
+        self.setDay(day)
+        self.setDayOfWeek(dayOfWeek)
+        self.setHour(hour)
+        self.setMinutes(minutes)
+        self.setSeconds(seconds)
+
+    # get times functions -------------------------------------------------
+    def getYear(self):
+        return self.bcd_to_int(self.read(0x06))
+    
+    def getMonth(self):
+        temp = self.read(0x05)
+        return self.bcd_to_int((temp<<4>>4) &0x7F)
+        #return temp[0] & 0x7F
+    
+    def getDay(self):
+        # 0 - 31
+        return self.bcd_to_int(self.read(0x04))
+        
+    def getDayOfWeek(self):
+        # 1 - 7
+        return self.bcd_to_int(self.read(0x03))
+    
+    def getHour(self):
+        temp = self.read(0x02)
+        if temp==0x64:    #if hour is 24:00,convert it to 00:00
+            temp=0x40
+        return self.bcd_to_int((temp<< 4 >>4)& 0x3F)
+        #return temp[0] & 0x3F
+    
+    def getMinutes(self):
+        return self.bcd_to_int(self.read(0x01))
+    
+    def getSeconds(self):
+        return self.bcd_to_int(self.read(0x00))
+    
+    def getDateTime(self): 
+        # returns whole date and time as list 
+        # (last two digits of year, month, day, day of week, hour, minutes, seconds)
+        dateTime = [0, 0, 0, 0, 0, 0, 0]
+        dateTime[0] = self.getYear()
+        dateTime[1] = self.getMonth()
+        dateTime[2] = self.getDay()
+        dateTime[3] = self.getDayOfWeek()
+        dateTime[4] = self.getHour()
+        dateTime[5] = self.getMinutes()
+        dateTime[6] = self.getSeconds()
+        return dateTime
+
+    def convertToByteType(self,number):
+        return bytes([number])
+
+    def decodeToDec(self,byte):
+        return ((byte[0] >> 4) * 10) + (byte[0] & 0x0F)
+
+    def encodeToByte(self,dec):
+        tens = floor(dec / 10)
+        ones = dec - tens*10
+        return (tens << 4) + ones
+
+    def decodeAlarmType(self,alarmTime):
+        if(len(alarmTime) > 4):
+            m1Bit = (alarmTime[3] & 0x80) >> 7
+        else:
+            m1Bit = False
+        m2Bit = (alarmTime[2] & 0x80) >> 7
+        m3Bit = (alarmTime[1] & 0x80) >> 7
+        m4Bit = (alarmTime[0] & 0x80) >> 7
+        dayBit = (alarmTime[0] & 0x40) >> 6
+        
+        if(m1Bit and m2Bit and m3Bit and m4Bit):
+            return "everySecond"
+        elif(not m1Bit and m2Bit and m3Bit and m4Bit):
+            return "everyMinute"
+        elif(not m1Bit and not m2Bit and m3Bit and m4Bit):
+            return "everyHour"
+        elif(not m1Bit and not m2Bit and not m3Bit and m4Bit):
+            return "everyDay"
+        elif(not dayBit and not m1Bit and not m2Bit and not m3Bit and not m4Bit):
+            return "everyMonth"
+        elif(dayBit and not m1Bit and not m2Bit and not m3Bit and not m4Bit):
+            return "everyWeek"
+        else:
+            return "noValidAlarmType"
+        
+    def decodeAlarmTime(self,alarmTime):
+        alarmTime[0] = decodeToDec(convertToByteType(alarmTime[0] & 0x3F))
+        alarmTime[1] = decodeToDec(convertToByteType(alarmTime[1] & 0x3F))
+        alarmTime[2] = decodeToDec(convertToByteType(alarmTime[2] & 0x7F))
+        if(len(alarmTime) > 4):
+            alarmTime[3] = decodeToDec(convertToByteType(alarmTime[3] & 0x7F))
+        return alarmTime
+
+    def encodeAlarmType(self,alarmType):
+        if(alarmType == "everySecond"):
+            return 15   #0b01111
+        elif(alarmType == "everyMinute"):
+            return 14   #0b01110
+        elif(alarmType == "everyHour"):
+            return 12   #0b01100
+        elif(alarmType == "everyDay"):
+            return 8    #0b01000
+        elif(alarmType == "everyMonth"):
+            return 0    #0b00000
+        elif(alarmType == "everyWeek"):
+            return 16   #0b10000
+        else:
+            raise ValueError("""Not a supported alarmType. Options are: 
+            'everySecond' (only Alarm 1), 'everyMinute', 'everyHour', 'everyDay', 'everyMonth', 'everyWeek'""")
+
+    def encodeDateTime(self,day, hour, minutes, seconds, alarmType):
+        alarmBits = encodeAlarmType(alarmType)
+        alarmTime = [0, 0, 0, 0]
+        alarmTime[0] = (encodeToByte(day) & 0x3F) | ((alarmBits & 0x10) << 2) | ((alarmBits & 0x08) << 4)
+        alarmTime[1] = (encodeToByte(hour) & 0x3F) | ((alarmBits & 0x04) << 5)
+        alarmTime[2] = (encodeToByte(minutes) & 0x7F) | ((alarmBits & 0x02) << 6)
+        alarmTime[3] = (encodeToByte(seconds) & 0x7F) | ((alarmBits & 0x01) << 7)
+        return alarmTime
+
+
+##################################
+#          10、SPI_WS2812        #
+##################################
+class SPI_WS2812(object):
+    from maix import spi
+    spi = spi.SpiDev()
+    
+    def __init__(self,num):
+        self.num=num
+        self.spi.open(0, 0)
+        self.spi.mode = 3
+        self.spi.bits_per_word = 8
+        self.spi.max_speed_hz = 20000000
+        self.data=[[0,0,0]]*self.num
+        self.brightness=255
+    
+    def setRgbColor(self,id,r,g,b):
+        if id>(self.num-1):
+            raise ValueError("Out of range!")
+        else:
+            self.data[id]=[int(g*self.brightness/255),int(r*self.brightness/255),int(b*self.brightness/255)]
+            #print("set complete!")
+    
+    def setBrightness(self,brightness):
+        if brightness>255 or brightness<0:
+            raise ValueError("Out of range!")
+        self.brightness=brightness
+        
+
+    def rgbShow(self):
+        tx=[]
+        for rgb in self.data:
+            for byte in rgb:
+                for ibit in range(3,-1,-1):
+                    tx.append(((byte>>(2*ibit+1))&1)*0x60 +
+                              ((byte>>(2*ibit+0))&1)*0x06 +
+                              0x88)
+        print([hex(v) for v in tx])
+        tx[0]=0b1000000
+        tx.append(0b1000000)
+        self.spi.xfer(tx,int(4/1.05e-6))
+
+    def __del__(self):
+        self.data=[[0,0,0]]*self.num
+        self.rgbShow()
+
+##################################
+#          11、HCSR04            #
+##################################
+
+class HCSR04:
+    
+    def __init__(self,Trig,Echo):
+        pinNum={"TXD":"198","RXD":"199","CLK":"224","MOSI":"225","MISO":"226","CS":"227"}
+        os.system("insmod /home/drivers/hcsr04.ko")
+        pinCmd=pinNum.get(Trig)+","+pinNum.get(Echo)+",23200,0"
+        os.system('echo "'+pinCmd+'" > /sys/class/hcsr04/value')
+        
+    def getDistance(self):
+        startTime=round(time.time(),3)
+        #print("startTime:"+str(startTime))
+        while True:
+            dis=os.popen("cat /sys/class/hcsr04/value").read()
+            #print("dis:"+str(dis)+" len:"+str(len(dis)))
+            if "-1" in dis:
+                pass
+            else:
+                dis=round(int(dis)/58,2)
+                if dis<250:
+                    return dis
+                else:
+                    pass
+            if((round(time.time(),3)-startTime)>=1.200):#超时时间
+                return -1
+    
+    def __del__(self):
+        os.system("rmmod /home/drivers/hcsr04.ko")
+        
+
+import struct
+import math
+import os
+
+##################################
+#          12、MCP23017          #
+##################################
+
+class MCP23017(object):
+
+    bus = smbus2.SMBus(2) # 2 indicates /dev/i2c-2
+    address = 0x20
+    
+    iodira=0x00         #A引脚方向寄存器地址。初始值为0xFF,输入模式
+    iodirb=0x01         #B引脚方向寄存器地址。初始值为0xFF,输入模式
+    gppua=0x0c          #A引脚上拉电阻配置寄存器地址。初始值为0x00,无上拉
+    gppub=0x0d          #B引脚上拉电阻配置寄存器地址,初始值为0x00,无上拉    
+    gpioa=0x12          #A端口寄存器,初始值为0x00,低电平
+    gpiob=0x13          #B端口寄存器,初始值为0x00,低电平
+    DIR_A_V=0xff        #A引脚方向初始值
+    DIR_B_V=0xff        #B引脚方向初始值
+    GPPU_A_V=0x00       #A引脚上拉设定初始值
+    GPPU_B_V=0x00       #B引脚上拉设定初始值
+    GPIO_A_V=0x00       #A引脚电平初始值
+    GPIO_B_V=0x00       #B引脚电平初始值
+
+    def __init__(self):
+        self.reset()
+        
+    def reset(self):
+        self.DIR_A=self.DIR_A_V
+        self.DIR_B=self.DIR_B_V
+        self.GPPU_A=self.GPPU_A_V
+        self.GPPU_B=self.GPPU_B_V
+        self.GPIO_A=self.GPIO_A_V
+        self.GPIO_B=self.GPIO_B_V
+        self.byteWrite(self.iodira,self.DIR_A_V)
+        self.byteWrite(self.iodirb,self.DIR_B_V)
+        self.byteWrite(self.gppua,self.GPPU_A_V)
+        self.byteWrite(self.gppub,self.GPPU_B_V)
+        self.byteWrite(self.gpioa,self.GPIO_A_V)
+        self.byteWrite(self.gpiob,self.GPIO_B_V)
+        print("mcp23017 reset completed!")
+        
+    def byteWrite(self, addr, val):
+        try:
+            self.bus.write_byte_data(self.address, addr, val)
+            return True
+        except Exception:
+            pass
+    
+    def byteRead(self,addr):
+        tmp = self.bus.read_byte_data(self.address, addr)
+        return tmp
+    
+    def bitWrite(self,reg,num,val):    #寄存器值(byte类型),寄存器第...位(0-7),该位的值(0/1)
+        return (reg>>(num+1)<<(num+1))|(val << num)|(reg<<(8-num)&0xFF)>>(8-num)
+        
+    def bitRead(self,reg,num):         #寄存器值(byte类型),寄存器第...位(0-7)
+        return ((reg<<(7-num)&0xFF)>>7)
+    
+    def setGpioDir(self,channel,pinId,direction):    #set gpio direction
+        #channel:"A" or "B"
+        #pinId:0~7
+        #direction:[0:output],[1:input(default)]
+        if channel=="A":
+            self.DIR_A=self.bitWrite(self.DIR_A,pinId,direction)
+            print("Dir_A="+str(self.DIR_A))
+            self.byteWrite(self.iodira,self.DIR_A)
+        elif channel=="B":
+            self.DIR_B=self.bitWrite(self.DIR_B,pinId,direction)
+            self.byteWrite(self.iodirb,self.DIR_B)
+        else:
+            raise ValueError("Error Channel!")
+        
+    def setGppuEnable(self,channel,pinId,pullup):        #set gpio pullup on or off
+        #channel:"A" or "B"
+        #pinId:0~7
+        #pullup:[0:disable],[1:enable(default)]
+        if channel=="A":
+            self.GPPU_A=self.bitWrite(self.GPPU_A,pinId,pullup)
+            self.byteWrite(self.gppua,self.GPPU_A)
+        elif channel=="B":
+            self.GPPU_B=self.bitWrite(self.GPPU_B,pinId,pullup)
+            self.byteWrite(self.gppub,self.GPPU_B)
+        else:
+            raise ValueError("Error Channel!")
+    
+    def setGpioLevel(self,channel,pinId,level):    #set gpio volt level
+        #channel:"A" or "B"
+        #pinId:0~7
+        #level:[0:low(default)],[1:high]
+        if channel=="A":
+            self.GPIO_A=self.bitWrite(self.GPIO_A,pinId,level)
+            self.byteWrite(self.gpioa,self.GPIO_A)
+        elif channel=="B":
+            self.GPIO_B=self.bitWrite(self.GPIO_B,pinId,level)
+            self.byteWrite(self.gpiob,self.GPIO_B)
+        else:
+            raise ValueError("Error Channel!")
+    
+    def getGpioLevel(self,channel,pinId):                #get gpio volt level
+        #channel:"A" or "B"
+        #pinId:0~7
+        #level:[0:low(default)],[1:high]
+        if channel=="A":
+            return self.bitRead(self.byteRead(self.gpioa),pinId)
+        elif channel=="B":
+            return self.bitRead(self.byteRead(self.gpiob),pinId)
+        else:
+            raise ValueError("Error Channel!")
+        
+    def __del__(self):
+        self.reset()
+        time.sleep(0.001)
+        print("del mcp23017")
+        
+        
+class ADS1115(object):
+    
+    bus = smbus2.SMBus(2) # 2 indicates /dev/i2c-2
+    # Registers in the ADS1115,设备的4个寄存器
+    DEVICE_REG_CONVERSION           = 0x00                          #转换寄存器
+    DEVICE_REG_CONFIG               = 0x01                          #配置寄存器
+    DEVICE_REG_LO_THRESH            = 0x02                          #最低阈值寄存器
+    DEVICE_REG_HI_THRESH            = 0x03                          #最高阈值寄存器
+
+    # Configuration register fields                         #配置寄存器展开,共16bit
+
+    # Operational Status                                    #操作状态,在第15位
+    CONFIG_OS                                   = 0X8000                #无效
+    CONFIG_OS_START                             = 0X8000                #开始单次转换(处于掉电状态)
+    CONFIG_OS_PERFORMING_CONVERSION             = 0X0000                #转换进行中
+    CONFIG_OS_NOT_PERFORMING_OPERATION          = 0X8000              #转换闲置
+
+    # Differential measurements                             #测量模式设置,在第12-14位
+    CONFIG_MUX_AIN0P_AIN1N                        = 0X0000 # (default)    #AIN0差分输入,AIN1作为参考
+    CONFIG_MUX_AIN1P_AIN3N                        = 0X1000                #AIN1差分输入,AIN3作为参考
+    CONFIG_MUX_AIN2P_AIN3N                        = 0X2000                #AIN2差分输入,AIN3作为参考
+    CONFIG_MUX_AIN3P_AIN3N                        = 0X3000                #AIN3差分输入,AIN3作为参考
+    # Single ended measurements                             #单端测量
+    CONFIG_MUX_AIN0P_GNDN                        = 0X4000                #AIN0单端输入
+    CONFIG_MUX_AIN1P_GNDN                        = 0X5000                #AIN1单端输入
+    CONFIG_MUX_AIN2P_GNDN                        = 0X6000                #AIN2单端输入
+    CONFIG_MUX_AIN3P_GNDN                        = 0X7000                #AIN3单端输入
+
+    # Programmable gain amplifier configuration             #可编程增益放大器(量程选择)FSR:Feedback Shift Register,反馈移位寄存器,在第9-11位
+    CONFIG_FSR_6V144                                 = 0X0000                #CocoPi 需选择
+    CONFIG_FSR_4V096                                 = 0X0200
+    CONFIG_FSR_2V048                                 = 0X0400 # (default)
+    CONFIG_FSR_1V024                                 = 0X0600
+    CONFIG_FSR_0V512                                 = 0X0800
+    CONFIG_FSR_0V256                                 = 0X0A00
+    CONFIG_FSR_0V256                                 = 0X0C00
+    CONFIG_FSR_0V256                                 = 0X0E00
+
+    # Continuous or single shot mode                        #设备运行模式:持续转换或者单次转换,在第8位
+    CONFIG_MODE_CONTINUOUS                          = 0X0000                #持续转换
+    CONFIG_MODE_SINGLE_SHOT                         = 0X0100 # (default)    #单次转换
+
+    # Data rate                                             #转换速率,第5-7位
+    CONFIG_DATA_RATE_8SPS                           = 0X0000                #SPS:Samples Per Second,每秒8次采样
+    CONFIG_DATA_RATE_16SPS                          = 0X0020
+    CONFIG_DATA_RATE_32SPS                          = 0X0040
+    CONFIG_DATA_RATE_64SPS                          = 0X0060
+    CONFIG_DATA_RATE_128SPS                         = 0X0080 #(default)
+    CONFIG_DATA_RATE_2508SPS                        = 0X00A0
+    CONFIG_DATA_RATE_475SPS                         = 0X00C0
+    CONFIG_DATA_RATE_860SPS                         = 0X00E0
+
+    # Comparitor mode                                       #比较器模式,第4位
+    CONFIG_COMP_MODE_TRADITIONAL                    = 0X0000 #(default)     #传统比较器
+    CONFIG_COMP_MODE_WINDOW                         = 0X0010                #窗口模式
+
+    # Comparitor polarity                                   #比较器集型,第3位,控制ALRET/RDY引脚极性
+    CONFIG_COMP_POL_ACTIVE_LOW                      = 0X0000 #(default)     #低电平有效(默认)
+    CONFIG_COMP_POL_ACTIVE_HIGH                     = 0X0008                #高电平有效
+
+    # Comparitor latching                                   #锁存比较器,第2位,该位控制ALERT/RDY引脚在被置为有效后锁存,还是在转换后处于上限和下限阈值范围内清零
+    CONFIG_COMP_LAT                                 = 0X0004
+    CONFIG_COMP_LAT_NON_LATCHING                    = 0X0000 #(default)     #默认不锁存
+    CONFIG_COMP_LAT_LATCHING                        = 0X0004
+
+    # comparitor queue and disable                          #比较器置位和禁用
+    CONFIG_COMP_QUE                                 = 0X0003                #默认禁用比较器并将ALERT/RDY引脚设置为高阻抗
+    CONFIG_COMP_QUE_1_CONV                          = 0X0000                #一次转换后断言
+    CONFIG_COMP_QUE_2_CONV                          = 0X0001                #两次转换后置位
+    CONFIG_COMP_QUE_4_CONV                          = 0X0002                #四次转换后置位
+    CONFIG_COMP_QUE_DISABLE                         = 0X0003 #(default)     #默认禁用比较器并将ALERT/RDY引脚设置为高阻抗
+    
+    # Address for the device ,设备地址选择
+    #addr=0x48       # ADDR tied to GND
+    addr=0x49        # ADDR tied to VDD
+    #addr=0x4A       # ADDR tied to SDA
+    #addr=0x4B       # ADDR tied to SCL
+    
+
+    def __init__(self):
+        self.address=0x49
+        self.config=0x0000
+        #time.sleep(0.05)
+        pass
+    
+    def swap(self,val):
+        return (((val&0xff00)>>8)|((val&0x00ff)<<8))                    #交换高8位与低8位
+    ###
+    def readAdc(self,channel):
+        if (channel>3) or (channel<0):
+            return False
+        self.config=(self.CONFIG_OS_START +                                # start conversion 
+            #self.CONFIG_MUX_AIN0P_GNDN  +                         # single ended conversion
+            ((channel+4)<<12) +                                         # select channel
+            self.CONFIG_FSR_6V144 +                                         # (5v signal)
+            self.CONFIG_MODE_SINGLE_SHOT +                         # single conversion and shutdown
+            self.CONFIG_DATA_RATE_128SPS +                         # data rate
+            self.CONFIG_COMP_MODE_TRADITIONAL +                 # comp conventional 
+            self.CONFIG_COMP_POL_ACTIVE_LOW  +                 # comp active low
+            self.CONFIG_COMP_LAT_NON_LATCHING +                 # comp non latching
+            self.CONFIG_COMP_QUE_DISABLE )                        # comp disabled
+        ###
+        self.bus.write_word_data(self.address, self.DEVICE_REG_CONFIG, self.swap(self.config))
+        while True:
+            # read status (note byte swap)
+            status=self.swap(self.bus.read_word_data(self.address,self.DEVICE_REG_CONFIG))
+            #print("status:"+str(status))
+            # when the Operational Status is no longer performing a conversion
+            # we can break out of this wait loop 
+            if (status & self.CONFIG_OS) != self.CONFIG_OS_PERFORMING_CONVERSION:
+                break
+        # read result (note byte swap)
+        result=self.swap(self.bus.read_word_data(self.address,self.DEVICE_REG_CONVERSION))
+        # return 16 bit integer A2D result for the specified channel
+        volt=round((result*6.144/32768),3)
+        return [result,volt]
+
+class PCA9685(object):
+    bus=smbus2.SMBus(2)
+    def __init__(self,freq=400,min_us=460,max_us=2400,address=0x40,degrees=180):
+        self.address=address
+        self.period=1000000/freq
+        self.min_duty = self._us2duty(min_us)
+        self.max_duty = self._us2duty(max_us)
+        self.freq(freq)
+        self.reset()
+        #for i in range(0,16):
+            #self.duty(i,0)
+        print("Pca9685 init")
+        
+    def write(self, addr, val):
+        for i in range(0, 2):
+            try:
+                self.bus.write_byte_data(self.address, addr, val)
+                #time.sleep(0.001) # 1ms
+                # print(addr, val) # debug
+                return True
+            except Exception:
+                time.sleep(0.001)
+                continue
+        return False
+        
+    def read(self,addr):
+        for i in range(0, 3):
+            try:
+                tmp = self.bus.read_byte_data(self.address, addr)
+                #time.sleep(0.001) # 1ms
+                # print(addr, tmp) # debug
+                return tmp
+            except Exception:
+                time.sleep(0.01)
+                continue
+        return None
+    
+    def reset(self):
+        self.write(0x00,0x00)        #初始化
+    
+    def freq(self,freq=None):
+        if freq is None:
+            return int(25000000.0/4096/(self.read(0xfe)-0.5))
+        #设定频率freq,预分频prescale=int(25000000.0 / (4096.0 * freq) + 0.5)
+        prescale=int(25000000.0/4096/freq+0.5)
+        self.write(0x00,0x10)        #设定pca9685为睡眠模式
+        self.write(0xfe,prescale)    #设定频率
+        self.reset()
+        time.sleep(0.01)
+        self.write(0x00,0xa1)        #设定pca9685为活跃模式
+    
+    def pwm(self,index,on=None,off=None):            #on和off来调节PWM的占空比
+        if not 0<= index <=15:
+            raise ValueError("Pin ID out of range!")
+        if on is None or off is None:
+            data = self.bus.read_i2c_block_data(self.address,0x06+index*4,4)
+            return data
+        data= [0]*4
+        data[0]=int(hex(on & 0xff),16)
+        data[1]=int(hex((on >> 8) & 0xff),16)
+        data[2]=int(hex(off & 0xff),16)
+        data[3]=int(hex((off >> 8) & 0xff),16)
+        print(data)
+        for i in range(0,4):
+            self.write(0x06+i+index*4,data[i])
+        
+    def duty(self,index,value=None):
+        if value == None:
+            return self.pwm(index)
+        elif not 0 <= value <=4095:
+            raise ValueError("Out of range!")
+        elif value==0:
+            self.pwm(index,0,4096)
+        elif value == 4095:
+            self.pwm(index,4096,0)
+        else:
+            self.pwm(index,0,value)  
+
+    def _us2duty(self,value):
+        return 4095*value/self.period
+        
+    def __del__():
+        print("del pac9685")
+        time.sleep(1)
+        for i in range(0,16):
+            self.duty(i,0)
+        time.sleep(0.001)
+        
+
+class extDcMotor(PCA9685):
+    def __init__(self,motorId):
+        #PCA9685.__init__(self)
+        self.motorPin=[11,12,13,10,9,8,5,6,7,4,3,2]
+        self.motorId=motorId
+        pass
+        
+    def speedControl(self,speed):
+        self.speed=abs(speed)
+        if not -255<= speed<=255:
+            raise ValueError("Out of range!")
+        if self.motorId == "C":
+            if speed<0:
+                self.duty(self.motorPin[0],4095)
+                self.duty(self.motorPin[1],0)
+                self.duty(self.motorPin[2],int(self.speed*16))
+            else:
+                self.duty(self.motorPin[0],0)
+                self.duty(self.motorPin[1],4095)
+                self.duty(self.motorPin[2],int(self.speed*16))
+        elif self.motorId == "D":
+            if speed<0:
+                self.duty(self.motorPin[3],4095)
+                self.duty(self.motorPin[4],0)
+                self.duty(self.motorPin[5],int(self.speed*16))
+            else:
+                self.duty(self.motorPin[3],0)
+                self.duty(self.motorPin[4],4095)
+                self.duty(self.motorPin[5],int(self.speed*16))
+        elif self.motorId == "E":
+            if speed<0:
+                self.duty(self.motorPin[6],4095)
+                self.duty(self.motorPin[7],0)
+                self.duty(self.motorPin[8],int(self.speed*16))
+            else:
+                self.duty(self.motorPin[6],0)
+                self.duty(self.motorPin[7],4095)
+                self.duty(self.motorPin[8],int(self.speed*16))
+        elif self.motorId == "F":
+            if speed<0:
+                self.duty(self.motorPin[9],4095)
+                self.duty(self.motorPin[10],0)
+                self.duty(self.motorPin[11],int(self.speed*16))
+            else:
+                self.duty(self.motorPin[9],0)
+                self.duty(self.motorPin[10],4095)
+                self.duty(self.motorPin[11],int(self.speed*16))
+        else:
+            pass
+       
+    
+    def __del__(self):
+        if self.motorId == "C":
+            self.duty(self.motorPin[0],0)
+            self.duty(self.motorPin[1],0)
+            self.duty(self.motorPin[2],0)
+        elif self.motorId == "D":
+            self.duty(self.motorPin[3],0)
+            self.duty(self.motorPin[4],0)
+            self.duty(self.motorPin[5],0)
+        elif self.motorId == "E":
+            self.duty(self.motorPin[6],0)
+            self.duty(self.motorPin[7],0)
+            self.duty(self.motorPin[8],0)
+        elif self.motorId == "F":
+            self.duty(self.motorPin[9],0)
+            self.duty(self.motorPin[10],0)
+            self.duty(self.motorPin[11],0)
+        else:
+            pass
+        time.sleep(0.001)
+        
+class extServo(PCA9685):
+    def __init__(self,servoId):
+        #PCA9685.__init__(self)
+        self.servoId=servoId
+        self.servoPin=[14,15,1,0]
+        self.degrees=180
+        pass      
+        
+    def position(self,degrees=None):        #index:0,1,2,3
+        span = self.max_duty - self.min_duty
+        duty = self.min_duty + span * degrees / self.degrees
+        duty = int(min(self.max_duty, max(self.min_duty, int(duty))))
+        self.duty(self.servoPin[self.servoId], duty)
+        
+    def release(self):
+        self.duty(self.servoPin[self.servoId],0)
+    
+    def __del__(self):  
+        self.duty(self.servoPin[self.servoId],0)
+    
+        
+class extOutputPin(PCA9685):
+    def __init__(self):
+        #PCA9685.__init__(self)
+        self.pin=[14,15,1,0]
+        self.pinId=0
+        pass
+    
+    def digitalSet(self,pinId,val):    #val:0/1
+        self.pinId=pinId
+        if val==0:
+            self.duty(self.pin[self.pinId],0)
+        else:
+            self.duty(self.pin[self.pinId],4095)
+    
+    def pwmWrite(self,pinId,val):    #val:0~255
+        self.pinId=pinId
+        print("pinid"+str(self.pin[self.pinId]))
+        self.duty(self.pin[self.pinId],val*16)
+    
+    def __del__(self):
+        self.duty(self.pin[self.pinId],0)
+        print("del extPin")
+        
+class extGpio(MCP23017,ADS1115,extOutputPin):
+    def __init__(self):
+        MCP23017.__init__(self) 
+        ADS1115.__init__(self)
+        extOutputPin.__init__(self)
+        self.address=0x20    #初始默认为mcp23017的地址
+   
+    def pinMode(self,pinId,mode):    #控制mcp23017
+        self.address=0x20
+        #----------
+        #pinId:
+        #p0~p3:0~3
+        #a0~a3:4~7
+        #---------
+        #mode:
+        #output:1
+        #input:0
+        if pinId>=0 and pinId<=3:
+            if mode==0:
+                if pinId==0:            #p0
+                    self.setGpioDir("B",2,0)    #output
+                    self.setGpioLevel("B",2,1)    #high
+                    self.setGpioDir("B",3,1)    #input
+                elif pinId==1:            #p1
+                    self.setGpioDir("B",1,0)
+                    self.setGpioLevel("B",1,1)
+                    self.setGpioDir("B",0,1)
+                elif pinId==2:            #p2
+                    self.setGpioDir("B",6,0)
+                    self.setGpioLevel("B",6,1)
+                    self.setGpioDir("A",1,1)
+                elif pinId==3:            #p3
+                    self.setGpioDir("B",5,0)
+                    self.setGpioLevel("B",5,1)
+                    self.setGpioDir("B",4,1)
+                else:
+                    pass
+            elif mode==1:
+                if pinId==0:
+                    self.setGpioDir("B",2,0)    #output
+                    self.setGpioLevel("B",2,1)    #high
+                    self.setGpioDir("B",3,0)    #output
+                elif pinId==1:
+                    self.setGpioDir("B",1,0)
+                    self.setGpioLevel("B",1,1)
+                    self.setGpioDir("B",0,0)
+                elif pinId==2:
+                    self.setGpioDir("B",6,0)
+                    self.setGpioLevel("B",6,1)
+                    self.setGpioDir("A",1,0)
+                elif pinId==3:
+                    self.setGpioDir("B",5,0)
+                    self.setGpioLevel("B",5,1)
+                    self.setGpioDir("B",4,0)
+                    print("a")
+                    time.sleep(1)
+                else:
+                    pass
+            else:
+                pass
+        elif pinId>=4 and pinId<=7:
+            if mode==0:
+                if pinId==4:                #a0
+                    self.setGpioDir("A",4,0)    #output
+                    self.setGpioLevel("A",4,1)    #high
+                    self.setGpioDir("A",5,1)    #input
+                elif pinId==5:            #a1
+                    self.setGpioDir("A",3,0)
+                    self.setGpioLevel("A",3,1)
+                    self.setGpioDir("A",7,1)
+                elif pinId==6:            #a2
+                    self.setGpioDir("A",2,0)
+                    self.setGpioLevel("A",2,1)
+                    self.setGpioDir("A",6,1)
+                elif pinId==7:            #a3
+                    self.setGpioDir("B",7,0)
+                    self.setGpioLevel("B",7,1)
+                    self.setGpioDir("A",0,1)
+                else:
+                    pass
+            elif mode==1:
+                if pinId==4:                #a0
+                    self.setGpioDir("A",4,0)    #output
+                    self.setGpioLevel("A",4,1)    #high
+                    self.setGpioDir("A",5,0)    #output
+                elif pinId==5:            #a1
+                    self.setGpioDir("A",3,0)
+                    self.setGpioLevel("A",3,1)
+                    self.setGpioDir("A",7,0)
+                elif pinId==6:            #a2
+                    self.setGpioDir("A",2,0)
+                    self.setGpioLevel("A",2,1)
+                    self.setGpioDir("A",6,0)
+                elif pinId==7:            #a3
+                    self.setGpioDir("B",7,0)
+                    self.setGpioLevel("B",7,1)
+                    self.setGpioDir("A",0,0)
+                else:
+                    pass
+            else:
+                pass
+
+    def digitalWrite(self,pinId,level):    #控制mcp23017
+        #----------
+        #pinId:
+        #p0~p3:0~3
+        #a0~a3:4~7
+        #---------
+        #level:
+        #5v:1
+        #0v:0
+        self.address=0x20
+        if pinId>=0 and pinId<=3:
+            if pinId==0:
+                print("digital write level")
+                self.setGpioLevel("B",3,level)
+            elif pinId==1:
+                self.setGpioLevel("B",0,level)
+            elif pinId==2:
+                self.setGpioLevel("A",1,level)
+            elif pinId==3:
+                self.setGpioLevel("B",4,level)
+            else:
+                pass
+        elif pinId>=4 and pinId<=7:
+            if pinId==4:                #a0
+                self.setGpioLevel("A",5,level)
+            elif pinId==5:            #a1
+                self.setGpioLevel("A",7,level)
+            elif pinId==6:            #a2
+                self.setGpioLevel("A",6,level)
+            elif pinId==7:            #a3
+                self.setGpioLevel("A",0,level)
+            else:
+                pass
+        else:
+            pass
+    
+    def digitalRead(self,pinId):    #控制mcp23017
+        self.address=0x20
+        #----------
+        #pinId:
+        #p0~p3:0~3
+        #a0~a3:4~7
+        if pinId>=0 and pinId<=3:
+            if pinId==0:
+                print("get digital write level")
+                return self.getGpioLevel("B",3)
+            elif pinId==1:
+                return self.getGpioLevel("B",0)
+            elif pinId==2:
+                return self.getGpioLevel("A",1)
+            elif pinId==3:
+                return self.getGpioLevel("B",4)
+            else:
+                pass
+        elif pinId>=4 and pinId<=7:
+            if pinId==4:                #a0
+                return self.getGpioLevel("A",5)
+            elif pinId==5:            #a1
+                return self.getGpioLevel("A",7)
+            elif pinId==6:            #a2
+                return self.getGpioLevel("A",6)
+            elif pinId==7:            #a3
+                return self.getGpioLevel("A",0)
+            else:
+                pass
+        else:
+            pass
+            
+    def analogWrite(self,pinId,pwm):      #控制PCA9685,但是需要Mcp23017进行通道选择
+        self.address=0x20                 #先用mcp23017进行通道选择
+        #select X channel
+        if pinId==0:            #p0
+            self.setGpioDir("B",2,1)    #output
+            self.setGpioLevel("B",2,0)    #low
+        elif pinId==1:            #p1
+            self.setGpioDir("B",1,1)
+            self.setGpioLevel("B",1,0)
+        elif pinId==2:            #p2
+            self.setGpioDir("B",6,1)
+            self.setGpioLevel("B",6,0)
+        elif pinId==3:            #p3
+            self.setGpioDir("B",5,1)
+            self.setGpioLevel("B",5,0)
+        else:
+            pass
+        self.address=0x40                #再用PCA9685进行控制
+        self.pwmWrite(pinId,pwm)
+        
+    def analogRead(self,pinId):          #控制ADS1115,但是需要Mcp23017进行通道选择
+        self.adcPin=[3,1,0,2]
+        self.address=0x20                #先用mcp23017进行通道选择
+        #select X channel
+        if pinId==4:            #a0
+            self.setGpioDir("A",4,1)    #input
+            self.setGpioLevel("A",4,0)    #low
+        elif pinId==5:            #a1
+            self.setGpioDir("A",3,1)
+            self.setGpioLevel("A",3,0)
+        elif pinId==6:            #a2
+            self.setGpioDir("A",2,1)
+            self.setGpioLevel("A",2,0)
+        elif pinId==7:            #a3
+            self.setGpioDir("B",7,0)
+            self.setGpioLevel("B",7,0)
+        else:
+            pass        
+        self.address=0x49              #再用Ads1115进行ADC读取
+        return self.readAdc(self.adcPin[pinId-4])
+    def __del__(self):
+        self.address=0x40
+        extOutputPin.__del__(self)
+        self.address=0x20
+        MCP23017.__del__(self)        #最先init的配置最后再del
+        print("del finished!")

+ 1 - 0
CocoPi_intro_manual.html

@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=https://pi-help.cocorobo.cn/#/">

+ 1 - 0
CocoPi_online_programming.html

@@ -0,0 +1 @@
+<meta http-equiv="refresh" content="0; url=https://pi.cocorobo.hk">

+ 569 - 0
main.py

@@ -0,0 +1,569 @@
+#!/usr/bin/env python
+#version    :       2024.08.08
+#language   :       zh
+#hardware   :       pi
+import time
+from maix import *
+import gc
+import os,sys
+import sys
+sys.path.append('/root/')
+from CocoPi import BUTTON
+from CocoPi import stm8s
+from CocoPi import multiFuncGpio
+from CocoPi import singleRgb
+from CocoPi import LED
+
+gc.enable()
+gc.collect()
+iic_slaver=stm8s()
+iic_slaver.clear()
+PIXEL_LED1= multiFuncGpio(0,7)
+time.sleep(0.1)
+PIXEL_LED2= multiFuncGpio(1,7)
+PIXEL_LED1.pixelInit_()
+PIXEL_LED2.pixelInit_()
+time.sleep(0.1)
+L1=singleRgb()
+L1.setColor(0,0,0)
+L1.show()
+time.sleep(0.1)
+L2=LED()
+L2.out(0)
+del iic_slaver
+del PIXEL_LED1
+del PIXEL_LED2
+del L1
+del L2
+
+count = 0
+
+def gc_log():
+    global count
+    gc.collect()
+    count = count + 1
+
+splash_theme_color = (15,21,46)
+btn_selected = (255,255,255)
+btn_unselected = (76,86,127)
+txt_selected = (255,255,255)
+txt_unselected = (76,86,127)
+color_splash_theme = (15,21,46)
+color_blue = (31,61,185)
+color_blue_lighter = (60,131,211)
+color_white = (255,255,255)
+color_gray = (60,73,126)
+color_orange = (255,165,0)
+color_red = (255,0,0)
+
+
+btn_width = 134
+btn_height = 52
+btn_y_base = 5
+btn_col = (btn_y_base, btn_y_base+btn_width, btn_y_base+152)
+btn_row = 180
+
+main_title = (
+        "运行",
+        "上次程序",
+        "打开",
+        "样例菜单",
+        "B",
+        "A"
+    )
+splash_text = (
+        "系统版本: 2024-08-08 ",
+        "System version: N/A",
+        "2. 加载程序后,按下A键两秒退出程序界面.",
+        "    ",
+        "    ",
+        "启动上次程序中...",
+        "错误: 未找到程序...",
+        "错误: 语法有误",
+        "正在打开样例菜单...",
+        "未找到样例菜单.",
+        "运行",
+        "加载...",
+        "返回",
+        "按下C键返回主界面",
+        "按下D键重启",
+        "按下B键关机",
+        "1. 按下A键七秒来关闭或者重启CocoPi系统.",
+        "    ",
+        "    ",
+        "CocoPi V6",
+        "/ Linux / AIot /Python /",
+        "/Graphical programming /",
+        "------------- 基础 --------------",
+        "----------- 人工智能 ----------",
+        "------------ 物联网 ------------",
+    )
+
+title_logo_text = image.open("/root/preset/img/cocorobo_text.jpg")
+iconUpNp = image.open("/root/preset/img/arrow_up_filled.jpg")
+iconUpP = image.open("/root/preset/img/arrow_up_pressed.jpg")
+iconDownNp = image.open("/root/preset/img/arrow_down_filled.jpg")
+iconDownP = image.open("/root/preset/img/arrow_down_pressed.jpg")
+frostedGlass = image.open("/root/preset/img/frostedglass_.jpg")
+#backUp = image.open("/root/preset/img/backup_48x48.png")
+#powerOff = image.open("/root/preset/img/poweroff_48x48.png")
+#reBoot = image.open("/root/preset/img/reboot_48x48.png")
+
+run_user_code_path='/root/user_latest_code.py'
+run_try_demo_path='/root/play_music.py'
+
+
+key_A = BUTTON(14)
+key_B = BUTTON(8)
+key_C = BUTTON(13)
+key_D = BUTTON(7)
+
+splash = image.new(size=(320, 240),mode = "RGB")
+img_drop=image.new(size=(320,240),mode="RGB")
+
+demo_i=0
+demo_j=0
+demo_m=0
+demo_n=0
+pressTime=0
+systemRunNum=0
+
+image.load_freetype("/root/preset/fonts/simhei.ttf")
+def screenFirstPage():
+    from maix import display,image,camera
+    global splash,title_logo_text,btn_col,btn_row,splash_text,txt_unselected,txt_selected,btn_selected,btn_unselected,\
+splash_theme_color,btn_height,btn_width,main_title,menuSelect,gc_log,demo_i,demo_j,demo_m,demo_n,screenShow,img_drop,\
+frostedGlass
+    gc_log()
+    image.load_freetype("/root/preset/fonts/simhei.ttf")
+    splash.clear()
+    splash.draw_rectangle(0,0,320,320,color=splash_theme_color,thickness=-1)
+    splash.draw_image(title_logo_text, btn_col[0]+16, 10)
+    x, y = image.get_string_size(splash_text[0], 1)
+
+    splash.draw_string(btn_col[0]+16, 40, splash_text[19]+"  "+splash_text[0], color=(0,255,255), thickness = 1)
+#    splash.draw_string(btn_col[0], 60, splash_text[20], color=(0,255,255), thickness = 1)
+#    splash.draw_string(btn_col[0], 80, splash_text[21], color=(0,255,255), thickness = 1)
+#    splash.draw_string(btn_col[0], 60, splash_text[0], color=(0,255,255), thickness = 1)
+    splash.draw_string(btn_col[0]+16, btn_row-105, splash_text[16], color=txt_unselected, thickness = 1)
+    splash.draw_string(btn_col[0]+16, btn_row-85, splash_text[17], color=txt_unselected, thickness = 1)
+    #splash.draw_string(btn_col[0], btn_row-105, splash_text[18], color=txt_unselected, thickness = 1)
+    splash.draw_string(btn_col[0]+16, btn_row-65, splash_text[2], color=txt_unselected, thickness = 1)
+    splash.draw_string(btn_col[0]+16, btn_row-45, splash_text[3], color=txt_unselected, thickness = 1)
+    splash.draw_string(btn_col[0]+16, btn_row-25, splash_text[4], color=txt_unselected, thickness = 1)
+
+    if menuSelect==0:
+        splash.draw_rectangle(btn_col[1]+40, btn_row, btn_col[1]+btn_width+42, btn_row+btn_height, color=btn_selected, thickness=1)
+        splash.draw_string(btn_col[1]+52, btn_row+7, main_title[2], color=txt_selected, thickness = 1)
+        splash.draw_string(btn_col[1]+52, btn_row+27, main_title[3], color=txt_selected, thickness = 1)
+        splash.draw_string(btn_col[1]+157, btn_row+27, main_title[5], color=txt_unselected, thickness = 1)
+
+        splash.draw_rectangle(btn_col[0], btn_row, btn_col[0]+btn_width, btn_row+btn_height, color=btn_selected, thickness=1)
+        splash.draw_string(btn_col[0]+96, btn_row+7, main_title[0], color=txt_selected, thickness = 1)
+        splash.draw_string(btn_col[0]+68, btn_row+27, main_title[1], color=txt_selected, thickness = 1)
+        splash.draw_string(btn_col[0]+7, btn_row+27, main_title[4], color=txt_unselected, thickness = 1)
+
+    if menuSelect==1:
+        splash.draw_rectangle(btn_col[0], btn_row, btn_col[0]+btn_width, btn_row+btn_height, color=btn_unselected, thickness=1)
+        splash.draw_string(btn_col[0]+7, btn_row+7, main_title[0], color=txt_unselected, thickness = 1)
+        splash.draw_string(btn_col[0]+7, btn_row+27, main_title[1], color=txt_unselected, thickness = 1)
+
+        splash.draw_rectangle(btn_col[1], btn_row, btn_col[1]+btn_width, btn_row+btn_height, color=btn_selected, thickness=1)
+        splash.draw_string(btn_col[1]+7, btn_row+7, main_title[2], color=txt_selected, thickness = 1)
+        splash.draw_string(btn_col[1]+7, btn_row+27, main_title[3], color=txt_selected, thickness = 1)
+
+    splash.draw_image(frostedGlass, 0, 0,alpha=0.2)
+    #screenShow()
+    display.show(splash)
+
+def screenSecondPage():
+    from maix import display, image,camera
+    global splash,title_logo_text,btn_col,btn_row,splash_text,txt_unselected,txt_selected,btn_selected,btn_unselected,\
+splash_theme_color,btn_height,btn_width,main_title,demoSelect,gc_log,color_splash_theme,color_blue,color_blue_lighter,\
+color_white,color_gray,color_orange,color_red,iconUpNp,iconUpP,iconDownNp,iconDownP,demoListText,screenShow,img_drop,\
+frostedGlass
+    gc_log()
+    image.load_freetype("/root/preset/fonts/simhei.ttf")
+    splash.clear()
+    splash.draw_rectangle(0,0,320,240,color=splash_theme_color,thickness=-1)
+    splash.draw_rectangle(0,0,320,32,color=color_blue,thickness=-1)
+    splash.draw_image(iconUpNp, 3, 3)
+    splash.draw_image(iconDownNp, 287, 3)
+
+    splash.draw_rectangle(0,214,50,240,color=color_blue,thickness=-1)
+    splash.draw_rectangle(270,214,320,240,color=color_blue,thickness=-1)
+    splash.draw_string(12, 218, splash_text[10], color=(255,255,255), thickness = 1)
+    splash.draw_string(282, 218, splash_text[12], color=(255,255,255), thickness = 1)
+
+    demo_i=int(demoSelect/6)
+    demo_j=demoSelect%6
+    demo_m=int(demoNum/6)
+    demo_n=demoNum%6
+    for j in range(6):
+        if demo_i==demo_m:
+            if j>=demo_n:
+                pass
+            else:
+                if j==demo_j:
+                    pass
+                else:
+                    splash.draw_rectangle(0,33+30*j,319,33+30*(j+1),color=color_gray,thickness=1)
+                    splash.draw_string(8, 39+30*j,demoListText[j+demo_i*6] , color=color_gray, thickness = 1)
+        else:
+            if j==demo_j:
+                pass
+            else:
+                splash.draw_rectangle(0,33+30*j,319,33+30*(j+1),color=color_gray,thickness=1)
+                splash.draw_string(8, 39+30*j,demoListText[j+demo_i*6] , color=color_gray, thickness = 1)
+    if demoSelect<13:
+        splash.draw_string(72, 10, splash_text[22], color=(255,255,255), thickness = 1)
+    elif demoSelect<23:
+        splash.draw_string(72, 10, splash_text[23], color=(255,255,255), thickness = 1)
+    else:
+        splash.draw_string(72, 10, splash_text[24], color=(255,255,255), thickness = 1)
+    splash.draw_rectangle(0,33+30*demo_j,319,33+30*(demo_j+1),color=color_white,thickness=1)
+    splash.draw_string(8, 39+30*demo_j,demoListText[demoSelect] , color=color_white, thickness = 1)
+    splash.draw_string(146, 218, str(demoSelect+1), color=(255,255,255), thickness = 1)
+    splash.draw_string(160, 218, "/"+str(demoNum), color=(255,255,255), thickness = 1)
+    splash.draw_image(frostedGlass, 0, 0,alpha=0.2)
+    #screenShow()
+    display.show(splash)
+
+def systemPage():
+    from maix import display, image,camera
+    import time
+    global splash,title_logo_text,btn_col,btn_row,splash_text,txt_unselected,txt_selected,btn_selected,btn_unselected,\
+splash_theme_color,btn_height,btn_width,main_title,demoSelect,gc_log,color_splash_theme,color_blue,color_blue_lighter,\
+color_white,color_gray,color_orange,color_red,iconUpNp,iconUpP,iconDownNp,iconDownP,demoListText,screenShow,img_drop,\
+frostedGlass
+    image.load_freetype("/root/preset/fonts/simhei.ttf")
+    for i in range(10):
+        splash.draw_image(frostedGlass, 0, 0,alpha=0.2)
+        #screenShow()
+        display.show(splash)
+    splash.draw_string(80, 68, splash_text[13], 1,color=(0,255,0), thickness = 1)
+    splash.draw_string(80, 118, splash_text[14], 1,color=(255,255,0), thickness = 1)
+    splash.draw_string(80, 168, splash_text[15], 1,color=(255,0,0), thickness = 1)
+    #splash.draw_image(backUp, 20, 140)
+    #screenShow()
+    splash.draw_image((image.open("/root/preset/img/backup_00ff00_32x32.png")).rotate(0, adjust=0),40,60,alpha=1)
+    splash.draw_image((image.open("/root/preset/img/reboot_ffff00_32x32.png")).rotate(0, adjust=0),40,110,alpha=1)
+    splash.draw_image((image.open("/root/preset/img/poweroff_ff0000_32x32.png")).rotate(0, adjust=0),40,160,alpha=1)
+
+    display.show(splash)
+
+pageVal=0
+menuSelect=0
+demoSelect=0
+execVal=0
+demoListText=(
+    "相机",
+    "相册",
+    "颜色分析",
+    "录音机",
+    "音频播放器",
+    "播放演示音乐",
+    "播放演示视频",
+    "秒表计时器",
+    "系统时钟显示",
+    "舵机操控",
+    "电机操控",
+    "图片轮播",
+    "二维码扫描",
+    "人形识别",
+    "人脸检测",
+    "人脸比对",
+    "物体识别",
+    "边缘检测",
+    "手写数字识别",
+    "车牌识别",
+    "口罩识别",
+    "手势识别",
+    "猜拳识别",
+    "扫码连接WIFI",
+    "关于CocoPi",
+    "无线相机",
+    "网络天气",
+    "网络时钟",
+    "环境监测",
+    "模型训练:数据集采集",
+    "模型训练:模型部署",
+    "手写数字识别本地训练",
+    "手写数字识别即时训练模型测试",
+    "可可派-GPT",
+    "可可派-终端",
+    "图片分析",
+    "语音输入生成图片",
+    "跳跳机器人",
+    "贪吃蛇",
+    "声音响度分析",
+    "声音频谱分析",
+    "切换语言",
+    "检查更新",
+    "撤销更新",
+
+)
+demoNameList=(
+    "01_camera",
+    "02_photoViewer",
+    "03_colorDetection",
+    "04_recorder",
+    "05_audioPlayer",
+    "06_musicPlayer",
+    "07_videoPlayer",
+    "08_timeCounter",
+    "09_localTimeClock",
+    "10_servoControl",
+    "11_motorControl",
+    "12_pictureLoopPlay",
+    "13_qrCodeScanner",
+    "14_humanDetection",
+    "15_faceDetection",
+    "16_faceComparison",
+    "17_objectRecognition",
+    "18_edgeDetection",
+    "19_handWrittenDigiRecognition",
+    "20_carLicensePlateRecognition",
+    "21_maskDetection",
+    "22_gestureRecognition",
+    "23_fingerGuessing",
+    "24_connectWiFi",
+    "25_aboutCocoPi",
+    "26_internetCamera",
+    "27_internetWeatherPrediction",
+    "28_internetTimeClock",
+    "29_environmentDetection",
+    "30_training_data_collect",
+    "31_training_deploy_model",
+    "32_mnistModelTraining",
+    "33_mnistCameraTest",
+    "34_CocoGPT",
+    "35_CocoTerminal",
+    "36_pictureAnalysis",
+    "37_speechToImageSynthesis",
+    "38_jumpbot",
+    "39_gluttonousSnake",
+    "40_soundLoudnessAnalysis",
+    "41_soundSpectrumAnalysis",
+    "checkout",
+    "pull",
+    "reset",
+
+)
+demoNum=len(demoListText)
+pageSig=1
+selectSig=1
+def buttonDectect():
+    from maix import display, image,camera
+    import time
+    import os
+    global key_A,key_B,key_C,key_D,pageVal,menuSelect,execVal,demoNum,demoSelect,splash,iconUpP,iconDownP,screenShow,img_drop,systemRunNum,pageSig,selectSig
+
+    if(pageVal==0):
+        if(key_A.is_pressed()):
+            pressTime=time.perf_counter()
+            while key_A.is_pressed()==1:
+                if(time.perf_counter()-pressTime)<5:
+                    time.sleep(0.001)
+                    pageVal=1
+                else:
+                    pageVal=2
+                    break
+            execVal=0
+        elif(key_B.is_pressed()):
+            while key_B.is_pressed()==1:
+                time.sleep(0.001)
+            execVal=1
+#         elif (key_B.is_pressed()):
+#             while key_B.is_pressed()==1:
+#                 time.sleep(0.001)
+#             pageVal=1
+        else:
+            pass
+    elif(pageVal==1):
+        if execVal==0:
+            if(key_D.is_pressed()):
+                splash.draw_image(iconUpP, 3, 3)
+                #screenShow()
+                display.show(splash)
+                while key_D.is_pressed()==1:
+                    time.sleep(0.001)
+                demoSelect=demoSelect-1
+                if(demoSelect==-1):
+                    demoSelect=demoNum-1
+            elif (key_C.is_pressed()):
+                splash.draw_image(iconDownP, 287, 3)
+                #screenShow()
+                display.show(splash)
+                while key_C.is_pressed()==1:
+                    time.sleep(0.001)
+                demoSelect=demoSelect+1
+                if(demoSelect==demoNum):
+                    demoSelect=0
+            elif (key_B.is_pressed()):
+                while key_B.is_pressed()==1:
+                    time.sleep(0.001)
+                execVal=2+demoSelect
+            elif (key_A.is_pressed()):
+                while key_A.is_pressed()==1:
+                    time.sleep(0.001)
+                menuSelect=0
+                pageVal=0
+                demoSelect=0
+                execVal=0
+                try:
+                    with open( '/tmp/page.txt', 'w' ) as f:
+                        f.write(str(pageVal))
+                except:
+                    pass
+                try:
+                    with open( '/tmp/menu.txt', 'w' ) as f:
+                        f.write(str(demoSelect))
+                except:
+                    pass
+                pageSig=1
+                selectSig=1
+            else:
+                pass
+        else:
+            if (key_A.is_pressed()):
+                while key_A.is_pressed()==1:
+                    time.sleep(0.001)
+                menuSelect=0
+                pageVal=0
+                demoSelect=0
+                execVal=0
+                systemRunNum=0
+    elif pageVal==2:
+        if(key_C.is_pressed()):
+            pageVal=0
+            menuSelect=0
+            pageVal=0
+            demoSelect=0
+            execVal=0
+            systemRunNum=0
+        elif key_B.is_pressed():
+            os.system("poweroff")
+        elif key_D.is_pressed():
+            os.system("reboot")
+    else:
+        pass
+
+def running():
+    from maix import display, image,camera
+    global splash,title_logo_text,btn_col,btn_row,splash_text,txt_unselected,txt_selected,btn_selected,btn_unselected,\
+splash_theme_color,btn_height,btn_width,main_title,menuSelect,pageVal,execVal,screenFirstPage,screenSecondPage,\
+color_splash_theme,color_blue,color_blue_lighter,color_white,color_gray,color_orange,color_red,demo_i,demo_j,\
+demo_m,demo_n,screenShow,img_drop,systemRunNum,systemPage,demoNameList,pageSig,selectSig,demoSelect
+    if pageSig==1:
+        try:
+            with open( '/tmp/page.txt', 'r' ) as f:
+                pageVal=int(f.read())
+                print(pageVal)
+            pageSig=0
+        except:
+            pass
+    if selectSig==1:
+        try:
+            with open( '/tmp/menu.txt', 'r' ) as f:
+                demoSelect=int(f.read())
+                print(demoSelect)
+            selectSig=0
+        except:
+            pass
+
+    if(pageVal==0):
+        screenFirstPage()
+        if(execVal==0):
+            pass
+            #splash.draw_rectangle(btn_col[0], btn_row-26,btn_col[0]+220,26, color=splash_theme_color, thickness=1)
+            #screenShow()
+            #display.show(splash)
+        else:
+            try:
+                splash.draw_string(btn_col[0], btn_row-25, splash_text[5], color=(0,255,255),thickness = 1)
+                #screenShow()
+                display.show(splash)
+                time.sleep(0.5)
+                os.system("ln -sf %s /tmp/event && touch /tmp/start" % "/root/user_latest_code.py")
+
+            except BaseException as e:
+                execVal=0
+                print(str(e))
+                splash.draw_rectangle(btn_col[0], btn_row-26,btn_col[0]+220,26, color=splash_theme_color, thickness=1)
+                splash.draw_string(btn_col[0], btn_row-85, splash_text[9], color=(255,0,0), thickness = 1)
+                #screenShow()
+                display.show(splash)
+    elif(pageVal==1):
+        if(execVal==0):
+            screenSecondPage()
+            #print("show(demoSelect)")
+        else:
+            demo_i=int(demoSelect/6)
+            demo_j=demoSelect%6
+            demo_m=int(demoNum/6)
+            demo_n=demoNum%6
+            splash.draw_rectangle(0,33+30*demo_j,319,33+30*(demo_j+1),color=color_orange,thickness=-1)
+            splash.draw_rectangle(0,33+30*demo_j,319,33+30*(demo_j+1),color=color_white,thickness=1)
+            splash.draw_string(8, 39+30*demo_j,splash_text[11] , color=color_white, thickness = 1)
+            #screenShow()
+            display.show(splash)
+            time.sleep(0.5)
+            app_path_1='ln -sf /root/preset/app/'
+            app_path_2='.py /tmp/event && touch /tmp/start'
+            app_path=app_path_1+demoNameList[execVal-2]+app_path_2
+            #print(app_path)
+            try:
+                with open( '/tmp/page.txt', 'w' ) as f:
+                    f.write(str(pageVal))
+            except:
+                pass
+            try:
+                with open( '/tmp/menu.txt', 'w' ) as f:
+                    f.write(str(demoSelect))
+            except:
+                pass
+            pageSig=1
+            selectSig=1
+            os.system(app_path)
+    else:
+        if systemRunNum==0:
+            systemPage()
+            systemRunNum=systemRunNum+1
+        else:
+            pass
+
+def screenShow():
+    from maix import image,display,camera
+    global img_drop
+    screenCapture=splash.crop(0,0,240,320)
+    img_drop.draw_image((screenCapture.rotate(0,adjust=1)),0,0)
+    #img_drop.draw_image((screenCapture.rotate(-90,adjust=1)),0,0)
+    display.show(img_drop)
+try:
+    with open( '/tmp/filesyStem.txt', 'w' ) as f:
+        f.write("a")
+    #os.system("rm /etc/wifi/wpa_supplicant.conf && touch /etc/wifi/wpa_supplicant.conf && sync && fsck.ext4 -p /dev/root && mount -o remount -o rw /dev/root && rm /etc/wifi/wpa_supplicant.conf && touch /etc/wifi/wpa_supplicant.conf && sync &")
+    os.system("sync && rm /tmp/filesyStem.txt && sync")
+    #os.system("fsck.ext4 -p /dev/root && mount -o remount -o rw /dev/root")
+    #os.system("rm /etc/wifi/wpa_supplicant.conf && touch /etc/wifi/wpa_supplicant.conf && sync")
+    
+except:
+    os.system("fsck.ext4 -p /dev/root && mount -o remount -o rw /dev/root")
+
+try:
+    os.popen("cd /root/preset/server/ && python wirelessServer.py &")
+except:
+    pass
+while True:
+    buttonDectect()
+    running()
+
+del key_A
+del key_B
+del key_C
+del key_D
+
+
+
+

+ 62 - 0
preset/app/01_camera.py

@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+#version    :       2024.03.14
+#language   :       ch
+#camera     :       CR5205
+
+from maix import camera
+from maix import display
+from maix import image     #引入python模块包
+import time
+import sys
+sys.path.append('/root/')
+from CocoPi import BUTTON
+
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+buttonState=0
+newState=0
+oldState=0
+def buttonDetect():
+    global buttonState,newState,oldState
+    newState=key_C.is_pressed()
+    if newState == True and oldState == False:
+        buttonState=1
+    elif newState == False and oldState == True:
+        buttonState=2
+    else:
+        buttonState=0
+    oldState=newState
+    
+def timeStampConvert():
+    timeListOutput=""
+    timeListOutput = str(time.localtime().tm_year) + \
+        str(time.localtime().tm_mon)+str(time.localtime().tm_mday) + \
+        str(time.localtime().tm_hour)+str(time.localtime().tm_min) + \
+        str(time.localtime().tm_sec)
+    return timeListOutput
+
+key_C = BUTTON(13)
+camera.camera.config(size=(320, 240))
+while True:
+    buttonDetect()
+    savePathHead="/root/user/img/photo_"
+    savePathTail=".jpg"
+    if buttonState!=2:
+        img_backdrop = image.new(size=(320,240),color=(0, 0, 0))    #创建背景画布
+        camera_img = camera.capture()    #从摄像头中获取一张图像
+        #camera_img_capture = camera_img.crop(0, 0, 320, 240)        #截取图像
+        img_backdrop.draw_image(camera_img)
+        img_backdrop.draw_image((image.open("/root/preset/img/camera_bfbfbf_24x24.png")).rotate(0, adjust=0),292,2,alpha=1)
+        img_backdrop.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+        display.show(img_backdrop)         #将图像显示出来
+    else:
+        img_backdrop = image.new(size=(320,240),color=(0, 0, 0))    #创建背景画布
+        camera_img = camera.capture()    #从摄像头中获取一张图像
+        camera_img_capture = camera_img.crop(0, 0, 320, 240)        #截取图像
+        # camera_img_rotate=camera_img_capture.rotate(90,adjust=1)
+        camera_img_capture.save(savePathHead+timeStampConvert()+savePathTail)
+        img_backdrop.draw_image(camera_img_capture.resize(280, 210),20,15)
+        img_backdrop.draw_image((image.open("/root/preset/img/camera_bfbfbf_24x24.png")).rotate(0, adjust=0),292,2,alpha=1)
+        img_backdrop.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+        display.show(img_backdrop)         #将图像显示出来
+        time.sleep(0.5)
+        

+ 95 - 0
preset/app/02_photoViewer.py

@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+#version    :       2024.03.15
+#language   :       ch
+#camera     :       CR5205
+
+import os
+from maix import display
+from maix import image
+from maix import camera
+import time
+import os
+import sys
+sys.path.append('/root/')
+from CocoPi import BUTTON
+
+key_A = BUTTON(14)
+key_B = BUTTON(8)
+key_C = BUTTON(13)
+key_D = BUTTON(7)
+camera.camera.config(size=(320,240))
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+
+###需要查询的文件夹目录及文件格式后缀###
+def getImgFileList(filePath="/root/user/img/",selectFile=".jpg"):
+    import os
+    FileList=[]
+    aimFilePath=filePath
+    aimFile=selectFile
+    aimFileLenth=len(selectFile)*(-1)
+    for root,dirs,files in os.walk(aimFilePath):
+        for name in files:
+            if str(name)[aimFileLenth:]==aimFile:
+                FileList.append(name)
+    return FileList
+pngImgShow=getImgFileList()
+picNum=len(pngImgShow)
+picSelect=0
+deleteSig=False
+
+canvas = image.new(size=(320, 240),color = (15,21,46),mode = "RGB")
+blackBlock=image.new(size=(320, 24), mode="RGB", color=(0, 0, 0))
+
+while True:
+    if picNum==0:
+        canvas.clear()
+        canvas.draw_string(24, 100, "未找到 .jpg 格式图片!", 1, color=(255, 0, 0))
+    else:
+        if key_B.is_pressed():
+            while key_B.is_pressed():
+                time.sleep(0.001)
+            deleteSig=True
+            os.system("rm /root/user/img/"+pngImgShow[picSelect])
+            pngImgShow=getImgFileList()
+            picNum=len(pngImgShow)
+        else:
+            if key_D.is_pressed():
+                while key_D.is_pressed():
+                    time.sleep(0.001)
+                picSelect=picSelect-1
+            elif key_C.is_pressed():
+                while key_C.is_pressed():
+                    time.sleep(0.001)
+                picSelect=picSelect+1
+            else:
+                picSelect=picSelect
+                
+            if picSelect>picNum-1:
+                picSelect=0
+            elif picSelect<0:
+                picSelect=picNum-1
+            else:
+                pass
+            canvas.clear()
+            try:
+                canvas.draw_image((image.open("/root/user/img/"+pngImgShow[picSelect])),0,0)
+            except:
+                canvas.draw_string(64, 100, "无法打开此张图片!", 1, color=(255,0, 0))
+            canvas.draw_string(60, 218, pngImgShow[picSelect], color=(255,255,255), thickness = 1)
+            
+    
+    canvas.draw_image(image.open("/root/preset/img/blackBlock_7f7f7f_320x24.jpg"), 0, 0,alpha=0.8)
+    canvas.draw_image(image.open("/root/preset/img/blackBlock_7f7f7f_320x24.jpg"), 0, 216,alpha=0.8)
+    canvas.draw_image((image.open("/root/preset/img/trashBox_ff0000_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/left_ffffff_16x16.png")).rotate(0, adjust=0),6,4,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/left_ffffff_16x16.png")).rotate(180, adjust=0),296,4,alpha=1)
+    #canvas.draw_image((image.open("/root/preset/img/blackBlock_000000_320x33.png")).rotate(0, adjust=0),0,0,alpha=0.3)
+    #canvas.draw_string(8, 39+30*demo_j,demoListText[demoSelect] , color=color_white, thickness = 1)
+    if picNum==0:
+        canvas.draw_string(116, 3, str(picSelect), color=(255,255,255), thickness = 1)
+    else:
+        canvas.draw_string(116, 3, str(picSelect+1), color=(255,255,255), thickness = 1)
+    canvas.draw_string(160, 3, "/   "+str(picNum), color=(255,255,255), thickness = 1)
+    
+    display.show(canvas)

+ 16 - 0
preset/app/03_colorDetection.py

@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from maix import display
+from maix import image
+from maix import camera
+camera.camera.config(size=(320,240))
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+
+while True:
+    canvas = camera.capture()
+    RGB = canvas.get_blob_color((154, 114, 10, 10), 0, 0)
+    canvas.draw_rectangle(154,114, 164,124, color=(255,0,0), thickness=1)
+    canvas.draw_rectangle(0,0, 319,20, color=((int(RGB[0])),(int(RGB[1])),(int(RGB[2]))), thickness=-1)
+    canvas.draw_string(120,0, (''.join([str(x) for x in ["(", int(RGB[0]), ",", int(RGB[1]), ",", int(RGB[2]), ")"]])), scale = 1, color = ((255 - int(RGB[0])),(255 - int(RGB[1])),(255 - int(RGB[2]))), thickness = 1)
+    display.show(canvas)

+ 123 - 0
preset/app/04_recorder.py

@@ -0,0 +1,123 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from maix import display
+from maix import image
+from maix import camera
+import pyaudio
+import wave
+import time
+import sys
+sys.path.append('/root/')
+#按键初始化
+from CocoPi import BUTTON
+key_C = BUTTON(13)
+
+buttonState=0
+newState=0
+oldState=0
+def buttonDetect():
+    global buttonState,newState,oldState,key_C
+    newState=key_C.is_pressed()
+    if newState == True and oldState == False:
+        buttonState=1
+    elif newState == False and oldState == True:
+        buttonState=2
+    else:
+        buttonState=0
+    oldState=newState
+    
+def timeStampConvert():
+    timeListOutput=""
+    timeListOutput = str(time.localtime().tm_year) + \
+        str(time.localtime().tm_mon)+str(time.localtime().tm_mday) + \
+        str(time.localtime().tm_hour)+str(time.localtime().tm_min) + \
+        str(time.localtime().tm_sec)
+    return timeListOutput
+
+#音频初始化
+CHUNK = 1024
+FORMAT = pyaudio.paInt16
+CHANNELS = 2
+RATE = 44100
+
+#屏幕初始化
+canvas = image.new(size=(320, 240),color = (15,21,46),mode = "RGB")
+
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+startPointer=0
+startTime=0
+global deltaTime
+deltaTime=0
+# 初始化
+startTime = time.time()
+oldState=0
+newState=0
+savePathHead="/root/user/audio/"
+savePathTail=".wav"
+recordState=0
+canvas.draw_string(12, 18, "提示:按下C键来开始/停止录音!", 1, color=(0, 255, 0))
+canvas.draw_string(58, 48, "   ", 1, color=(0, 255, 0))
+canvas.draw_image(image.open("/root/preset/img/recording.png"),288 , 8,alpha=1)
+canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+display.show(canvas)
+while True:
+    
+    buttonDetect()
+    if buttonState==2:
+        recordState=1-recordState
+        print("recordState",recordState)
+    if recordState==1:
+        if startPointer==0:
+            canvas.clear()
+            canvas = image.new(size=(320, 240),color = (15,21,46),mode = "RGB")
+            canvas.draw_string(12, 18, "提示:按下C键来开始/停止录音!", 1, color=(0, 255, 0))
+            canvas.draw_string(58, 48, "   ", 1, color=(0, 255, 0))
+            canvas.draw_image(image.open("/root/preset/img/recording.png"),288 , 8,alpha=1)
+            canvas.draw_string(24, 108, "开始录音!", 1, color=(0, 255, 0))
+            canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+            display.show(canvas)
+            print("Recording start!")
+            startTime = round(time.time(), 2)
+            startPointer=1
+            p = pyaudio.PyAudio()
+            stream = p.open(format=FORMAT,
+                            channels=CHANNELS,
+                            rate=RATE,
+                            input=True,
+                            frames_per_buffer=CHUNK)
+            frames = []
+        else:
+            data = stream.read(CHUNK,exception_on_overflow = False)
+            frames.append(data)  
+    elif recordState==0:
+        if startPointer==1:
+            stream.stop_stream()
+            stream.close()
+            p.terminate()
+            WAVE_OUTPUT_FILENAME=savePathHead+timeStampConvert()+savePathTail
+            wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
+            wf.setnchannels(CHANNELS)
+            wf.setsampwidth(p.get_sample_size(FORMAT))
+            wf.setframerate(RATE)
+            wf.writeframes(b''.join(frames))
+            wf.close()
+            deltaTime = round(time.time() - startTime, 2)
+            canvas.clear()
+            canvas = image.new(size=(320, 240),color = (15,21,46),mode = "RGB")
+            canvas.draw_string(12, 18, "提示:按下C键来开始/停止录音!", 1, color=(0, 255, 0))
+            canvas.draw_string(58, 48, "   ", 1, color=(0, 255, 0))
+            canvas.draw_image(image.open("/root/preset/img/recording.png"),288 , 8,alpha=1)
+            canvas.draw_string(24, 108, "录制完成!", 1, color=(0, 255, 0))
+            canvas.draw_string(24, 128, "持续时间(秒):"+str(deltaTime), 1, color=(0, 255, 0))
+            canvas.draw_string(24, 148, "文件保存路径:", 1, color=(0, 255, 0))
+            canvas.draw_string(24, 168, WAVE_OUTPUT_FILENAME, 1, color=(0, 255, 0))
+            canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+            
+            display.show(canvas)
+            print(deltaTime)
+            startPointer=0
+        else:
+            startPointer=0
+    else:
+        pass

+ 162 - 0
preset/app/05_audioPlayer.py

@@ -0,0 +1,162 @@
+#!/usr/bin/python
+#version    :       2023.12.31
+#language   :       ch
+import os
+from maix import display
+from maix import image
+from maix import camera
+import time
+import pyaudio
+import wave
+import sys
+sys.path.append('/root/')
+from CocoPi import BUTTON
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+key_A = BUTTON(14)
+key_B = BUTTON(8)
+key_C = BUTTON(13)
+key_D = BUTTON(7)
+camera.camera.config(size=(240,320))
+
+buttonState=0
+newState=0
+oldState=0
+def buttonDetect():
+    global buttonState,newState,oldState,key_C
+    newState=key_B.is_pressed()
+    if newState == True and oldState == False:
+        buttonState=1
+    elif newState == False and oldState == True:
+        buttonState=2
+    else:
+        buttonState=0
+    oldState=newState
+
+
+###需要查询的文件夹目录及文件格式后缀###
+def getWavFileList(filePath="/root/user/audio/",selectFile=".wav"):
+    import os
+    FileList=[]
+    aimFilePath=filePath
+    aimFile=selectFile
+    aimFileLenth=len(selectFile)*(-1)
+    for root,dirs,files in os.walk(aimFilePath):
+        for name in files:
+            if str(name)[aimFileLenth:]==aimFile:
+                FileList.append(name)
+    return FileList
+
+wavShow=getWavFileList()
+print(wavShow)
+audioNum=len(wavShow)
+audioSelect=0
+playState=0
+playRunState=0
+
+canvas = image.new(size = (320, 240))
+
+while True:
+    if audioNum==0:
+        canvas.clear()
+        canvas.draw_image(image.open("/root/preset/img/blackBlock_7f7f7f_320x24.jpg"), 0, 0,alpha=0.8)
+        canvas.draw_image(image.open("/root/preset/img/blackBlock_7f7f7f_320x24.jpg"), 0, 216,alpha=0.8)
+        canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+        canvas.draw_image((image.open("/root/preset/img/left_ffffff_16x16.png")).rotate(0, adjust=0),6,4,alpha=1)
+        canvas.draw_image((image.open("/root/preset/img/left_ffffff_16x16.png")).rotate(180, adjust=0),296,4,alpha=1)
+        canvas.draw_string(4, 140, "未找到WAV格式音频文件!", 1, color=(0, 255, 0))
+        display.show(canvas)
+    else:
+        if key_C.is_pressed():
+            while key_C.is_pressed():
+                time.sleep(0.001)
+            audioSelect=audioSelect-1
+        elif key_D.is_pressed():
+            while key_D.is_pressed():
+                time.sleep(0.001)
+            audioSelect=audioSelect+1
+        else:
+            buttonDetect()
+            if buttonState==2:
+                playState=1-playState
+                print("playState",playState)
+        if audioSelect>audioNum-1:
+            audioSelect=0
+        elif audioSelect<0:
+            audioSelect=audioNum-1
+        else:
+            pass
+        if playState==1:
+            if playRunState==0:
+                canvas.clear()
+                canvas.draw_image(image.open("/root/preset/img/blackBlock_7f7f7f_320x24.jpg"), 0, 0,alpha=0.8)
+                canvas.draw_image(image.open("/root/preset/img/blackBlock_7f7f7f_320x24.jpg"), 0, 216,alpha=0.8)
+                canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+                canvas.draw_image((image.open("/root/preset/img/left_ffffff_16x16.png")).rotate(0, adjust=0),6,4,alpha=1)
+                canvas.draw_image((image.open("/root/preset/img/left_ffffff_16x16.png")).rotate(180, adjust=0),296,4,alpha=1)
+                canvas.draw_string(4, 80, "音频状态:正在播放!", 1, color=(0, 255, 0))
+                canvas.draw_image((image.open("/root/preset/img/stop24.png")).rotate(0, adjust=0),4,216,alpha=1)
+                canvas.draw_string(104, 218, wavShow[audioSelect], 1, color=(0, 255, 0))
+                display.show(canvas)
+                CHUNK = 1024
+                wf = wave.open(r"/root/user/audio/"+wavShow[audioSelect], 'rb')
+                p = pyaudio.PyAudio()
+                stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),channels=wf.getnchannels(),rate=wf.getframerate(),output=True)
+                data = wf.readframes(CHUNK)
+                playRunState=1
+            elif playRunState==1:
+                if len(data) > 0:
+                    stream.write(data)
+                    data = wf.readframes(CHUNK)
+                else:
+                    stream.stop_stream()
+                    stream.close()
+                    p.terminate()
+                    canvas.clear()
+                    canvas.draw_image(image.open("/root/preset/img/blackBlock_7f7f7f_320x24.jpg"), 0, 0,alpha=0.8)
+                    canvas.draw_image(image.open("/root/preset/img/blackBlock_7f7f7f_320x24.jpg"), 0, 216,alpha=0.8)
+                    canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+                    canvas.draw_image((image.open("/root/preset/img/left_ffffff_16x16.png")).rotate(0, adjust=0),6,4,alpha=1)
+                    canvas.draw_image((image.open("/root/preset/img/left_ffffff_16x16.png")).rotate(180, adjust=0),296,4,alpha=1)
+                    canvas.draw_string(4, 80, "音频状态:播放完成!", 1, color=(0, 255, 0))
+                    canvas.draw_image((image.open("/root/preset/img/play24.png")).rotate(0, adjust=0),4,216,alpha=1)
+                    canvas.draw_string(104, 218, wavShow[audioSelect], 1, color=(0, 255, 0))
+                    display.show(canvas)
+                    playRunState=0
+                    playState=0
+                    time.sleep(0.5)
+            else:
+                pass
+        elif playState==0:
+            if playRunState==0:
+                canvas.clear()
+                canvas.draw_image(image.open("/root/preset/img/blackBlock_7f7f7f_320x24.jpg"), 0, 0,alpha=0.8)
+                canvas.draw_image(image.open("/root/preset/img/blackBlock_7f7f7f_320x24.jpg"), 0, 216,alpha=0.8)
+                canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+                canvas.draw_image((image.open("/root/preset/img/left_ffffff_16x16.png")).rotate(0, adjust=0),6,4,alpha=1)
+                canvas.draw_image((image.open("/root/preset/img/left_ffffff_16x16.png")).rotate(180, adjust=0),296,4,alpha=1)
+                canvas.draw_string(4, 80, "音频状态:等待播放!", 1, color=(0, 255, 0))
+                canvas.draw_image((image.open("/root/preset/img/play24.png")).rotate(0, adjust=0),4,216,alpha=1)
+                canvas.draw_string(104, 218, wavShow[audioSelect], 1, color=(0, 255, 0))
+                display.show(canvas)
+                playRunState=0
+            elif playRunState==1:
+                stream.stop_stream()
+                stream.close()
+                p.terminate()
+                canvas.clear()
+                canvas.draw_image(image.open("/root/preset/img/blackBlock_7f7f7f_320x24.jpg"), 0, 0,alpha=0.8)
+                canvas.draw_image(image.open("/root/preset/img/blackBlock_7f7f7f_320x24.jpg"), 0, 216,alpha=0.8)
+                canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+                canvas.draw_image((image.open("/root/preset/img/left_ffffff_16x16.png")).rotate(0, adjust=0),6,4,alpha=1)
+                canvas.draw_image((image.open("/root/preset/img/left_ffffff_16x16.png")).rotate(180, adjust=0),296,4,alpha=1)
+                canvas.draw_string(4, 80, "音频状态:播放结束!", 1, color=(0, 255, 0))
+                canvas.draw_image((image.open("/root/preset/img/play24.png")).rotate(0, adjust=0),4,216,alpha=1)
+                canvas.draw_string(4, 100, "音频路径:"+wavShow[audioSelect], 1, color=(0, 255, 0))
+                display.show(canvas)
+                playRunState=0
+            else:
+                pass
+        else:
+            pass
+        #canvas.clear()
+        #canvas.draw_image((image.open("/root/user/audio/"+wavShowShow[audioSelect])),0,0)

+ 28 - 0
preset/app/06_musicPlayer.py

@@ -0,0 +1,28 @@
+import os
+import pyaudio
+import wave
+import sys
+
+def voice_numberMap(value):
+    valueScaled = float(value - 0) / float(100)
+    return valueScaled * 31
+
+
+
+while True:
+    os.system("amixer cset numid=8,iface=MIXER,name='LINEOUT volume'voice_numberMap(25)")
+    CHUNK = 1024
+    wf = wave.open(r"/root/preset/audio/funky_stars_quazar.wav", 'rb')#(sys.argv[1], 'rb'
+    p = pyaudio.PyAudio()
+
+    stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),channels=wf.getnchannels(),rate=wf.getframerate(),output=True)
+
+    data = wf.readframes(CHUNK)
+    while len(data) > 0:
+        stream.write(data)
+        data = wf.readframes(CHUNK)
+
+    stream.stop_stream()
+    stream.close()
+
+    p.terminate()

+ 37 - 0
preset/app/07_videoPlayer.py

@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+#version    :       2023.04.04
+#language   :       ch
+import pyaudio, av, os,_thread
+from maix import display, camera, image
+# ffmpeg -r 30 -i badapple_240_60fps.mp4 -vf scale=240:240,setdar=1:1 output.mp4
+# adb push ./output.mp4 /root/
+path_to_video = '/root/preset/video/output_240_240.mp4'
+try:
+    container = av.open(path_to_video)
+    ai_stream = container.streams.audio[0]
+    vi_stream = container.streams.video[0]
+    fifo = av.AudioFifo()
+    p = pyaudio.PyAudio()
+    ao = p.open(format=pyaudio.paFloat32, channels=1, rate=44100, output=True)
+    audio = [p, ao, fifo]
+    def play_audio(audio):
+        try:
+            while len(audio):
+                for frame in audio[2].read_many(4096):
+                    audio[1].write(frame.planes[0].to_bytes())
+        except Exception as e:
+            print(e)
+    _thread.start_new_thread(play_audio, (audio, ) )
+    for frame in container.decode(video=0, audio=0):
+        if 'Audio' in repr(frame):
+            frame.pts = None
+            frame.time_base = None
+            fifo.write(frame)
+        if 'Video' in repr(frame):
+            img = image.load(bytes(frame.to_rgb().planes[0]), (vi_stream.width, vi_stream.height))
+            display.show(img)
+finally:
+    ao.stop_stream()
+    ao.close()
+    p.terminate()
+    audio = []

+ 71 - 0
preset/app/08_timeCounter.py

@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from maix import display
+from maix import image
+from maix import camera
+import time
+import sys
+sys.path.append('/root/')
+from CocoPi import BUTTON
+# 秒表小程序
+key_C = BUTTON(13)
+key_B = BUTTON(8)
+camera.camera.config(size=(240,320))
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+signal=0
+startPointer=0
+startTime=0
+global deltaTime
+deltaTime=0
+# 初始化
+startTime = time.time()
+oldState=0
+newState=0
+canvas = image.new(color=(0,0,0),size = (320, 240))
+while True:
+    canvas.clear()
+    if key_B.is_pressed():
+        time.sleep(0.02)
+        deltaTime = 0
+        startTime = round(time.time(), 3)
+    else:
+        pass
+    newState=key_C.is_pressed()
+    if (newState==0 and oldState==1):
+        time.sleep(0.02)
+        signal=1-signal
+        if deltaTime == 0:
+            startTime = round(time.time(), 3)
+        else:
+            startTime =  round(time.time(), 3) - deltaTime
+    else:
+        pass
+    if signal==1:
+        if startPointer==0:
+            startPointer=1
+            #print("startPoniter",startPoniter)
+        else:
+            #pass
+            deltaTime = round(time.time() - startTime, 3)
+            #deltaTime = time.time()-startTime
+            #deltaTime = round(time.time()-startTime, 5)
+            #canvas.draw_string(80, 128, "持续时间:"+str(deltaTime), 1, color=(0, 255, 0))
+        
+    elif signal==0:
+        startPointer=0
+    else:
+        pass
+    if signal==1:
+        canvas.draw_string(80, 108, "正在计时中...", 1, color=(0, 255, 0))
+        canvas.draw_image((image.open("/root/preset/img/stop24.png")).rotate(0, adjust=0),288,2,alpha=1)
+    else:
+        canvas.draw_string(80, 108, "等待计时...", 1, color=(0, 255, 0))
+        canvas.draw_image((image.open("/root/preset/img/play24.png")).rotate(0, adjust=0),288,2,alpha=1)
+    canvas.draw_string(80, 128, "计时持续时间(秒):"+str(deltaTime), 1, color=(0, 255, 0))
+    canvas.draw_string(16, 8, "按下C键来开始/停止计时!", 1, color=(0, 255, 0))
+    
+    canvas.draw_image((image.open("/root/preset/img/restart_ff0000_24x24.png")).rotate(0, adjust=0),2,216,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+    display.show(canvas)
+    oldState=newState

+ 11 - 0
preset/app/09_localTimeClock.py

@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+import time
+from maix import camera, display, image
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+while True:
+    hello_img = image.new(size = (240, 240), color = (0, 0, 0), mode = "RGB")
+    hello_img.draw_string(20, 108, time.asctime(), scale = 1.0, color = (255, 255, 255), thickness = 1)
+    display.show(hello_img)
+    time.sleep(1)

+ 58 - 0
preset/app/10_servoControl.py

@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+#hardware   :       pi
+
+from maix import display
+from maix import image
+from maix import camera
+import time
+import sys
+sys.path.append('/root/')
+from CocoPi import BUTTON
+from CocoPi import multiFuncGpio
+S1=multiFuncGpio(0,1)
+S2=multiFuncGpio(1,1)
+
+key_D = BUTTON(7)
+key_C = BUTTON(13)
+
+camera.camera.config(size=(320,240))
+ScreenOrientation = False
+angle=0
+addValue=0
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+
+canvas = image.new(size = (320, 240))
+while True:
+    if(key_C.is_pressed()):
+        if angle<180:
+            addValue=1
+        else:
+            addValue=0
+    elif key_D.is_pressed():
+        if angle>0:
+            addValue=-1
+        else:
+            addValue=0
+    else:
+        addValue=0
+    canvas = image.new(color=(0,0,0),size = (320, 240))
+    
+    angle=angle+addValue
+    #canvas.draw_string(4, 180, "C:increase servo's angle", 1, color=(0, 255, 0))
+    #canvas.draw_string(4, 200, "D:decrease servo's angle", 1, color=(0, 255, 0))
+    canvas.draw_string(80, 10, "舵机角度值:"+str(angle), 1, color=(0, 0, 255))
+    canvas.draw_image((image.open("/root/preset/img/sg90.png")).rotate(0, adjust=1),132,70,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/sg90_double_arm.png")).rotate(angle, adjust=0),103,89,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/increase_bfbfbf_24x24.png")).rotate(0, adjust=0),288,8,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/decrease_bfbfbf_24x24.png")).rotate(0, adjust=0),8,8,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+    S1.servoCtrl(angle)
+    S2.servoCtrl(angle)
+    if ScreenOrientation:
+        canvasVER = canvas.crop(0,0,240,320)
+        canvasVER = canvasVER.rotate(-90, adjust=1)
+        display.show(canvasVER)
+    else:
+        display.show(canvas)

+ 93 - 0
preset/app/11_motorControl.py

@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+#hardware   :       pi
+from maix import display
+from maix import image
+from maix import camera
+import smbus2
+import time
+import sys
+sys.path.append("/root/")
+from CocoPi import stm8s
+iic_slaver=stm8s()
+iic_slaver.clear()
+del iic_slaver
+from CocoPi import dcMotor
+from CocoPi import BUTTON
+
+key_D = BUTTON(7)
+key_B = BUTTON(8)
+key_C = BUTTON(13)
+
+D1=dcMotor(1)
+D2=dcMotor(2)
+
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+camera.camera.config(size=(320,240))
+ScreenOrientation = False
+speed=0
+rotation=1
+addValue=1
+angle=0
+
+canvas = image.new(size = (320, 240))
+while True:
+    if (key_B.is_pressed()):
+        while key_B.is_pressed():
+            time.sleep(0.001)
+        rotation=(-1)*rotation
+    if(key_C.is_pressed()):
+        if speed<255:
+            addValue=1
+        else:
+            addValue=0
+    elif key_D.is_pressed():
+        if speed>0:
+            addValue=-1
+        else:
+            addValue=0
+    else:
+        addValue=0
+    canvas = image.new(color=(0,0,0),size = (320, 240))
+    
+    speed=speed+addValue
+    canvas.draw_string(80, 8, "转速:"+str(speed), 1, color=(0, 255, 0))
+    if rotation==1:
+        canvas.draw_image((image.open("/root/preset/img/clockwise_bfbfbf_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+        #canvas.draw_string(40, 24, "rotation:clockwise", 1, color=(0, 255, 0))
+    else:
+        canvas.draw_image((image.open("/root/preset/img/anticlockwise_bfbfbf_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+        #canvas.draw_string(40, 24, "rotation:anticlockwise", 1, color=(0, 255, 0))
+    angle=angle-int(rotation*speed/3)
+    if angle>3600:
+        angle=angle-3600
+    elif angle<-3600:
+        angle=angle+3600
+    else:
+        angle=angle
+    #canvas.draw_string(4, 180, "C:change fan's direction of rotation", 1, color=(0, 255, 0))
+    #canvas.draw_string(4, 200, "D:increase fan's speed of rotation", 1, color=(0, 255, 0))
+    #canvas.draw_string(4, 220, "B:decrease fan's speed of rotation", 1, color=(0, 255, 0))
+    canvas.draw_image((image.open("/root/preset/img/ttMotor_200_64.png")).rotate(0, adjust=1),80,90,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/fan_140_140.png")).rotate(angle, adjust=0),60,52,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/increase_bfbfbf_24x24.png")).rotate(0, adjust=0),288,8,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/decrease_bfbfbf_24x24.png")).rotate(0, adjust=0),8,8,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+    if(speed<80):
+        D1.dcMotorCtrl(rotation,speed)
+        D2.dcMotorCtrl(rotation,speed)
+    else:
+        if rotation==1:
+            D1.dcMotorCtrl(1,speed)
+            D2.dcMotorCtrl(1,speed)
+        else:
+            D1.dcMotorCtrl(0,speed)
+            D2.dcMotorCtrl(0,speed)
+        time.sleep(0.004)
+    if ScreenOrientation:
+        canvasVER = canvas.crop(0,0,240,320)
+        canvasVER = canvasVER.rotate(-90, adjust=1)
+        display.show(canvasVER)
+    else:
+        display.show(canvas)

+ 32 - 0
preset/app/12_pictureLoopPlay.py

@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from maix import display
+
+from maix import image
+
+from maix import camera
+import time
+
+camera.camera.config(size=(320,240))
+
+ScreenOrientation = False
+
+
+
+canvas = image.new(size = (320, 240))
+img_num = 0
+while True:
+    img_num = img_num + 1
+    canvas.draw_image((image.open((str("/root/preset/img/dog/dog") + str(str(img_num) + str(".jpg"))))),0,0)
+
+    time.sleep(1)
+    if img_num == 30:
+        img_num = 1
+    if ScreenOrientation:
+        canvasVER = canvas.crop(0,0,240,320)
+        canvasVER = canvasVER.rotate(-90, adjust=1)
+        display.show(canvasVER)
+    else:
+        canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+        display.show(canvas)

+ 27 - 0
preset/app/13_qrCodeScanner.py

@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from maix import camera, display, zbar, image
+import sys
+sys.path.append('/root/CocoPi.py')
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+camera.camera.config(size=(320,240))
+
+while True:
+    canvas = camera.capture()
+    mks = canvas.find_qrcodes()
+    for mk in mks:
+        #外框数据
+        X = mk['x']
+        Y = mk['y']
+        W = mk['w']
+        H = mk['h']            
+        #二维码信息
+        string = mk['payload']
+        #画外框
+        canvas.draw_rectangle(X, Y, X + W, Y + H, color=(0, 0, 255), thickness = 2) 
+        #打印信息
+        canvas.draw_string(int(X) , int(Y - 35) , str(string), scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+    canvas.draw_image(image.open("/root/preset/img/exit_ff0000_24x24.png"),288,216,alpha=1)
+    display.show(canvas)
+    

+ 57 - 0
preset/app/14_humanDetection.py

@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from time import time
+from maix import image
+class Person:
+    mud_path = "/root/preset/model/person_int8.mud"
+    labels = ["person"]
+    anchors = [4.72, 6.26, 1.39, 3.53, 0.78, 1.9, 0.35, 0.95, 2.49, 4.87]
+
+    def __init__(self) -> None:
+        from maix import nn
+        self.model = nn.load(self.mud_path)
+        from maix.nn import decoder
+        self.decoder = decoder.Yolo2(len(self.labels) , self.anchors , net_in_size = (224, 224) ,net_out_size = (7,7))
+
+    def __del__(self):
+        del self.model
+        del self.decoder
+
+    def cal_fps(self ,start , end):
+        one_second = 1
+        one_flash = end - start
+        fps = one_second / one_flash
+        return  fps
+
+    def draw_rectangle_with_title(self ,img, box, disp_str , fps ):
+        img.draw_rectangle(box[0], box[1], box[0] + box[2], box[1] + box[3],color=(255, 0, 0), thickness=2)
+        img.draw_string(box[0], box[1]+ box[3] ,disp_str, scale=1,color=(0, 0, 255), thickness=2)
+        #img.draw_string(0, 0 ,'FPS :'+str(fps), scale=2 ,color=(0, 0, 255), thickness=2)
+
+    def process(self,input):
+        t =  time()
+        out = self.model.forward(input, quantize=1, layout = "hwc")
+        boxes, probs = self.decoder.run(out, nms=0.5, threshold=0.6, img_size=(224,224))
+        for i, box in enumerate(boxes):
+            class_id = probs[i][0]
+            prob = probs[i][1][class_id]
+            disp_str = "{}:{:.2f}%".format(self.labels[class_id], prob*100)
+            fps = self.cal_fps(t, time())
+            self.draw_rectangle_with_title(input, box, disp_str, fps)
+
+
+canvasImg = image.new(size = (320, 240))
+def main():
+    from maix import display, camera
+    app = Person()
+    #camera.config((224,224))
+    while True:
+        canvasImg.clear()
+        img = camera.capture().crop(0, 0,224, 224)
+        app.process(img)
+        canvasImg.draw_image(img,48,8)
+        canvasImg.draw_image(image.open("/root/preset/img/exit_ff0000_24x24.png"),288,216,alpha=1)
+        display.show(canvasImg)
+
+main()

+ 49 - 0
preset/app/15_faceDetection.py

@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from maix import camera
+from maix import display
+
+from maix import image
+
+from maix import nn
+from maix.nn import decoder
+
+camera.camera.config(size=(320,240))
+
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+
+model = {
+    "param": "/root/preset/model/yolo2_face_awnn.param",
+    "bin": "/root/preset/model/yolo2_face_awnn.bin"
+}
+labels = ["person"]
+options = {
+    "model_type":  "awnn",
+    "inputs": {
+        "input0": (224, 224, 3)
+    },
+    "outputs": {
+        "output0": (7, 7, (1+4+len(labels))*5)
+    },
+    "mean": [127.5, 127.5, 127.5],
+    "norm": [0.0078125, 0.0078125, 0.0078125],
+}
+anchors = [1.19, 1.98, 2.79, 4.59, 4.53, 8.92, 8.06, 5.29, 10.32, 10.65]
+m = nn.load(model, opt=options)
+yolo2_decoder = decoder.Yolo2(len(labels), anchors, net_in_size=(options["inputs"]["input0"][0], options["inputs"]["input0"][1]), net_out_size=(7, 7))
+
+
+canvasImg = image.new(size = (240, 320))
+while True:
+    canvasImg.clear()
+    img_facedetection = camera.capture()
+    img_facedetection = img_facedetection.crop(0, 0,224, 224)
+    out = m.forward(img_facedetection.tobytes(), quantize=True, layout="hwc")
+    boxes, probs = yolo2_decoder.run(out, nms=0.3, threshold=0.3, img_size=(options["inputs"]["input0"][0], options["inputs"]["input0"][1]))
+    if len(boxes):
+        for i in (boxes):
+            img_facedetection.draw_rectangle(i[0],i[1], int(i[0]+i[2]),int(i[1]+i[3]), color=(255,0,0), thickness=1)
+    canvasImg.draw_image(img_facedetection,48,8)
+    canvasImg.draw_image(image.open("/root/preset/img/exit_ff0000_24x24.png"),288,216,alpha=1)
+    display.show(canvasImg)

+ 171 - 0
preset/app/16_faceComparison.py

@@ -0,0 +1,171 @@
+'''
+    Face recognize demo, download model from maixhub first:
+            https://maixhub.com/
+'''
+
+from maix import nn, display, camera, image
+from maix.nn.app import face
+from maix.nn.app.face import FaceRecognize
+import time
+import sys
+sys.path.append('/root/')
+from CocoPi import BUTTON
+
+key_A = BUTTON(14)
+key_B = BUTTON(8)
+key_C = BUTTON(13)
+key_D = BUTTON(7)
+ScreenOrientation = False
+class Face_Recognizer:
+    def __init__(self, threshold = 0.5, nms = 0.3, max_face_num = 1):
+        model = "/root/preset/model/retinaface.mud"
+        model_fe = "/root/preset/model/fe_resnet.mud"
+        self.input_size = (224, 224, 3)
+        input_size_fe = (128, 128, 3)
+        self.feature_len = 256
+        self.features = []
+        print("-- load model:", model)
+        m = nn.load(model)
+        print("-- load ok")
+        print("-- load model:", model_fe)
+        m_fe = nn.load(model_fe)
+        print("-- load ok")
+
+        self.recognizer = FaceRecognize(m, m_fe, self.feature_len, self.input_size, threshold, nms, max_face_num)
+        print("-- init end")
+
+    def get_faces(self, img, std_img = False):
+        faces = self.recognizer.get_faces(img, std_img)
+        return faces
+
+    def __len__(self):
+        return len(self.features)
+
+    def add_user(self, name, feature):
+        self.features.append([name, feature])
+        return True
+
+    def remove_user(self, name_del):
+        rm = None
+        for name, feature in self.features:
+            if name_del == name:
+                rm = [name, feature]
+        if rm:
+            self.features.remove(rm)
+            return True
+        return False
+
+    def recognize(self, feature):
+        max_score = 0
+        uid = -1
+        for i, user in enumerate(self.features):
+            score = self.recognizer.compare(user[1], feature)
+            if score > max_score:
+                max_score = score
+                uid = i
+        if uid >= 0:
+            return self.features[uid][0], max_score
+        return None, 0
+
+
+    def get_input_size(self):
+        '''
+            @return input_size (w, h, c)
+        '''
+        return self.input_size
+
+    def get_feature_len(self):
+        return self.feature_len
+
+    def darw_info(self, img, box, points, disp_str, bg_color=(255, 0, 0, 255), font_color=(255, 255, 255, 255), font_size=32):
+        font_wh = image.get_string_size(disp_str)
+        for p in points:
+            img.draw_rectangle(p[0] - 1, p[1] -1, p[0] + 1, p[1] + 1, color=bg_color)
+        img.draw_rectangle(box[0], box[1], box[0] + box[2], box[1] + box[3], color=bg_color, thickness=2)
+        if disp_str:
+            img.draw_rectangle(box[0], box[1] - font_wh[1], box[0] + font_wh[0], box[1], color=bg_color, thickness = -1)
+            img.draw_string(box[0], box[1] - font_wh[1], disp_str, color=font_color)
+
+
+    def darw_title(self, img, dis_size ,key_l = None, key_r =None):
+        if key_C:
+            key_l = "| "+ key_l
+            img.draw_string( 1, 2 ,key_l , scale = 1, color = (255, 255, 255), thickness = 2)
+        if key_D:
+            key_r = key_r+" |"
+            w = int(dis_size[0] - 4 - image.get_string_size(key_r)[0] * 1)
+            img.draw_string( w, 2 ,key_r , scale = 1, color = (255, 255, 255), thickness = 2)
+
+
+
+max_face_num = 4
+detect_threshold = 0.5
+detect_nms = 0.3
+score_threshold = 70
+names = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
+
+face_recognizer = Face_Recognizer(detect_threshold, detect_nms, max_face_num = max_face_num)
+camera.config(size=face_recognizer.get_input_size()[:2])
+
+def lcdRotation(inputImg,rotationAngle):
+    from maix import image
+    imageRotationBuffer = inputImg.crop(0, 0, 240, 320)
+    if ScreenOrientation:
+        imgRotationAim = image.new(size = (240, 320))
+    else:
+        imgRotationAim = image.new(size = (320, 240))
+    return imgRotationAim.draw_image(imageRotationBuffer.rotate(rotationAngle, adjust=1),0,0,alpha=1)
+
+if ScreenOrientation:
+    CAMERAROTATE = +180
+else:
+    CAMERAROTATE = +90
+
+
+
+canvasImg = image.new(size = (240, 320))
+while 1:
+    canvasImg.clear()
+    img = camera.capture().crop(0, 0,224, 224)
+    if not img:
+        time.sleep(0.02)
+        continue
+    faces = face_recognizer.get_faces(img)
+    face_recognizer.darw_title(img , face_recognizer.get_input_size()[:2] , "rm" ,"add")
+
+    if faces:
+        # for prob, box, landmarks, feature, std_img in faces:
+        for prob, box, landmarks, feature in faces:
+            # [ prob, [x,y,w,h], [[x,y], [x,y], [x,y], [x,y], [x,y]], feature ]
+            if key_C.is_pressed():
+                if len(face_recognizer) < len(names):
+                    while not (key_C.is_pressed() == False):
+                        time.sleep(0.1)
+                    idx = len(face_recognizer)
+                    print("add user: {}, {}".format(idx, names[idx]))
+                    face_recognizer.add_user(names[idx], feature)
+                else:
+                    print("user full")
+            name, score = face_recognizer.recognize(feature)
+            if name:
+                if score > score_threshold:
+                    face_recognizer.darw_info(img, box, landmarks, "{}:{:.2f}".format(name, score), font_color=(0, 0, 255, 255), bg_color=(0, 255, 0, 255))
+                    print("user: {}, score: {:.2f}".format(name, score))
+                else:
+                    face_recognizer.darw_info(img, box, landmarks, "{}:{:.2f}".format(name, score), font_color=(255, 255, 255, 255), bg_color=(255, 0, 0, 255))
+                    print("maybe user: {}, score: {:.2f}".format(name, score))
+            else:
+                face_recognizer.darw_info(img, box, landmarks, "", font_color=(255, 255, 255, 255), bg_color=(255, 255, 255, 255))
+
+    if key_D.is_pressed():
+        if len(face_recognizer) > 0:
+            while not (key_D.is_pressed() == False):
+                time.sleep(0.1)
+            idx = len(face_recognizer) - 1
+            print("remove user:", names[idx])
+            face_recognizer.remove_user(names[idx])
+        else:
+            print("user empty")
+    canvasImg.draw_image(img,48,8)
+    canvasImg.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+    display.show(canvasImg)

+ 77 - 0
preset/app/17_objectRecognition.py

@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from maix import camera
+from maix import display
+
+from maix import image
+
+from maix import nn
+from maix.nn import decoder
+
+camera.camera.config(size=(320,240))
+
+ScreenOrientation = False
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+
+model = {
+    "param": "/root/preset/model/yolo2_20class_awnn.param",
+    "bin": "/root/preset/model/yolo2_20class_awnn.bin"
+}
+options = {
+    "model_type":  "awnn",
+    "inputs": {
+        "input0": (224, 224, 3)
+    },
+    "outputs": {
+        "output0": (7, 7, (1+4+20)*5)
+    },
+    "mean": [127.5, 127.5, 127.5],
+    "norm": [0.0078125, 0.0078125, 0.0078125],
+}
+labels = ['飞机', '自行车', '鸟', '船', '瓶子', '公共汽车', '汽车', '猫', '椅子', '牛', '餐桌', '狗', '马', '摩托车', '人', '盆栽', '羊', '沙发', '火车', '电视监视器']
+#labels = ['plane', 'bicycle', 'bird', 'ship', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'table', 'dog', 'horse', 'motobike', 'human', 'Pot plant', 'sheep', 'sofa', 'train', 'tv']
+anchors = [5.4, 5.38, 1.65, 2.09, 0.8, 1.83, 2.45, 4.14, 0.46, 0.8]
+m = nn.load(model, opt=options)
+yolo2_decoder = decoder.Yolo2(len(labels), anchors, net_in_size=(options["inputs"]["input0"][0], options["inputs"]["input0"][1]), net_out_size=(7, 7))
+
+def lcdRotation(inputImg,rotationAngle):
+    from maix import image
+    imageRotationBuffer = inputImg.crop(0, 0, 240, 320)
+    if ScreenOrientation:
+        imgRotationAim = image.new(size = (240, 320))
+    else:
+        imgRotationAim = image.new(size = (320, 240))
+    return imgRotationAim.draw_image(imageRotationBuffer.rotate(rotationAngle, adjust=1),0,0,alpha=1)
+
+if ScreenOrientation:
+    CAMERAROTATE = +180
+else:
+    CAMERAROTATE = +90
+
+
+
+canvasImg = image.new(size = (240, 320))
+while True:
+    canvasImg.clear()
+    img_objectrecognition = camera.capture()
+    img_objectrecognition = img_objectrecognition.crop(0, 0,224, 224)
+    out = m.forward(img_objectrecognition.tobytes(), quantize=True, layout="hwc")
+    boxes, probs = yolo2_decoder.run(out, nms=0.3, threshold=0.3, img_size=(options["inputs"]["input0"][0], options["inputs"]["input0"][1]))
+    if len(boxes):
+        for boxesi, box in enumerate(boxes):
+            boxes[boxesi].append(probs[boxesi])
+    if len(boxes):
+        for i in (boxes):
+            img_objectrecognition.draw_string(10,0, (str(str(labels[i[4][0]])) + str(round(i[4][1][i[4][0]]*100, 2))), scale = 1, color = (255,0,0) , thickness = 1)
+            img_objectrecognition.draw_rectangle(i[0],i[1], int(i[0]+i[2]),int(i[1]+i[3]), color=(255,0,0), thickness=1)
+    else:
+        img_objectrecognition.draw_string(10,0, "未识别到任何目标!", scale = 1, color = (255,0,0) , thickness = 1)
+    if ScreenOrientation:
+        img_objectrecognitionVER = img_objectrecognition.crop(0,0,240,320)
+        img_objectrecognitionVER = img_objectrecognitionVER.rotate(-90, adjust=1)
+        display.show(img_objectrecognitionVER)
+    else:
+        canvasImg.draw_image(img_objectrecognition,48,8)
+        canvasImg.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+        display.show(canvasImg)

+ 77 - 0
preset/app/18_edgeDetection.py

@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from maix import camera
+from maix import display
+
+from maix import image
+
+import numpy as np
+
+camera.camera.config(size=(320,240))
+
+ScreenOrientation = False
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+
+class Edge:
+    model = {
+        "param": "/root/preset/model/sobel_int8.param",
+        "bin": "/root/preset/model/sobel_int8.bin"
+    }
+    input_size = (224, 224, 3)
+    output_size = (222, 222, 3)
+    options = {
+        "model_type":  "awnn",
+        "inputs": {
+            "input0": input_size
+        },
+        "outputs": {
+            "output0": output_size
+        },
+        "mean": [127.5, 127.5, 127.5],
+        "norm": [0.0078125, 0.0078125, 0.0078125],
+    }
+    def __init__(self):
+        from maix import nn
+        print("-- load model:", self.model)
+        self.model = nn.load(self.model, opt=self.options)
+        print("-- load ok")
+    def __del__(self):
+        del self.model
+
+m = Edge()
+def lcdRotation(inputImg,rotationAngle):
+    from maix import image
+    imageRotationBuffer = inputImg.crop(0, 0, 240, 320)
+    if ScreenOrientation:
+        imgRotationAim = image.new(size = (240, 320))
+    else:
+        imgRotationAim = image.new(size = (320, 240))
+    return imgRotationAim.draw_image(imageRotationBuffer.rotate(rotationAngle, adjust=1),0,0,alpha=1)
+
+if ScreenOrientation:
+    CAMERAROTATE = +180
+else:
+    CAMERAROTATE = +90
+
+
+
+canvas = image.new(size = (320, 240))
+while True:
+    canvas.clear()
+    img_edgedetection = camera.capture()
+    img_edgedetection = img_edgedetection.resize(224, 224, padding = 0)
+    out = m.model.forward(img_edgedetection, quantize=True, layout="hwc")
+    out = out.astype(np.float32).reshape(m.output_size)
+    out = (np.ndarray.__abs__(out) * 255 / out.max()).astype(np.uint8)
+    data = out.tobytes()
+    edgeModel = img_edgedetection.load(data,(222, 222), mode="RGB")
+    # canvas = edgeModel
+    if ScreenOrientation:
+        canvasVER = canvas.crop(0,0,240,320)
+        canvasVER = canvasVER.rotate(-90, adjust=1)
+        display.show(canvasVER)
+    else:
+        canvas.draw_image(edgeModel,48,8)
+        canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+        display.show(canvas)

+ 73 - 0
preset/app/19_handWrittenDigiRecognition.py

@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from maix import camera
+from maix import display
+
+from maix import image
+
+from maix import nn
+from maix.nn import decoder
+
+camera.camera.config(size=(320,240))
+
+ScreenOrientation = False
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+
+def lcdRotation(inputImg,rotationAngle):
+    from maix import image
+    imageRotationBuffer = inputImg.crop(0, 0, 240, 320)
+    if ScreenOrientation:
+        imgRotationAim = image.new(size = (240, 320))
+    else:
+        imgRotationAim = image.new(size = (320, 240))
+    return imgRotationAim.draw_image(imageRotationBuffer.rotate(rotationAngle, adjust=1),0,0,alpha=1)
+
+if ScreenOrientation:
+    CAMERAROTATE = +180
+else:
+    CAMERAROTATE = +90
+
+
+
+
+class Number_recognition:
+    mdsc_path = "/root/preset/model/Number.mud"
+    labels = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
+    anchors = [1.0, 5.0, 1.35, 5.42, 0.49, 2.55, 0.86, 3.75, 0.65, 4.38]
+
+    def __init__(self):
+        self.model = nn.load(self.mdsc_path)
+        self.decoder = decoder.Yolo2(len(self.labels) , self.anchors , net_in_size = (224, 224) ,net_out_size = (7,7))
+    def __del__(self):
+        del self.model
+        del self.decoder
+    def cal_fps(self ,start , end):
+        one_second = 1
+        one_flash = end - start
+        fps = one_second / one_flash
+        return  fps
+
+number_recognition = Number_recognition()
+canvasImg = image.new(size = (240, 320))
+while True:
+    canvasImg.clear()
+    img_mnist = camera.capture()
+    img_mnist = img_mnist.crop(0, 0,224, 224)
+    out = number_recognition.model.forward(img_mnist, quantize=1, layout = "hwc")
+    boxes, probs = number_recognition.decoder.run(out, nms=0.5, threshold=0.3, img_size=(224,224))
+    if len(boxes):
+        for boxesi, box in enumerate(boxes):
+            boxes[boxesi].append(probs[boxesi])
+    if len(boxes):
+        for i in (boxes):
+            img_mnist.draw_string(i[0],i[1], (str(number_recognition.labels[i[4][0]]) + str(str(":") + str(round(i[4][1][i[4][0]]*100, 2)))), scale = 1, color = (255,0,0) , thickness = 1)
+            img_mnist.draw_rectangle(i[0],i[1], int(i[0] + i[2]),int(i[1] + i[3]), color=(255,0,0), thickness=1)
+    if ScreenOrientation:
+        img_mnistVER = img_mnist.crop(0,0,240,320)
+        img_mnistVER = img_mnistVER.rotate(-90, adjust=1)
+        display.show(img_mnistVER)
+    else:
+        canvasImg.draw_image(img_mnist,48,8)
+        canvasImg.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+        display.show(canvasImg)

+ 106 - 0
preset/app/20_carLicensePlateRecognition.py

@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from time import time
+
+ScreenOrientation = False
+
+class LPR:
+    loc_model_path = '/root/preset/model/loc.mud'
+    reg_model_path = '/root/preset/model/reg.mud'
+    chars =[ "皖", "沪", "津", "渝", "冀", "晋", "蒙", "辽", "吉", "黑",
+                    "苏", "浙", "京", "闽", "赣", "鲁", "豫", "鄂", "湘" , "粤",
+                    "桂", "琼", "川", "贵", "云", "藏", "陕", "甘", "青" , "宁",
+                    "新", "警", "学", "A"  , "B" ,  "C" ,  "D" ,  "E" ,  "F"  ,  "G",
+                    "H" ,   "J" ,  "K" ,  "L" , "M" , "N" ,  "P" ,  "Q" ,  "R" , "S",
+                    "T" ,  "U" ,  "V" , "W", "X"  , "Y" , "Z" , "0" , "1", "2", "3",
+                    "4", "5", "6", "7", "8", "9", "-"]
+
+    variances = [0.1, 0.2]
+    steps = [8, 16, 32]
+    min_sizes = [12, 24, 48, 96, 192, 320]
+
+    def __init__(self) -> None:
+        from maix import nn
+        self.loc_model = nn.load(self.loc_model_path , opt = None)
+        self.reg_model = nn.load(self.reg_model_path , opt = None)
+
+        from maix.nn import decoder
+        self.loc_decoder = decoder.license_plate_location([224,224] , self.steps , self.min_sizes, self.variances)
+        self.reg_decoder  = decoder.CTC((1,68,18))
+
+    def __del__(self):
+        del self.loc_model
+        del self.loc_decoder
+
+    def cal_fps(self ,start , end):
+        one_second = 1
+        one_flash = end - start
+        fps = one_second / one_flash
+        return  fps
+
+    def  draw_fps(self,img , fps):
+        img.draw_string(0, 0 ,'FPS :'+str(fps), scale=1,color=(255, 0, 255), thickness=1)
+
+    def draw_string(self , img , x , y , string , color):
+        img.draw_string( x , y , string ,color = color)
+
+    def draw_paste(self , src ,dst):
+        src.paste(dst , 0 , 0)
+
+    def draw_rectangle(self,img, box):
+        img.draw_rectangle(box[0], box[1], box[2], box[3],color=(230 ,230, 250), thickness=2)
+
+    def draw_point(self,img,landmark):
+        for i in range(4):
+            x = landmark[2 * i ]
+            y = landmark[2 * i + 1]
+            img.draw_rectangle(x-2,y-2, x+2,y+2,color= (193 ,255 ,193), thickness =-1)
+
+    def process(self,input):
+        loc_out = self.loc_model.forward(input, quantize=1, layout = "chw") # retinaface decoder only support chw layout
+        boxes , landmarks = self.loc_decoder.run(loc_out, nms = 0.2 ,score_thresh = 0.7 , outputs_shape =[[1,4,2058],[1,2,2058],[1,8,2058]])
+
+        for i,box in enumerate(boxes):
+
+            landmark = landmarks[i][:6]
+            reg_in  = input.crop_affine(landmark , 94 , 24)
+            reg_out = self.reg_model.forward(reg_in ,  quantize=1, layout = "chw")
+
+            LP_number = self.reg_decoder.run(reg_out)
+            string_LP = ''
+            for id in LP_number:
+                string_LP += self.chars[id]
+
+            self.draw_string(input , box[0], box[1] , string_LP  ,color=(225,0,0))
+            self.draw_paste(input , reg_in)
+            self.draw_rectangle(input,box)
+            self.draw_point(input , landmarks[i])
+def lcdRotation(inputImg,rotationAngle):
+    from maix import image
+    imageRotationBuffer = inputImg.crop(0, 0, 240, 320)
+    if ScreenOrientation:
+        imgRotationAim = image.new(size = (240, 320))
+    else:
+        imgRotationAim = image.new(size = (320, 240))
+    return imgRotationAim.draw_image(imageRotationBuffer.rotate(rotationAngle, adjust=1),0,0,alpha=1)
+
+if ScreenOrientation:
+    CAMERAROTATE = +180
+else:
+    CAMERAROTATE = +90
+def main():
+    from maix import display, camera , image
+    image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+    app  = LPR()
+    
+    canvasImg = image.new(size = (240, 320))
+    while True:
+        canvasImg.clear()
+        img = camera.capture().crop(0, 0,224, 224)
+        app.process(img)
+        canvasImg.draw_image(img,48,8)
+        canvasImg.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+        display.show(canvasImg)
+        # break
+main()

+ 66 - 0
preset/app/21_maskDetection.py

@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from time import time
+from maix import display, camera,image
+
+ScreenOrientation = False
+class Mask:
+    mud_path = "/root/preset/model/mask_int8.mud"
+    labels = ["no wear","wear"]
+    anchors = [1.19, 1.98, 2.79, 4.59, 4.53, 8.92, 8.06, 5.29, 10.32, 10.65]
+
+    def __init__(self) -> None:
+        from maix import nn
+        self.model = nn.load(self.mud_path)
+        from maix.nn import decoder
+        self.decoder = decoder.Yolo2(len(self.labels) , self.anchors , net_in_size = (224, 224) ,net_out_size = (7,7))
+
+    def __del__(self):
+        del self.model
+        del self.decoder
+
+    def cal_fps(self ,start , end):
+        one_second = 1
+        one_flash = end - start
+        fps = one_second / one_flash
+        return  fps
+
+    def draw_rectangle_with_title(self ,img, box, disp_str , fps ):
+        img.draw_rectangle(box[0], box[1], box[0] + box[2], box[1] + box[3],color=(255, 0, 0), thickness=2)
+        img.draw_string(box[0], box[1]+ box[3] ,disp_str, scale=1,color=(0, 0, 255), thickness=1)
+        img.draw_string(0, 0 ,'FPS :'+str(fps), scale=2 ,color=(0, 0, 255), thickness=1)
+
+    def process(self,input):
+        t =  time()
+        out = self.model.forward(input, quantize=1, layout = "hwc")
+        boxes, probs = self.decoder.run(out, nms=0.5, threshold=0.6, img_size=(224,224))
+        for i, box in enumerate(boxes):
+            class_id = probs[i][0]
+            prob = probs[i][1][class_id]
+            disp_str = "{}:{:.2f}%".format(self.labels[class_id], prob*100)
+            fps = self.cal_fps(t, time())
+            self.draw_rectangle_with_title(input, box, disp_str, fps)
+
+app = Mask()
+
+def lcdRotation(inputImg,rotationAngle):
+    from maix import image
+    imageRotationBuffer = inputImg.crop(0, 0, 240, 320)
+    if ScreenOrientation:
+        imgRotationAim = image.new(size = (240, 320))
+    else:
+        imgRotationAim = image.new(size = (320, 240))
+    return imgRotationAim.draw_image(imageRotationBuffer.rotate(rotationAngle, adjust=1),0,0,alpha=1)
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+if ScreenOrientation:
+    CAMERAROTATE = +180
+else:
+    CAMERAROTATE = +90
+canvasImg = image.new(size = (320, 240))
+while True:
+    img = camera.capture().crop(0, 0,224, 224)
+    app.process(img)
+    canvasImg.draw_image(img,48,8)
+    canvasImg.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+    display.show(canvasImg)

+ 76 - 0
preset/app/22_gestureRecognition.py

@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       en
+from time import time
+from maix import image
+
+ScreenOrientation = False
+
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+class Hand:
+    mud_path = "/root/preset/model/hand_int8.mud"
+    labels = ["0","1","2","3","4","5"]
+    anchors = [3.78, 5.81, 3.97, 3.98, 4.05, 4.98, 4.81, 5.41, 2.91, 4.53]
+
+    def __init__(self) -> None:
+        from maix import nn
+        self.model = nn.load(self.mud_path)
+        from maix.nn import decoder
+        self.decoder = decoder.Yolo2(len(self.labels) , self.anchors , net_in_size = (224, 224) ,net_out_size = (7,7))
+
+    def __del__(self):
+        del self.model
+        del self.decoder
+
+    def cal_fps(self ,start , end):
+        one_second = 1
+        one_flash = end - start
+        fps = one_second / one_flash
+        return  fps
+
+    def draw_rectangle_with_title(self ,img, box, disp_str , fps ):
+        img.draw_rectangle(box[0], box[1], box[0] + box[2], box[1] + box[3],color=(255, 0, 0), thickness=2)
+        img.draw_string(box[0], box[1]+ box[3] ,disp_str, scale=1,color=(0, 0, 255), thickness=2)
+        img.draw_string(0, 0 ,'FPS :'+str(fps), scale=2 ,color=(0, 0, 255), thickness=2)
+
+    def process(self,input):
+        t =  time()
+        out = self.model.forward(input, quantize=1, layout = "hwc")
+        boxes, probs = self.decoder.run(out, nms=0.5, threshold=0.6, img_size=(224,224))
+        for i, box in enumerate(boxes):
+            class_id = probs[i][0]
+            prob = probs[i][1][class_id]
+            disp_str = "{}:{:.2f}%".format(self.labels[class_id], prob*100)
+            fps = self.cal_fps(t, time())
+            self.draw_rectangle_with_title(input, box, disp_str, fps)
+
+
+
+def lcdRotation(inputImg,rotationAngle):
+    from maix import image
+    imageRotationBuffer = inputImg.crop(0, 0, 240, 320)
+    if ScreenOrientation:
+        imgRotationAim = image.new(size = (240, 320))
+    else:
+        imgRotationAim = image.new(size = (320, 240))
+    return imgRotationAim.draw_image(imageRotationBuffer.rotate(rotationAngle, adjust=1),0,0,alpha=1)
+
+if ScreenOrientation:
+    CAMERAROTATE = +180
+else:
+    CAMERAROTATE = +90
+
+
+def main():
+    from maix import display, camera,image
+    global Hand
+    app =  Hand()
+    canvasImg = image.new(size = (320, 240))
+    while True:
+        img = camera.capture().crop(0, 0,224, 224)
+        app.process(img)
+        canvasImg.draw_image(img,48,8)
+        canvasImg.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+        display.show(canvasImg)
+
+main()

+ 71 - 0
preset/app/23_fingerGuessing.py

@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from time import time
+from maix import image
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+ScreenOrientation = False
+class Mora:
+    mud_path = "/root/preset/model/mora_int8.mud"
+    labels = ["Scissors", "Stone" ,"Paper"]
+    anchors = [3.23, 3.25, 1.47, 1.55, 5.09, 5.33, 4.03, 4.28, 2.12, 2.56]
+
+    def __init__(self) -> None:
+        from maix import nn
+        self.model = nn.load(self.mud_path)
+        from maix.nn import decoder
+        self.decoder = decoder.Yolo2(len(self.labels) , self.anchors , net_in_size = (224, 224) ,net_out_size = (7,7))
+
+    def __del__(self):
+        del self.model
+        del self.decoder
+
+    def cal_fps(self ,start , end):
+        one_second = 1
+        one_flash = end - start
+        fps = one_second / one_flash
+        return  fps
+
+    def draw_rectangle_with_title(self ,img, box, disp_str , fps ):
+        img.draw_rectangle(box[0], box[1], box[0] + box[2], box[1] + box[3],color=(255, 0, 0), thickness=2)
+        img.draw_string(box[0], box[1] ,disp_str, scale=1,color=(222, 0, 3), thickness=2)
+        #img.draw_string(0, 0 ,'FPS :'+str(fps), scale=2 ,color=(0, 0, 255), thickness=2)
+
+    def process(self,input):
+        t =  time()
+        out = self.model.forward(input, quantize=1, layout = "hwc")
+        boxes, probs = self.decoder.run(out, nms=0.5, threshold=0.5, img_size=(224,224))
+        for i, box in enumerate(boxes):
+            class_id = probs[i][0]
+            prob = probs[i][1][class_id]
+            disp_str = "{}:{:.2f}%".format(self.labels[class_id], prob*100)
+            fps = self.cal_fps(t, time())
+            self.draw_rectangle_with_title(input, box, disp_str, fps)
+
+
+def lcdRotation(inputImg,rotationAngle):
+    from maix import image
+    imageRotationBuffer = inputImg.crop(0, 0, 240, 320)
+    if ScreenOrientation:
+        imgRotationAim = image.new(size = (240, 320))
+    else:
+        imgRotationAim = image.new(size = (320, 240))
+    return imgRotationAim.draw_image(imageRotationBuffer.rotate(rotationAngle, adjust=1),0,0,alpha=1)
+
+if ScreenOrientation:
+    CAMERAROTATE = +180
+else:
+    CAMERAROTATE = +90
+
+def main():
+    from maix import display, camera,image
+    app = Mora()
+    canvasImg = image.new(size = (320, 240))
+    while True:
+        img = camera.capture().crop(0, 0,224, 224)
+        app.process(img)
+        canvasImg.draw_image(img,48,8)
+        canvasImg.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+        display.show(canvasImg)
+
+main()

+ 189 - 0
preset/app/24_connectWiFi.py

@@ -0,0 +1,189 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from maix import camera, display, zbar, image
+import socket
+import os
+import sys
+sys.path.append('/root/')
+import http.client
+from CocoPi import BUTTON
+import time
+import ssl
+ssl._create_default_https_context = ssl._create_unverified_context
+
+key_A = BUTTON(14)
+key_B = BUTTON(8)
+key_C = BUTTON(13)
+key_D = BUTTON(7)
+ScreenOrientation = False
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+camera.camera.config(size=(320,240))
+def lcdRotation(inputImg,rotationAngle):
+    from maix import image
+    imageRotationBuffer = inputImg.crop(0, 0, 240, 320)
+    if ScreenOrientation:
+        imgRotationAim = image.new(size = (240, 320))
+    else:
+        imgRotationAim = image.new(size = (320, 240))
+    return imgRotationAim.draw_image(imageRotationBuffer.rotate(rotationAngle, adjust=1),0,0,alpha=1)
+
+def getPublicIp():
+    import requests
+    url = 'https://myip.ipip.net'
+    res = requests.get(url,verify=False).text.split(" ")
+    return res[1][3:]
+if ScreenOrientation:
+    CAMERAROTATE = +180
+else:
+    CAMERAROTATE = +90
+
+def getNetworkDate_noexit():
+    global getDateNum
+    try:
+        coon = http.client.HTTPConnection('www.baidu.com')
+        coon.request("GET","/")
+        r = coon.getresponse()
+        ts = r.getheader('date')
+        GMT_time = time.strptime(ts[5:25],"%d %b %Y %H:%M:%S")
+        BeiJing_time = time.localtime(time.mktime(GMT_time) + 8*60*60)
+        format_time = time.strftime("%Y-%m-%d %H:%M:%S",BeiJing_time)
+        command = "date -s "+"\"{}\"".format(format_time)
+        os.system(command)
+        getDateNum = 1
+        # sys.exit()
+    except:
+        pass
+
+def getWifiConnectState():
+    cmd = "wifi_get_connection_info_test 1"
+    res = os.popen(cmd).read()
+    wifiInfo = {}
+    if res.find('get connection infomation successfully!') != -1:
+        wifiInfo["state"]=True
+        wifiInfo["AP"] = res[res.find("Connected AP: ")+13:res.find("IP address: ")-1]
+        wifiInfo["IP"] = res[res.find("IP address: ")+12:res.find("frequency")-1]
+        wifiInfo["frequency"] = res[res.find("frequency: ")+10:res.find("RSSI")-1]
+        wifiInfo["RSSI"] = res[res.find("RSSI: ")+6:res.find("link_speed")-1]
+        wifiInfo["link_speed"] = res[res.find("link_speed: ")+10:res.find("IP address: ")-1]
+        wifiInfo["noise"] = res[res.find("noise: ")+6:res.find("noise: ")+11]
+    else:
+        wifiInfo["state"]=False
+        wifiInfo["AP"] = "N/A"
+        wifiInfo["IP"] = "N/A"
+        wifiInfo["frequency"] = "N/A"
+        wifiInfo["RSSI"] = "N/A"
+        wifiInfo["link_speed"] = "N/A"
+        wifiInfo["noise"] = "N/A"
+    return wifiInfo
+
+def getPrivateIp():
+    st = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
+    try:
+        st.connect(("10.255.255.255",1))
+        IP = st.getsockname()[0]
+    except Exception:
+        IP = "127.0.0.1"
+    finally:
+        st.close()
+    return IP
+
+ssidInfo = ""
+passwordInfo = ""
+checkConnectState = False
+connectText = ""
+startConnect=False
+wifiConnectState = False
+# PublicIp=""
+PrivateIP=""
+runConnectSig=True
+connectSuccessSig=False
+while True:
+    canvas = camera.capture()
+    IP = getPrivateIp()
+    if ssidInfo!="" and passwordInfo!="":
+        startConnect=True
+        #connectText = "Waitting for Connection..."
+        #canvas.draw_string(10,40, ssidInfo+" "+str(len(ssidInfo))+" "+str(type(ssidInfo)), scale = 1.5, color = (0,0,0), thickness = 1)
+        canvas.draw_string(10,50, "正在连接WIFI,请等待...", scale = 1.5, color = (0,0,0), thickness = 1)
+        display.show(canvas)
+    if startConnect==True:
+        canvas_1 = image.new(size = (320, 320), color = (255,255,255), mode = "RGB")
+        canvas.draw_image(canvas_1,0,0, alpha=0.4)
+        if wifiConnectState == True:
+            if key_B.is_pressed():
+                while (key_B.is_pressed() == True):
+                    time.sleep(0.001)
+                startConnect= False
+                connectText = ""
+                checkConnectState = False
+                connectSuccessSig = False
+                wifiConnectState = False
+                runConnectSig== True
+                ssidInfo=""
+                passwordInfo=""
+            if checkConnectState == True:
+                if connectSuccessSig == False:
+                    # PublicIp=getPublicIp()
+                    PrivateIP=getPrivateIp()
+                    connectSuccessSig = True
+                connectText = "WiFi连接成功!"
+                # canvas.draw_string(10,80, "路由器公网IP:" + PublicIp, scale = 1.5, color = (0,0,0), thickness = 1)
+                canvas.draw_string(10,80, "局域网IP:" + PrivateIP, scale = 1.5, color = (0,0,0), thickness = 1)
+                canvas.draw_image((image.open("/root/preset/img/restart_ff0000_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+                ssidInfo=""
+                passwordInfo=""
+            else:
+                pass
+        else:
+            if checkConnectState == False:
+                os.system("wifi_disconnect_ap_test")
+                os.system('wifi_connect_chinese_ap_test '+ssidInfo+' '+passwordInfo+'')
+                wifiConnectState=getWifiConnectState()["state"]
+                checkConnectState = True
+            if checkConnectState == True:
+                if key_B.is_pressed():
+                    while (key_B.is_pressed() == True):
+                        time.sleep(0.001)
+                    startConnect= False
+                    connectText = ""
+                    checkConnectState = False
+                    connectSuccessSig = False
+                    wifiConnectState = False
+                    runConnectSig== True
+                    passwordInfo = ""
+                    ssidInfo = ""
+                else:
+                    if runConnectSig== True:
+                        connectText = "正在连接WIFI,请等待..."
+                        runConnectSig= False
+                    else:
+                        passwordInfo = ""
+                        ssidInfo = ""
+                        connectText = "WIFI连接失败!"
+                        canvas.draw_image((image.open("/root/preset/img/restart_ff0000_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+                
+        
+        canvas.draw_string(10,50, connectText, scale = 1.5, color = (0,0,0) , thickness = 1)
+    else:
+        mks = canvas.find_qrcodes()
+        for mk in mks:
+            #外框数据
+            X = mk['x']
+            Y = mk['y']
+            W = mk['w']
+            H = mk['h']            
+            #二维码信息
+            string = mk['payload']
+            codeData = string.split(";")
+            ssidInfo = codeData[0].split(":")[1]
+            passwordInfo = codeData[1].split(":")[1]
+            #画外框
+            canvas.draw_rectangle(X, Y, X + W, Y + H, color=(0, 0, 255), thickness = 2) 
+            #打印信息
+            canvas.draw_string(int(X) , int(Y - 45) , "WIFI名:"+ssidInfo, scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+            canvas.draw_string(int(X) , int(Y - 25) , "密码:"+passwordInfo, scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+    canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+    #canvas.draw_image((image.open("/root/preset/img/camera_bfbfbf_24x24.png")).rotate(0, adjust=0),292,2,alpha=1)
+    display.show(canvas)
+    

+ 220 - 0
preset/app/25_aboutCocoPi.py

@@ -0,0 +1,220 @@
+#!/usr/bin/env python
+#version    :       2024.03.13
+#language   :       ch
+from maix import *
+import socket
+import os
+import sys
+sys.path.append('/root/')
+import http.client
+from CocoPi import BUTTON
+import time
+
+key_A = BUTTON(14)
+key_B = BUTTON(8)
+key_C = BUTTON(13)
+key_D = BUTTON(7)
+#image.load_freetype("/root/preset/fonts/JetBrainsMono-Bold-7.ttf")
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+
+def getWifiConnectState():
+    cmd = "wifi_get_connection_info_test 1"
+    res = os.popen(cmd).read()
+    wifiInfo = {}
+    if res.find('get connection infomation successfully!') != -1:
+        wifiInfo["state"]=True
+        wifiInfo["AP"] = res[res.find("Connected AP: ")+13:res.find("IP address: ")-1]
+        wifiInfo["IP"] = res[res.find("IP address: ")+12:res.find("frequency")-1]
+        wifiInfo["frequency"] = res[res.find("frequency: ")+10:res.find("RSSI")-1]
+        wifiInfo["RSSI"] = res[res.find("RSSI: ")+6:res.find("link_speed")-1]
+        wifiInfo["link_speed"] = res[res.find("link_speed: ")+10:res.find("IP address: ")-1]
+        wifiInfo["noise"] = res[res.find("noise: ")+6:res.find("noise: ")+11]
+    else:
+        wifiInfo["state"]=False
+        wifiInfo["AP"] = "N/A"
+        wifiInfo["IP"] = "N/A"
+        wifiInfo["frequency"] = "N/A"
+        wifiInfo["RSSI"] = "N/A"
+        wifiInfo["link_speed"] = "N/A"
+        wifiInfo["noise"] = "N/A"
+    return wifiInfo
+
+def getPrivateIp():
+    st = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
+    try:
+        st.connect(("10.255.255.255",1))
+        IP = st.getsockname()[0]
+    except Exception:
+        IP = "127.0.0.1"
+    finally:
+        st.close()
+    return IP
+
+def getPublicIp():
+    import requests
+    url = 'https://myip.ipip.net'
+    res = requests.get(url).text.split(" ")
+    return res[1][3:]
+
+PublicIp=""
+PrivateIP=""
+
+baseInfo=[
+        "--------------------------------------",
+        "     --- 设计 --- 创造 --- 分享 ---",
+        "--------------------------------------",
+        "                       系统信息         ",
+        "***************************",
+        "系统名称:          CocoPi Linux",
+        "系统版本:              2024.01.01A",
+        "--------------------------------------",
+        "  用户名:                ",
+        "--------------------------------------",
+        "          网络信息         ",
+        "***************************",
+        " ",
+        " ",
+        " ",
+        " ",
+        "--------------------------------------",
+        "Python 版本                        3.8.5",
+        "***************************",
+        "Python 包信息                 版本号",
+        "***************************",
+        "av                                                9.2.0",
+        "beautifulsoup4                4.11.1",
+        "certifi                              2020.6.20",
+        "cffi                                            1.14.3",
+        "chardet                                    3.0.4",
+        "click                                           7.1.2",
+        "defusedxml                           0.6.0",
+        "et-xmlfile                                1.0.1",
+        "evdev                                        1.4.0",
+        "Flask                                         1.1.2",
+        "Flask-Login                           0.5.0",
+        "gpiod                                        1.4.0",
+        "html5lib                                      1.1",
+        "idna                                            2.10",
+        "itsdangerous                        1.1.0",
+        "jdcal                                          1.4.1",
+        "jieba                                       0.42.1",
+        "Jinja2                                    2.11.2",
+        "lxml                                           4.5.2",
+        "maixpy3                                  0.5.4",
+        "MarkupSafe                           1.1.1",
+        "numpy                                   1.19.2",
+        "openpyxl                                 3.0.5",
+        "Pillow                                        7.2.0",
+        "pip                                           20.1.1",
+        "plumbum                               1.6.9",
+        "ply                                                3.11",
+        "pyasn1                                     0.4.8",
+        "PyAudio                                0.2.11",
+        "pycparser                                 2.20",
+        "pylibmodbus                        0.5.0",
+        "pyserial                                        3.4",
+        "qrcode                                          6.1",
+        "requests                               2.24.0",
+        "rpyc                                            5.0.1",
+        "rsa                                                  4.6",
+        "schedule                                0.6.0",
+        "setuptools                           47.1.0",
+        "six                                            1.15.0",
+        "smbus2                                   0.4.2",
+        "soupsieve                               2.3.1",
+        "spidev                                           3.5",
+        "SQLAlchemy                       1.3.18",
+        "urllib3                                  1.25.10",
+        "websocket-client                1.5.1",
+        "Werkzeug                                1.0.1",
+        "zbarlight                                      3.0",
+        "--------------------------------------",
+    ]
+
+ownerName=""
+try:
+    with open( '/root/user/text/owner.txt', 'r' ) as f:
+        ownerName=f.read()
+except:
+    ownerName="N/A"
+baseInfo[8]="{: <28}".format("用户名:     "+ownerName)
+canvas = image.new(size=(320, 240),color = (15,21,46),mode = "RGB")
+canvas.draw_string(12 , 100 , "检查WIFI连接状态...", scale = 1, color = (255,255,255), thickness = 2)
+display.show(canvas)
+checkInternet=False
+try:
+    if getWifiConnectState()["state"]==True:
+        PublicIp=getPublicIp()
+        PrivateIP=getPrivateIp()
+        baseInfo[12]="{: <28}".format("路由器公网IP:"+PublicIp)
+        baseInfo[13]="{: <28}".format("局域网IP:"+PrivateIP)
+        baseInfo[14]="{: <28}".format("WIFI热点名:"+getWifiConnectState()["AP"])
+        baseInfo[15]="{: <28}".format("WIFI信号强度:"+getWifiConnectState()["RSSI"])
+    else:
+        PublicIp="N/A"
+        PrivateIP="N/A"
+        baseInfo[12]="{: <28}".format("路由器公网IP:    N/A")
+        baseInfo[13]="{: <28}".format("局域网IP:   N/A")
+        baseInfo[14]="{: <28}".format("WIFI热点名:    N/A")
+        baseInfo[15]="{: <28}".format("WIFI RSSI:   N/A")
+except:
+    PublicIp="N/A"
+    PrivateIP="N/A"
+    baseInfo[12]="{: <28}".format("路由器公网IP:    N/A")
+    baseInfo[13]="{: <28}".format("局域网IP:   N/A")
+    baseInfo[14]="{: <28}".format("WIFI热点名:    N/A")
+    baseInfo[15]="{: <28}".format("WIFI信号强度:   N/A")
+    pass
+
+xPosition=48
+yPosition=160
+ySpeedMax=12
+yDirection=0
+yRealSpeed=0
+totalNum=0
+while True:
+    canvas.clear()
+    canvas = image.new(size=(320, 240),color = (15,21,46),mode = "RGB")
+    if key_D.is_pressed():
+        yDirection=-1
+    elif key_B.is_pressed():
+        yDirection=1
+    else:
+        yDirection=0
+    if yDirection==1:
+        if yRealSpeed<(ySpeedMax*yDirection):
+            yRealSpeed=yRealSpeed+1
+        else:
+            yRealSpeed=yRealSpeed
+    elif yDirection==-1:
+        if yRealSpeed>(ySpeedMax*yDirection):
+            yRealSpeed=yRealSpeed-1
+        else:
+            yRealSpeed=yRealSpeed
+    else:
+        if yRealSpeed>0:
+            yRealSpeed=yRealSpeed-1
+        elif yRealSpeed<0:
+            yRealSpeed=yRealSpeed+1
+        else:
+            yRealSpeed=0
+    yPosition=yPosition+yRealSpeed
+    if yPosition>160:
+        yPosition=160
+    elif yPosition<-900:
+        yPosition=-900
+    else:
+        yPosition=yPosition
+    #canvas.draw_string(60 , 8 , "yPosition:"+str(yPosition)+"yRealSpeed:"+str(yRealSpeed), scale = 1, color = (255,255,255), thickness = 1)
+    canvas.draw_image(image.open("/root/preset/img/cocorobo_152146.png"),xPosition+40 , yPosition-144,alpha=1)
+    canvas.draw_image(image.open("/root/preset/img/cocorobo_text.jpg"),xPosition+32 , yPosition-20,alpha=1)
+
+    for i in range(len(baseInfo)):
+        if  (yPosition+(i)*16)<260 and (yPosition+(i)*16)>-20:
+            canvas.draw_string(xPosition , yPosition+i*16 , baseInfo[i], scale = 1, color = (255,255,255), thickness = 1)
+        else:
+            pass
+    canvas.draw_image((image.open("/root/preset/img/left_ffffff_16x16.png")).rotate(90, adjust=0),6,6,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/left_ffffff_16x16.png")).rotate(270, adjust=0),6,216,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+    display.show(canvas)

+ 101 - 0
preset/app/26_internetCamera.py

@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       pi
+from maix import image     #引入python模块包
+from maix import camera, mjpg, utils, display
+import time
+import qrcode
+import sys
+import os
+import socket
+sys.path.append('/root/')
+from CocoPi import BUTTON
+
+def getWifiConnectState():
+    wifiConnectState=False
+    cmd = "wifi_get_connection_info_test 1"
+    res = os.popen(cmd).read()
+    if res.find('get connection infomation successfully!') != -1:
+        wifiConnectState = True
+    else:
+        wifiConnectState = False
+    return wifiConnectState
+
+def getPrivateIp():
+    st = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
+    try:
+        st.connect(("10.255.255.255",1))
+        IP = st.getsockname()[0]
+    except Exception:
+        IP = "127.0.0.1"
+    finally:
+        st.close()
+    return IP
+
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+PrivateIP=""
+canvas = image.new(size=(320, 240),color = (15,21,46),mode = "RGB")
+canvas.draw_string(8 , 100 , "检查网络连接状态...", scale = 1, color = (255,255,255), thickness = 1)
+display.show(canvas)
+wirelessTransmitPath=" "
+
+try:
+    if getWifiConnectState()==True:
+        PrivateIP=getPrivateIp()
+        pathHead="http://"
+        pathTail=":18811"
+        wirelessTransmitPath=pathHead+PrivateIP+pathTail
+    else:
+        PrivateIP="N/A"
+        wirelessTransmitPath="请先连接网络"
+except:
+    wirelessTransmitPath="请先连接网络"
+    pass
+
+os.system("rm /root/user/img/wirelessPictureTransmit.jpg")
+qrcode.make(wirelessTransmitPath).save("/root/user/img/wirelessPictureTransmit.jpg")
+
+
+key_A = BUTTON(14)
+key_B = BUTTON(8)
+key_C = BUTTON(13)
+key_D = BUTTON(7)
+
+buttonState=0
+newState=0
+oldState=0
+def buttonDetect():
+    global buttonState,newState,oldState
+    newState=key_C.is_pressed()
+    if newState == True and oldState == False:
+        buttonState=1
+    elif newState == False and oldState == True:
+        buttonState=2
+    else:
+        buttonState=0
+    oldState=newState
+
+queue = mjpg.Queue(maxsize=8)
+mjpg.MjpgServerThread(
+    "0.0.0.0", 18811, mjpg.BytesImageHandlerFactory(q=queue)).start()
+
+
+
+camera.camera.config(size=(320, 240))
+qrShowState=0
+while True:
+    buttonDetect()
+    
+    img_backdrop = image.new(size=(320,240),color=(0, 0, 0))    #创建背景画布
+    camera_img = camera.capture()    #从摄像头中获取一张图像
+    camera_img_capture = camera_img.crop(0, 0, 320, 240)        #截取图像
+    jpg = utils.rgb2jpg(camera_img.convert("RGB").tobytes(), 320, 240)
+    queue.put(mjpg.BytesImage(jpg))
+    img_backdrop.draw_image(camera_img)
+    if buttonState==2:
+        qrShowState=1-qrShowState
+    if qrShowState==1:
+        img_backdrop.draw_image(image.open("/root/user/img/wirelessPictureTransmit.jpg").resize(260,260), 30, -10,alpha=0.8)
+    img_backdrop.draw_image((image.open("/root/preset/img/qrcode_3c83f0_24x24.png")).rotate(0, adjust=0),288,6,alpha=1)
+    img_backdrop.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+    display.show(img_backdrop)         #将图像显示出来

+ 70 - 0
preset/app/27_internetWeatherPrediction.py

@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from maix import display
+from maix import image
+from maix import camera
+import bs4
+import ssl
+import json
+ssl._create_default_https_context = ssl._create_unverified_context
+import http.client
+camera.camera.config(size=(320,240))
+
+ScreenOrientation = False
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+
+def get_content(city):
+    weather_list = []
+    try:        
+        conn = http.client.HTTPSConnection("weather.visualcrossing.com")
+        conn.request("GET", "/VisualCrossingWebServices/rest/services/timeline/"+city+"?unitGroup=us&include=days&key=XGMGVZSNH3RFJWNQYL4Z5THYS&contentType=json")
+        res = conn.getresponse()
+        data = res.read().decode("utf-8")
+        # print(json.loads(data)["days"],'1111111111111111111')
+        for i in json.loads(data)["days"]:
+            # print(i)
+            weather_list.extend([{"D":i["datetime"],"W":i["conditions"],
+            "T":str(round((i["tempmax"]-32)/1.8))+"/"+str(round((i["tempmin"]-32)/1.8))+"℃"}])
+    # weather_list = data.decode("utf-8")["days"]
+    except:
+        print('no result')
+    # with open("/root/wResult.txt","w") as f:
+    #     f.write(data.decode("utf-8"))
+    # print(weather_list)
+    return weather_list
+
+# https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/weatherdata/forecast?locations=Herndon,VA,20170&aggregateHours=24&unitGroup=us&shortColumnNames=false&contentType=csv&key=YOURAPIKEY
+
+canvas = image.new(size=(320, 240),color = (15,21,46),mode = "RGB")
+canvas.draw_string(4 , 100 , "正在检查网络连接状态...", scale = 1, color = (255,255,255), thickness = 2)
+display.show(canvas)
+weather_all1 = get_content('shenzhen')
+weather_all2 = get_content('HongKong')
+weather_all3 = get_content('Macau')
+weather_all4 = get_content('Guangzhou')
+while True:
+    canvas.clear()
+    try:
+        canvas = image.new(size=(320, 240),color = (15,21,46),mode = "RGB")
+        #canvas.draw_string(2,20, ("Day:"+str(weather_all1[0]["D"])), scale = 1, color = (255,255,255) , thickness = 1)
+        canvas.draw_string(2,20, ("气象变化:"+str(weather_all1[0]["W"])+"  ,温度:"+str(weather_all1[0]["T"]))[:-1]+"℃", scale = 1, color = (255,255,255) , thickness = 1)
+        canvas.draw_string(0,0, "深圳", scale = 1, color = (255,255,255) , thickness = 1)
+        canvas.draw_string(0,60, "香港", scale = 1, color = (255,255,255) , thickness = 1)
+        #canvas.draw_string(2,80, ("Day:"+str(weather_all2[0]["D"])), scale = 1, color = (255,255,255) , thickness = 1)
+        canvas.draw_string(2,80, ("气象变化:"+str(weather_all2[0]["W"])+"  ,温度:"+str(weather_all2[0]["T"]))[:-1]+"℃", scale = 1, color = (255,255,255) , thickness = 1)
+        canvas.draw_string(0,120, "澳门", scale = 1, color = (255,255,255) , thickness = 1)
+        #canvas.draw_string(2,140, ("Day:"+str(weather_all3[0]["D"])), scale = 1, color = (255,255,255) , thickness = 1)
+        canvas.draw_string(2,140, ("气象变化:"+str(weather_all3[0]["W"])+"  ,温度:"+str(weather_all3[0]["T"]))[:-1]+"℃", scale = 1, color = (255,255,255) , thickness = 1)
+        canvas.draw_string(0,180, "广州", scale = 1, color = (255,255,255) , thickness = 1)
+        #canvas.draw_string(2,200, ("Day:"+str(weather_all4[0]["D"])), scale = 1, color = (255,255,255) , thickness = 1)
+        canvas.draw_string(2,200, ("气象变化:"+str(weather_all4[0]["W"])+"  ,温度:"+str(weather_all4[0]["T"]))[:-1]+"℃",scale = 1, color = (255,255,255) , thickness = 1)
+    except:
+        canvas.draw_string(20,80, "获取天气信息失败!", scale = 1, color = (255,255,255) , thickness = 1)
+    if ScreenOrientation:
+        canvasVER = canvas.crop(0,0,240,320)
+        canvasVER = canvasVER.rotate(-90, adjust=1)
+        display.show(canvasVER)
+    else:
+        canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+        display.show(canvas)

+ 142 - 0
preset/app/28_internetTimeClock.py

@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+
+import os
+from maix import display
+
+from maix import image
+
+from maix import camera
+import sys
+sys.path.append('/root/')
+import time
+import http.client
+import json
+import requests
+import bs4
+from datetime import datetime
+from CocoPi import AHT20
+
+def getNetworkDate_noexit():
+    global getDateNum
+    try:
+        coon = http.client.HTTPConnection('www.baidu.com')
+        coon.request("GET","/")
+        r = coon.getresponse()
+        ts = r.getheader('date')
+        GMT_time = time.strptime(ts[5:25],"%d %b %Y %H:%M:%S")
+        BeiJing_time = time.localtime(time.mktime(GMT_time) + 8*60*60)
+        format_time = time.strftime("%Y-%m-%d %H:%M:%S",BeiJing_time)
+        command = "date -s "+"\"{}\"".format(format_time)
+        os.system(command)
+        getDateNum = 1
+        # sys.exit()
+    except:
+        pass
+
+camera.camera.config(size=(320,240))
+
+ScreenOrientation = False
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+
+def getNetworkDate():
+    try:
+        coon = http.client.HTTPConnection('www.baidu.com')
+        coon.request("GET","/")
+        r = coon.getresponse()
+        ts = r.getheader('date')
+        GMT_time = time.strptime(ts[5:25],"%d %b %Y %H:%M:%S")
+        BeiJing_time = time.localtime(time.mktime(GMT_time)+ 8*60*60)
+        format_time = time.strftime("%Y-%m-%d %H:%M:%S",BeiJing_time)
+        command = "date -s "+"\"{}\"".format(format_time)
+        os.system(command)
+        sys.exit()
+    except:
+        pass
+
+def get_html(url):
+    '''
+    封装请求
+    '''
+    headers = {
+        'User-Agent':
+        'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36',
+        'ContentType':
+        'text/html; charset=utf-8',
+        'Accept-Encoding':
+        'gzip, deflate, sdch',
+        'Accept-Language':
+        'zh-CN,zh;q=0.8',
+        'Connection':
+        'keep-alive',
+    }
+    try:
+        htmlcontet = requests.get(url, headers=headers, timeout=30)
+        htmlcontet.raise_for_status()
+        htmlcontet.encoding = 'utf-8'
+        return htmlcontet.text
+    except:
+        return " 请求失败 "
+
+def get_content(url):
+    '''
+    抓取页面天气数据
+    '''
+    weather_list = []
+    html = get_html(url)
+    soup = bs4.BeautifulSoup(html, 'lxml')
+    content_ul = soup.find('div', class_='t').find('ul', class_='clearfix').find_all('li')
+
+    for content in content_ul:
+        try:
+            weather = {}
+            weather['day'] = content.find('h1').text
+            weather['temperature'] = content.find(
+                'p', class_='tem').span.text + content.find(
+                    'p', class_='tem').em.text
+            weather_list.append(weather)
+        except:
+            print('查询不到')
+    print(weather_list)
+    return weather_list
+
+def getCurrent_data(type):
+    now = datetime.now()
+    return now.strftime("%"+type+"")
+
+aht20 = AHT20(2)
+
+def screenShow(inputImg,rotationAngle):
+    #global img_drop
+
+    if rotationAngle==90 or rotationAngle == 270:
+        screenCapture=inputImg.crop(0,0,240,320)
+    else:
+        screenCapture=inputImg.crop(0,0,320,240)
+    canvas_screenShow = screenCapture.rotate(-rotationAngle,adjust=1)
+    display.show(canvas_screenShow)
+
+
+canvas = image.new(size=(320, 240),color = (15,21,46),mode = "RGB")
+canvas.draw_string(8 , 100 , "正在检查网络连接状态...", scale = 1, color = (209,72,54), thickness = 1)
+display.show(canvas)
+
+#os.system("wifi_disconnect_ap_test")
+#os.system('wifi_connect_chinese_ap_test "CocoRobo_SZ" "cocorobo2019"')
+#CLIENT = ntplib.NTPClient()
+#RESPONSE = CLIENT.request('127.0.0.1')
+getNetworkDate_noexit()
+canvas = image.new(size = (320, 240))
+getNetworkDate()
+weather = get_content('http://www.weather.com.cn/weather1d/101280601.shtml')
+image.load_freetype("/root/preset/fonts/DigitalNumbers-Regular.ttf")
+while True:
+    time.sleep(1)
+    canvas.clear()
+    canvas.draw_string(10,10, (''.join([str(x) for x in [getCurrent_data("Y"), "-", getCurrent_data("m"), "-", getCurrent_data("d"), " "]])), scale = 2, color = (111,195,223) , thickness = 1)
+    canvas.draw_string(25,85, (''.join([str(x) for x in [getCurrent_data("H"), "-", getCurrent_data("M"), "-", getCurrent_data("S")]])), scale = 3, color = (111,195,223) , thickness = 1)
+    canvas.draw_string(190,190, str((str(int((aht20.get_humidity()))))) + str("%RH"), scale = 2, color = (111,195,223) , thickness = 1)
+    canvas.draw_string(30,190, (str(weather[1].get("temperature"))), scale = 2, color = (111,195,223) , thickness = 1)
+    screenShow(canvas,0)
+

+ 53 - 0
preset/app/29_environmentDetection.py

@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+import sys
+import time
+from maix import display,image,camera
+sys.path.append('/root/')
+from CocoPi import AHT20
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+
+class v83x_ADC():
+    def __init__(self, addr=b"0x05070080") -> None:
+        self.addr = addr
+        self.path = "/sys/class/sunxi_dump/dump"
+        self.file = open(self.path, "wb+")
+        self.last = self.value()
+    def __del__(self):
+        try:
+            if self.file:
+                self.file.close()
+                del self.file
+        except Exception as e:
+            pass
+    def value(self):
+        self.file.write(b"0x05070080")
+        self.file.seek(0)
+        return int(self.file.read()[:-1], 16)
+
+v831_adc0 = v83x_ADC()
+
+aht20 = AHT20(2)    #创建温湿度传感器对象
+def aht20Test():
+    global aht20,img_backdrop
+    from maix import display
+    h=round(aht20.get_humidity(),2)+10.00
+    t=round(aht20.get_temperature()-15,2)
+    img_backdrop.draw_string(16, 108, "原始湿度值:"+str(h)+"RH%", scale = 1.0,color = (0, 255, 0), thickness = 1)
+    img_backdrop.draw_string(16, 132, "原始温度值:"+str(t)+"℃", scale = 1.0,color = (0, 255, 0), thickness = 1)
+    
+
+
+camera.camera.config(size=(320, 240))
+img_backdrop = image.new(size=(320, 240),color = (15,21,46),mode = "RGB")
+
+while True:
+    img_backdrop.clear()
+    img_backdrop = image.new(size=(320, 240),color = (15,21,46),mode = "RGB")
+    aht20Test()
+    v=v831_adc0.value()
+    img_backdrop.draw_string(16, 84, "原始光照强度值:"+str(v), scale = 1.0,color = (0, 255, 0), thickness = 1)
+    img_backdrop.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+    display.show(img_backdrop)
+    time.sleep(0.5)

+ 286 - 0
preset/app/30_training_data_collect.py

@@ -0,0 +1,286 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+
+from maix import camera, display, zbar, image
+import socket
+import os
+import sys
+sys.path.append('/root/')
+import http.client
+from CocoPi import BUTTON
+import time
+import json
+import requests
+
+key_A = BUTTON(14)
+key_B = BUTTON(8)
+key_C = BUTTON(13)
+key_D = BUTTON(7)
+ScreenOrientation = False
+image.load_freetype("/root/preset/fonts/CascadiaCodePL-Italic.ttf")
+camera.camera.config(size=(320,240))
+
+if ScreenOrientation:
+    CAMERAROTATE = +180
+else:
+    CAMERAROTATE = +90
+
+def getWifiConnectState():
+    cmd = "wifi_get_connection_info_test 1"
+    res = os.popen(cmd).read()
+    wifiInfo = {}
+    if res.find('get connection infomation successfully!') != -1:
+        wifiInfo["state"]=True
+        wifiInfo["AP"] = res[res.find("Connected AP: ")+13:res.find("IP address: ")-1]
+        wifiInfo["IP"] = res[res.find("IP address: ")+12:res.find("frequency")-1]
+        wifiInfo["frequency"] = res[res.find("frequency: ")+10:res.find("RSSI")-1]
+        wifiInfo["RSSI"] = res[res.find("RSSI: ")+6:res.find("link_speed")-1]
+        wifiInfo["link_speed"] = res[res.find("link_speed: ")+10:res.find("IP address: ")-1]
+        wifiInfo["noise"] = res[res.find("noise: ")+6:res.find("noise: ")+11]
+    else:
+        wifiInfo["state"]=False
+        wifiInfo["AP"] = "N/A"
+        wifiInfo["IP"] = "N/A"
+        wifiInfo["frequency"] = "N/A"
+        wifiInfo["RSSI"] = "N/A"
+        wifiInfo["link_speed"] = "N/A"
+        wifiInfo["noise"] = "N/A"
+    return wifiInfo
+
+name = ''
+host = ''
+isCollect = False
+image_num = 0
+save_path = ""
+startConnect=False
+
+def getWifiConnectState():
+    cmd = "wifi_get_connection_info_test 1"
+    res = os.popen(cmd).read()
+    wifiInfo = {}
+    if res.find('get connection infomation successfully!') != -1:
+        wifiInfo["state"]=True
+        wifiInfo["AP"] = res[res.find("Connected AP: ")+13:res.find("IP address: ")-1]
+        wifiInfo["IP"] = res[res.find("IP address: ")+12:res.find("frequency")-1]
+        wifiInfo["frequency"] = res[res.find("frequency: ")+10:res.find("RSSI")-1]
+        wifiInfo["RSSI"] = res[res.find("RSSI: ")+6:res.find("link_speed")-1]
+        wifiInfo["link_speed"] = res[res.find("link_speed: ")+10:res.find("IP address: ")-1]
+        wifiInfo["noise"] = res[res.find("noise: ")+6:res.find("noise: ")+11]
+    else:
+        wifiInfo["state"]=False
+        wifiInfo["AP"] = "N/A"
+        wifiInfo["IP"] = "N/A"
+        wifiInfo["frequency"] = "N/A"
+        wifiInfo["RSSI"] = "N/A"
+        wifiInfo["link_speed"] = "N/A"
+        wifiInfo["noise"] = "N/A"
+    return wifiInfo
+
+def getPrivateIp():
+    st = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
+    try:
+        st.connect(("10.255.255.255",1))
+        IP = st.getsockname()[0]
+    except Exception:
+        IP = "127.0.0.1"
+    finally:
+        st.close()
+    return IP
+
+ssidInfo = ""
+passwordInfo = ""
+checkConnectState = False
+connectText = ""
+startConnectWifi=False
+wifiConnectState = False
+# PublicIp=""
+PrivateIP=""
+runConnectSig=True
+connectSuccessSig=False
+while True:
+    canvas = camera.capture()
+    IP = getPrivateIp()
+    if ssidInfo!="" and passwordInfo!="":
+        startConnectWifi=True
+        #connectText = "Waitting for Connection..."
+        #canvas.draw_string(10,40, ssidInfo+" "+str(len(ssidInfo))+" "+str(type(ssidInfo)), scale = 1.5, color = (0,0,0), thickness = 1)
+        canvas.draw_string(10,50, "正在连接WIFI,请等待...", scale = 1.5, color = (0,0,0), thickness = 1)
+        display.show(canvas)
+    if startConnectWifi==True:
+        canvas_1 = image.new(size = (320, 320), color = (255,255,255), mode = "RGB")
+        canvas.draw_image(canvas_1,0,0, alpha=0.4)
+        if wifiConnectState == True:
+            if key_B.is_pressed():
+                while (key_B.is_pressed() == True):
+                    time.sleep(0.001)
+                startConnectWifi= False
+                connectText = ""
+                checkConnectState = False
+                connectSuccessSig = False
+                wifiConnectState = False
+                runConnectSig== True
+                ssidInfo=""
+                passwordInfo=""
+            if checkConnectState == True:
+                if connectSuccessSig == False:
+                    # PublicIp=getPublicIp()
+                    PrivateIP=getPrivateIp()
+                    connectSuccessSig = True
+                connectText = "WiFi连接成功!"
+                canvas.draw_string(10,50, "WiFi连接成功!", scale = 1.5, color = (0,0,0) , thickness = 1)
+                canvas.draw_string(10,80, "局域网IP:" + PrivateIP, scale = 1.5, color = (0,0,0), thickness = 1)
+                canvas.draw_image((image.open("/root/preset/img/restart_ff0000_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+                ssidInfo=""
+                passwordInfo=""
+                display.show(canvas)
+                time.sleep(3)
+                canvas.clear()
+                
+                break
+            else:
+                pass
+        else:
+            if checkConnectState == False:
+                os.system("wifi_disconnect_ap_test")
+                os.system('wifi_connect_chinese_ap_test '+ssidInfo+' '+passwordInfo+'')
+                wifiConnectState=getWifiConnectState()["state"]
+                checkConnectState = True
+            if checkConnectState == True:
+                if key_B.is_pressed():
+                    while (key_B.is_pressed() == True):
+                        time.sleep(0.001)
+                    startConnectWifi= False
+                    connectText = ""
+                    checkConnectState = False
+                    connectSuccessSig = False
+                    wifiConnectState = False
+                    runConnectSig== True
+                    passwordInfo = ""
+                    ssidInfo = ""
+                else:
+                    if runConnectSig== True:
+                        connectText = "正在连接WIFI,请等待..."
+                        runConnectSig= False
+                    else:
+                        passwordInfo = ""
+                        ssidInfo = ""
+                        connectText = "WIFI连接失败!"
+                        canvas.draw_image((image.open("/root/preset/img/restart_ff0000_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+                
+        
+        canvas.draw_string(10,50, connectText, scale = 1.5, color = (0,0,0) , thickness = 1)
+    else:
+        mks = canvas.find_qrcodes()
+        for mk in mks:
+            #外框数据
+            X = mk['x']
+            Y = mk['y']
+            W = mk['w']
+            H = mk['h']            
+            #二维码信息
+            string = mk['payload']
+            codeData = string.split(";")
+            ssidInfo = codeData[0].split(":")[1]
+            passwordInfo = codeData[1].split(":")[1]
+            #画外框
+            canvas.draw_rectangle(X, Y, X + W, Y + H, color=(0, 0, 255), thickness = 2) 
+            #打印信息
+            canvas.draw_string(int(X) , int(Y - 45) , "WIFI名:"+ssidInfo, scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+            canvas.draw_string(int(X) , int(Y - 25) , "密码:"+passwordInfo, scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+    canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+    #canvas.draw_image((image.open("/root/preset/img/camera_bfbfbf_24x24.png")).rotate(0, adjust=0),292,2,alpha=1)
+    display.show(canvas)
+  
+while True:
+    canvas.clear()
+    canvas = camera.capture()
+    # IP = extract_ip()
+    if str(name) != '' and str(host) != '':
+        startConnect=True
+    if startConnect==True:
+        _COCOCLOUD_SEND_ENDPOINT = "https://" + host.split("//")[1] + "v831_update_code_connect_device"
+        _COCOCLOUD_SEND_DATA = {"DatasetName":"" + str(name) + ""}
+        try:
+            _COCOCLOUD_SEND_REQUEST = requests.post(_COCOCLOUD_SEND_ENDPOINT, json = _COCOCLOUD_SEND_DATA , headers = { "Content-type": "application/json" }, timeout = 60)
+            print(str(_COCOCLOUD_SEND_REQUEST.status_code)+", "+str(_COCOCLOUD_SEND_REQUEST.content))
+        except BaseException as e:
+            print(e)
+        pass
+        isCollect = True
+        break
+    else:
+        mks = canvas.find_qrcodes()
+        for mk in mks:
+            #外框数据
+            X = mk['x']
+            Y = mk['y']
+            W = mk['w']
+            H = mk['h']            
+            #二维码信息
+            string = mk['payload']
+            
+            try:
+                codeData = string.split(";")
+                name = codeData[0].split("=")[1]
+                host = codeData[1].split("=")[1]
+            except:
+                pass
+            #画外框
+            canvas.draw_rectangle(X, Y, X + W, Y + H, color=(0, 0, 255), thickness = 2) 
+            #打印信息
+            canvas.draw_string(int(X) , int(Y - 35) , str(string), scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+
+    canvas.draw_string(0, 0 , "扫描二维码来访问图片标注服务器", scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+    canvas.draw_string(0, 20 , "", scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+    # canvas.draw_image((image.open("/root/preset/img/camera_ff0000_24x24.png")).rotate(0, adjust=0),290,2,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),290,208,alpha=1)
+        
+    display.show(canvas)
+
+isAlTake = False
+while True:
+    canvas1 = camera.capture()
+    if isCollect:
+        if not isAlTake:
+            if key_C.is_pressed() :
+                while not (key_C.is_pressed() == False):
+                    time.sleep(0.01)
+                image_num = image_num + 1
+                save_path = ''.join([str(x) for x in ["/root/user/img/image", str(image_num), ".jpg"]])
+                canvas1.save(save_path)
+                isAlTake = True
+            canvas1.draw_string(0, 0 , "请拍照来采集图片数据", scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+            canvas1.draw_image((image.open("/root/preset/img/camera_ff0000_24x24.png")).rotate(0, adjust=0),290,2,alpha=1)
+            canvas1.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),290,208,alpha=1)
+            display.show(canvas1)
+
+        if isAlTake:
+            canvas1.draw_image((image.open(save_path)),0,0)
+            # if key_D.is_pressed() :
+            #     while not (key_D.is_pressed() == False):
+            #         time.sleep(0.01)
+            #     img = open(save_path,'rb')
+            #     data = {"file": img}
+            #     param = {"name": str(name)}
+            #     res = requests.post("https://" + host.split("//")[1] + "v831_upload_image", files=data, data=param)
+            #     print(res.status_code)
+            #     if str(res.status_code) == "200":
+            #         isAlTake = False
+            # if key_C.is_pressed() :
+            #     while not (key_C.is_pressed() == False):
+            #         time.sleep(0.01)
+            #     isAlTake = False
+            img = open(save_path,'rb')
+            data = {"file": img}
+            param = {"name": str(name)}
+            res = requests.post("https://" + host.split("//")[1] + "v831_upload_image", files=data, data=param)
+            print(res.status_code)
+            if str(res.status_code) == "200":
+                isAlTake = False
+            # canvas1.draw_image((image.open("/root/preset/img/upload_ff0000_24x24.png")).rotate(0, adjust=0),5,2,alpha=1)
+            # canvas1.draw_image((image.open("/root/preset/img/cancel_ff0000_24x24.png")).rotate(0, adjust=0),280,2,alpha=1)
+            canvas1.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),290,208,alpha=1)
+            display.show(canvas1)
+
+    display.show(canvas1)

+ 262 - 0
preset/app/31_training_deploy_model.py

@@ -0,0 +1,262 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+
+from maix import camera, display, zbar, image
+import socket
+import os
+import sys
+sys.path.append('/root/')
+import http.client
+from CocoPi import BUTTON
+import time
+import json
+import requests
+
+key_A = BUTTON(14)
+key_B = BUTTON(8)
+key_C = BUTTON(13)
+key_D = BUTTON(7)
+ScreenOrientation = False
+image.load_freetype("/root/preset/fonts/CascadiaCodePL-Italic.ttf")
+camera.camera.config(size=(320,240))
+def getWifiConnectState():
+    cmd = "wifi_get_connection_info_test 1"
+    res = os.popen(cmd).read()
+    wifiInfo = {}
+    if res.find('get connection infomation successfully!') != -1:
+        wifiInfo["state"]=True
+        wifiInfo["AP"] = res[res.find("Connected AP: ")+13:res.find("IP address: ")-1]
+        wifiInfo["IP"] = res[res.find("IP address: ")+12:res.find("frequency")-1]
+        wifiInfo["frequency"] = res[res.find("frequency: ")+10:res.find("RSSI")-1]
+        wifiInfo["RSSI"] = res[res.find("RSSI: ")+6:res.find("link_speed")-1]
+        wifiInfo["link_speed"] = res[res.find("link_speed: ")+10:res.find("IP address: ")-1]
+        wifiInfo["noise"] = res[res.find("noise: ")+6:res.find("noise: ")+11]
+    else:
+        wifiInfo["state"]=False
+        wifiInfo["AP"] = "N/A"
+        wifiInfo["IP"] = "N/A"
+        wifiInfo["frequency"] = "N/A"
+        wifiInfo["RSSI"] = "N/A"
+        wifiInfo["link_speed"] = "N/A"
+        wifiInfo["noise"] = "N/A"
+    return wifiInfo
+  
+
+if ScreenOrientation:
+    CAMERAROTATE = +180
+else:
+    CAMERAROTATE = +90
+
+
+def urldownload(url,filepath=None,filename=None,canvas1=image.new(size = (320, 40))):
+    """
+    下载文件到指定目录
+    :param url: 文件下载的url
+    :param filename: 要存放的目录及文件名,例如:./test.xls
+    :return:
+    """
+    headers = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"}
+    down_res = requests.get(url,headers=headers,stream=True)
+    chunk_size = 1024 * 1024  # 单次请求最大值
+    content_size = int(down_res.headers['content-length'])  # 内容体总大小
+    data_count = 0
+    with open(filepath,'wb') as file:
+        for data in down_res.iter_content(chunk_size=chunk_size):
+            file.write(data)
+            data_count = data_count + len(data)
+            now_jd = (data_count / content_size) * 100
+            # print("\r 文件下载进度:%d%%(%d/%d) - %s" % (now_jd, data_count, content_size, filename), end=" ")
+            canvas1.clear()
+            canvas1.draw_string(0,0,str("下载中: ") + filename, scale = 1, color = (255, 0, 0), thickness = 2)
+            canvas1.draw_string(0,20 , str("进度: %d%%(%d/%d)" % (now_jd, data_count, content_size)), scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+            display.show(canvas1)
+            # time.sleep(1)
+
+    # return down_res.code
+
+
+canvas1 = image.new(size = (320, 40))
+
+startConnect=False
+param = ''
+bin = ''
+py = ''
+def getWifiConnectState():
+    cmd = "wifi_get_connection_info_test 1"
+    res = os.popen(cmd).read()
+    wifiInfo = {}
+    if res.find('get connection infomation successfully!') != -1:
+        wifiInfo["state"]=True
+        wifiInfo["AP"] = res[res.find("Connected AP: ")+13:res.find("IP address: ")-1]
+        wifiInfo["IP"] = res[res.find("IP address: ")+12:res.find("frequency")-1]
+        wifiInfo["frequency"] = res[res.find("frequency: ")+10:res.find("RSSI")-1]
+        wifiInfo["RSSI"] = res[res.find("RSSI: ")+6:res.find("link_speed")-1]
+        wifiInfo["link_speed"] = res[res.find("link_speed: ")+10:res.find("IP address: ")-1]
+        wifiInfo["noise"] = res[res.find("noise: ")+6:res.find("noise: ")+11]
+    else:
+        wifiInfo["state"]=False
+        wifiInfo["AP"] = "N/A"
+        wifiInfo["IP"] = "N/A"
+        wifiInfo["frequency"] = "N/A"
+        wifiInfo["RSSI"] = "N/A"
+        wifiInfo["link_speed"] = "N/A"
+        wifiInfo["noise"] = "N/A"
+    return wifiInfo
+
+def getPrivateIp():
+    st = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
+    try:
+        st.connect(("10.255.255.255",1))
+        IP = st.getsockname()[0]
+    except Exception:
+        IP = "127.0.0.1"
+    finally:
+        st.close()
+    return IP
+
+ssidInfo = ""
+passwordInfo = ""
+checkConnectState = False
+connectText = ""
+startConnectWifi=False
+wifiConnectState = False
+# PublicIp=""
+PrivateIP=""
+runConnectSig=True
+connectSuccessSig=False
+while True:
+    canvas = camera.capture()
+    IP = getPrivateIp()
+    if ssidInfo!="" and passwordInfo!="":
+        startConnectWifi=True
+        #connectText = "Waitting for Connection..."
+        #canvas.draw_string(10,40, ssidInfo+" "+str(len(ssidInfo))+" "+str(type(ssidInfo)), scale = 1.5, color = (0,0,0), thickness = 1)
+        canvas.draw_string(10,50, "正在连接WIFI...", scale = 1.5, color = (0,0,0), thickness = 1)
+        display.show(canvas)
+    if startConnectWifi==True:
+        canvas_1 = image.new(size = (320, 320), color = (255,255,255), mode = "RGB")
+        canvas.draw_image(canvas_1,0,0, alpha=0.4)
+        if wifiConnectState == True:
+            if key_B.is_pressed():
+                while (key_B.is_pressed() == True):
+                    time.sleep(0.001)
+                startConnectWifi= False
+                connectText = ""
+                checkConnectState = False
+                connectSuccessSig = False
+                wifiConnectState = False
+                runConnectSig== True
+                ssidInfo=""
+                passwordInfo=""
+            if checkConnectState == True:
+                if connectSuccessSig == False:
+                    # PublicIp=getPublicIp()
+                    PrivateIP=getPrivateIp()
+                    connectSuccessSig = True
+                connectText = "WiFi连接成功!"
+                canvas.draw_string(10,50, "WiFi连接成功!", scale = 1.5, color = (0,0,0) , thickness = 1)
+                canvas.draw_string(10,80, "局域网IP地址:" + PrivateIP, scale = 1.5, color = (0,0,0), thickness = 1)
+                canvas.draw_image((image.open("/root/preset/img/restart_ff0000_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+                ssidInfo=""
+                passwordInfo=""
+                display.show(canvas)
+                time.sleep(3)
+                canvas.clear()
+                break
+            else:
+                pass
+        else:
+            if checkConnectState == False:
+                os.system("wifi_disconnect_ap_test")
+                os.system('wifi_connect_chinese_ap_test '+ssidInfo+' '+passwordInfo+'')
+                wifiConnectState=getWifiConnectState()["state"]
+                checkConnectState = True
+            if checkConnectState == True:
+                if key_B.is_pressed():
+                    while (key_B.is_pressed() == True):
+                        time.sleep(0.001)
+                    startConnectWifi= False
+                    connectText = ""
+                    checkConnectState = False
+                    connectSuccessSig = False
+                    wifiConnectState = False
+                    runConnectSig== True
+                    passwordInfo = ""
+                    ssidInfo = ""
+                else:
+                    if runConnectSig== True:
+                        connectText = "正在连接WIFI..."
+                        runConnectSig= False
+                    else:
+                        passwordInfo = ""
+                        ssidInfo = ""
+                        connectText = "WiFi连接失败!"
+                        canvas.draw_image((image.open("/root/preset/img/restart_ff0000_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+                
+        
+        canvas.draw_string(10,50, connectText, scale = 1.5, color = (0,0,0) , thickness = 1)
+    else:
+        mks = canvas.find_qrcodes()
+        for mk in mks:
+            #外框数据
+            X = mk['x']
+            Y = mk['y']
+            W = mk['w']
+            H = mk['h']            
+            #二维码信息
+            string = mk['payload']
+            codeData = string.split(";")
+            ssidInfo = codeData[0].split(":")[1]
+            passwordInfo = codeData[1].split(":")[1]
+            #画外框
+            canvas.draw_rectangle(X, Y, X + W, Y + H, color=(0, 0, 255), thickness = 2) 
+            #打印信息
+            canvas.draw_string(int(X) , int(Y - 45) , "SSID:"+ssidInfo, scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+            canvas.draw_string(int(X) , int(Y - 25) , "PASSWORD:"+passwordInfo, scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+    canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+    #canvas.draw_image((image.open("/root/preset/img/camera_bfbfbf_24x24.png")).rotate(0, adjust=0),292,2,alpha=1)
+    display.show(canvas)
+    
+
+while True:
+    canvas = lcdRotation(camera.capture(),CAMERAROTATE)
+    # IP = extract_ip()
+    if(str(param) != '' and str(bin) != '' and str(py) != ''):
+        startConnect=True
+    if startConnect==True:
+        canvas.clear()
+        time.sleep(5)
+        urldownload("https://" + bin.split("//")[1],"/root/user/model/" + (str(bin).split("newModels/")[1].split("/")[0]) + ".bin",(str(bin).split("newModels/")[1].split("/")[0]) + ".bin",canvas1)
+        urldownload("https://" + param.split("//")[1],"/root/user/model/" + (str(param).split("newModels/")[1].split("/")[0]) + ".param", (str(param).split("newModels/")[1].split("/")[0]) + ".param",canvas1)
+        urldownload("https://" + py.split("//")[1],"/root/" + (str(py).split("newModels/")[1].split("/")[1]),"user_latest_code.py",canvas1)
+        break
+    else:
+        mks = canvas.find_qrcodes()
+        for mk in mks:
+            #外框数据
+            X = mk['x']
+            Y = mk['y']
+            W = mk['w']
+            H = mk['h']            
+            #二维码信息
+            try:
+                string = mk['payload']
+                codeData = json.loads(string)
+                param = codeData['param']
+                bin = codeData['bin']
+                py = codeData['py']
+            except:
+                pass
+        
+            #画外框
+            canvas.draw_rectangle(X, Y, X + W, Y + H, color=(0, 0, 255), thickness = 2) 
+            #打印信息
+            canvas.draw_string(int(X) , int(Y - 35) , str(string), scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+                
+    canvas.draw_string(0, 0 , "扫描二维码来下载模型", scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+    # canvas.draw_image((image.open("/root/preset/img/camera_ff0000_24x24.png")).rotate(0, adjust=0),280,2,alpha=1)
+    canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),290,208,alpha=1)
+    display.show(canvas)
+
+os.system("ln -sf %s /tmp/event && touch /tmp/start" % "/root/user_latest_code.py")

+ 230 - 0
preset/app/32_mnistModelTraining.py

@@ -0,0 +1,230 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+import time
+from maix import camera, display, image
+import os
+import sys
+sys.path.append('/root/')
+from CocoPi import BUTTON
+
+key_A = BUTTON(14)
+key_B = BUTTON(8)
+key_C = BUTTON(13)
+key_D = BUTTON(7)
+
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+
+import numpy as np
+
+def sigmoid(x):
+    return 1/(1+np.exp(-x))
+
+
+def grad(x):
+    return x*(1-x)
+
+
+class NeuralNetwork:
+    """
+    三层全连接前馈神经网络
+    """
+
+    def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate, active_function=sigmoid, gradient=grad, lambda_=0.1):
+        """
+
+        :param inputnodes: 输入层结点数
+        :param hiddennodes: 隐藏层节点数
+        :param outputnodes: 输出层节点数
+        :param learningrate: 学习率
+        :param active_function: 激活函数
+        :param gradient: 激活函数的导数
+        :param lambda_: L2正则化系数
+        """
+        self.inputnodes = inputnodes
+        self.hiddennodes = hiddennodes
+        self.outputnodes = outputnodes
+        self.learningrate = learningrate
+        self.active_function = active_function
+        self.gradient = gradient
+        self.lambda_ = lambda_
+
+        # 权值矩阵
+        self.weights_i_h = np.random.rand(
+            self.hiddennodes, self.inputnodes) - 0.5
+        self.weights_h_o = np.random.rand(
+            self.outputnodes, self.hiddennodes) - 0.5
+
+    def train_sgd(self, x, y):
+        """梯度下降训练"""
+        train_x = np.array(x).reshape(-1, 1)
+        target = np.zeros((self.outputnodes, 1)) + 0.01
+        target[y, 0] = 0.99
+
+        hiddeninputs = np.dot(self.weights_i_h, train_x)
+        hiddenoutputs = self.active_function(hiddeninputs)
+
+        outputinputs = np.dot(self.weights_h_o, hiddenoutputs)
+        final_outputs = self.active_function(outputinputs)
+
+        error = target - final_outputs
+
+        hidden_error = np.dot(self.weights_h_o.transpose(), error)
+
+        self.weights_h_o += self.learningrate * error * \
+            np.dot(self.gradient(final_outputs), hiddenoutputs.transpose())
+
+        self.weights_i_h += self.learningrate * hidden_error * \
+            np.dot(self.gradient(hiddenoutputs), train_x.transpose())
+
+    def fit(self, train_x, targets):
+        train_x = np.array(train_x)
+        for i in range(train_x.shape[0]):
+            self.train_sgd(train_x[i], targets[i])
+
+    def query(self, inputs, debug=False):
+        """单个值预测"""
+        inputs = np.array(inputs).reshape(-1, 1)
+        hidden_input = np.dot(self.weights_i_h, inputs)
+        hidden_output = self.active_function(hidden_input)
+
+        output_input = np.dot(self.weights_h_o, hidden_output)
+
+        final_output = self.active_function(output_input)
+
+        if debug:
+            print('predict: ', final_output)
+
+        return np.argmax(final_output)
+
+    def predict(self, inputs):
+        """批量预测"""
+        res = []
+        for x in inputs:
+            res.append(self.query(x))
+        return res
+
+    def __str__(self):
+        return "NeuralNetwork: \ninput_nodes = {0}, hidden_nodes = {1}, \noutputnodes = {2}, learningrate = {3}".format(
+            self.inputnodes, self.hiddennodes, self.outputnodes, self.learningrate
+        )
+
+
+test_df = np.loadtxt("/root/preset/training/res/mnist_test_10.csv", delimiter=",", dtype=str)
+test_df
+
+train_df = np.loadtxt("/root/preset/training/res/mnist_train_100.csv", delimiter=",", dtype=str)
+train_df
+
+# 用测试数据测试
+def accuracy(y_true, y_pred):
+    """准确度"""
+    y_true = np.array(y_true)
+    y_pred = np.array(y_pred)
+    return sum(y_true == y_pred)/y_true.shape[0]
+
+# 用全部数据进行训练
+
+
+def get_data():
+    # train_df = np.loadtxt("mnist_train.csv", delimiter=",", dtype=str)
+    # test_df = np.loadtxt("mnist_test.csv", delimiter=",", dtype=str)
+    global train_df, test_df
+    print(train_df.shape)
+    print(test_df.shape)
+
+    train_data = train_df.astype('int')
+    train_x = train_data[:, 1:]
+    train_y = train_data[:, 0]
+    train_x = train_x / 255 * 0.99 + 0.01
+
+    test_data = test_df.astype('int')
+    test_x = test_data[:, 1:]
+    test_y = test_data[:, 0]
+    test_x = test_x / 255 * 0.99 + 0.01
+
+    return train_x, train_y, test_x, test_y
+
+canvas = image.new(size=(320, 240),color = (15,21,46),mode = "RGB")
+#检查numpy.random模块是否已加载...
+canvas.draw_string(6, 8 , "Checking numpy module state...", scale = 1, color = (255,255,255), thickness = 2)
+display.show(canvas)
+if os.path.exists('/usr/lib/python3.8/site-packages/numpy/random/__init__.py'):
+    canvas.draw_string(6, 28 , "Numpy.random module have't been loaded ...", scale = 1, color = (255,255,255), thickness = 2)
+    display.show(canvas)
+    canvas.draw_string(6, 48 , "Loading numpy.random module...", scale = 1, color = (255,255,255), thickness = 2)
+    display.show(canvas)
+    os.system('rm -rf /usr/lib/python3.8/site-packages/numpy/random/__init__.py')
+    canvas.draw_string(6, 68 , "Loaded numpy.random module successfully!", scale = 1, color = (255,255,255), thickness = 2)
+    display.show(canvas)
+    canvas.draw_string(6, 88 , "The program will exit to complete configuration.", scale = 1, color = (255,255,255), thickness = 2)
+    display.show(canvas)
+    offTime=3
+    while offTime:
+        canvas.draw_rectangle(12, 108, 230, 127, color=(15,21,46),thickness=-1)
+        canvas.draw_string(6, 108 , "The program will exit in {} seconds.".format(offTime), scale = 1, color = (255,255,255), thickness = 2)
+        display.show(canvas)
+        time.sleep(1)
+        offTime=offTime-1
+else:
+    canvas.draw_string(6, 28 , "Numpy.random module have been loaded ...", scale = 1, color = (255,255,255), thickness = 2)
+    display.show(canvas)
+    #如果未加载,选择提示...
+    #如果已加载,显示Numpy已加载
+    canvas.draw_string(6, 48 , "Building neural network training services...", scale = 1, color = (255,255,255), thickness = 2)
+    display.show(canvas)
+    #构建神经网络训练服务
+    train_x, train_y, test_x, test_y = get_data()
+
+    NN = NeuralNetwork(784, 100, 10, 0.3)
+    NN.fit(train_x, train_y)
+    y_pred = NN.predict(test_x)
+    print("accuracy%.2f%%" % (100*accuracy(test_y, y_pred)))
+
+    hiddennodes = [512, 256, 128]
+    lrs = [0.1, 0.2, 0.3]
+    for node in hiddennodes:
+        for lr in lrs:
+            NN = NeuralNetwork(784, node, 10, lr)
+            NN.fit(train_x, train_y)
+            y_pred = NN.predict(test_x)
+            print("The number of hidden layer nodes%d,Learning rate%f,accuracy%.2f%%" %
+                  (node, lr, 100*accuracy(test_y, y_pred)))
+
+    import pickle
+    # 最佳参数
+    # 隐藏层节点数128,学习率0.100000,准确度70.00%
+    NN = NeuralNetwork(784, 128, 10, 0.1)
+    #开启神经网络训练,记录时长
+    # 训练10次,每3次训练下降一次学习率
+    canvas.draw_string(6, 68 , "Start NN training for 10 training iterations...", scale = 1, color = (255,255,255), thickness = 2)
+    display.show(canvas)
+    for e in range(1, 11):
+        if e % 3 == 0:
+            NN.learningrate /= 2
+        NN.fit(train_x, train_y)
+        y_pred = NN.predict(test_x)
+        #"第%d次训练,准确度%.2f%%"
+        #文件已保存至
+        canvas.draw_rectangle(6, 108, 319, 147, color=(15,21,46),thickness=-1)
+        canvas.draw_string(6, 108 , "The %dth training,accuracy:%.2f%%" % (e, 100*accuracy(test_y, y_pred)), scale = 1, color = (209,72,54), thickness = 2)
+        canvas.draw_string(6, 128 , 'Model file path:/root/user/model/NN{}.pkl'.format(e), scale = 1, color = (209,72,54), thickness = 2)
+        display.show(canvas)
+        print("The %d th training,accuracy%.2f%%" % (e, 100*accuracy(test_y, y_pred)))
+        with open('/root/user/model/NN{}.pkl'.format(e), 'wb') as f:  # 保存模型
+            pickle.dump(pickle.dumps(NN), f)
+    canvas.draw_string(6, 168 , "Model training completed!", scale = 1, color = (255,255,255), thickness = 2)
+    display.show(canvas)
+    os.system('touch /usr/lib/python3.8/site-packages/numpy/random/__init__.py')
+    canvas.draw_string(6, 188 , "Numpy.random module have been unloaded ...", scale = 1, color = (255,255,255), thickness = 2)
+    display.show(canvas)
+    #训练已完成,是否要关闭numpy.random模块?
+    #是,numpy.random模块已关闭,开机速度已优化
+    #否,numpy.ramdom模块将持续占用系统内存,开机时将需要更多时间
+    offTime=5
+    while offTime:
+        canvas.draw_rectangle(6, 208, 230, 227, color=(15,21,46),thickness=-1)
+        canvas.draw_string(6, 208 , "The program will exit in {}seconds.".format(offTime), scale = 1, color = (255,255,255), thickness = 2)
+        display.show(canvas)
+        time.sleep(1)
+        offTime=offTime-1

+ 138 - 0
preset/app/33_mnistCameraTest.py

@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from maix import camera
+from maix import display
+from maix import image
+from maix import nn
+from maix.nn import decoder
+import os
+import numpy as np
+
+def sigmoid(x):
+    return 1/(1+np.exp(-x))
+
+def grad(x):
+    return x*(1-x)
+
+class NeuralNetwork:
+    """
+    三层全连接前馈神经网络
+    """
+
+    def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate, active_function=sigmoid, gradient=grad, lambda_=0.1):
+        """
+
+        :param inputnodes: 输入层结点数
+        :param hiddennodes: 隐藏层节点数
+        :param outputnodes: 输出层节点数
+        :param learningrate: 学习率
+        :param active_function: 激活函数
+        :param gradient: 激活函数的导数
+        :param lambda_: L2正则化系数
+        """
+        self.inputnodes = inputnodes
+        self.hiddennodes = hiddennodes
+        self.outputnodes = outputnodes
+        self.learningrate = learningrate
+        self.active_function = active_function
+        self.gradient = gradient
+        self.lambda_ = lambda_
+
+        # 权值矩阵
+        self.weights_i_h = np.random.rand(self.hiddennodes, self.inputnodes) - 0.5
+        self.weights_h_o = np.random.rand(self.outputnodes, self.hiddennodes) - 0.5
+
+    def train_sgd(self, x, y):
+        """梯度下降训练"""
+        train_x = np.array(x).reshape(-1,1)
+        target = np.zeros((self.outputnodes,1)) + 0.01
+        target[y,0] = 0.99
+
+        hiddeninputs = np.dot(self.weights_i_h, train_x)
+        hiddenoutputs = self.active_function(hiddeninputs)
+
+        outputinputs = np.dot(self.weights_h_o, hiddenoutputs)
+        final_outputs = self.active_function(outputinputs)
+
+        error = target - final_outputs
+
+        hidden_error = np.dot(self.weights_h_o.transpose(), error)
+
+        self.weights_h_o += self.learningrate * error * np.dot(self.gradient(final_outputs), hiddenoutputs.transpose())
+
+        self.weights_i_h += self.learningrate * hidden_error * np.dot(self.gradient(hiddenoutputs), train_x.transpose())
+
+    def fit(self, train_x, targets):
+        train_x = np.array(train_x)
+        for i in range(train_x.shape[0]):
+            self.train_sgd(train_x[i], targets[i])
+
+    def query(self, inputs, debug=False):
+        """单个值预测"""
+        inputs = np.array(inputs).reshape(-1,1)
+        hidden_input = np.dot(self.weights_i_h, inputs)
+        hidden_output = self.active_function(hidden_input)
+
+        output_input = np.dot(self.weights_h_o, hidden_output)
+
+        final_output = self.active_function(output_input)
+
+        if debug:
+            print('predict: ', final_output)
+
+        return np.argmax(final_output)
+
+    def predict(self,inputs):
+        """批量预测"""
+        res = []
+        for x in inputs:
+            res.append(self.query(x))
+        return res
+
+    def __str__(self):
+        return "NeuralNetwork: \ninput_nodes = {0}, hidden_nodes = {1}, \noutputnodes = {2}, learningrate = {3}".format(
+            self.inputnodes, self.hiddennodes, self.outputnodes, self.learningrate
+        )
+
+image.load_freetype("/root/preset/fonts/CascadiaCodePL-Italic.ttf")
+
+import pickle
+
+if os.path.exists('/root/user/model/NN10.pkl'):
+    with open('/root/user/model/NN10.pkl','rb') as f:
+        b_data = pickle.load(f)
+        net_model = pickle.loads(b_data)
+else:
+    # 最佳模型,载入最佳模型
+    with open('/root/user/NN10.pkl','rb') as f:
+        b_data = pickle.load(f)
+        net_model = pickle.loads(b_data)
+print(net_model)
+
+camera.camera.config(size=(320, 240))
+img_path="/root/user/image_1.png"
+img_gray_path="/root/user/image_gray.png"
+while True:
+    img = camera.capture()                               #从摄像头中获取一张图像
+    mk = img.crop(0, 0, 240, 240)                        #裁剪图像为320*240
+    mk1=img.crop(0, 0, 240, 240).resize(224,224)        #继续裁剪图像为224*224
+    canvas= image.new(size = (320, 240), color = (0,255,0), mode = 'RGB')    #创建背景图
+    canvas.draw_image(mk1,58,8)        #贴224*224的图片
+    mk2=mk1.resize(28,28)                                #裁剪图片为28*28
+    canvas.draw_image(mk2,8,8)                            #贴28*28的图
+    mk2.save(img_path)
+    from PIL import Image
+    origin=Image.open(img_path).convert('L')                #转为8位分辨率灰度图(0~255)
+    origin.save(img_gray_path)
+    origin_gray=image.open(img_gray_path)
+    canvas.draw_image(origin_gray,8,48)
+    img = np.array(origin).reshape(1, 784).astype('int')
+    img = img / 255 * 0.99 + 0.01
+    print(img.shape)
+
+    tmp = net_model.query(img)
+    print(tmp)
+    if tmp:
+        canvas.draw_string(12,80, str(tmp), scale = 5, color = (255,0,0) , thickness = 1)
+    display.show(canvas)                                 #将图像显示出来

+ 231 - 0
preset/app/34_CocoGPT.py

@@ -0,0 +1,231 @@
+#!/usr/bin/env python
+#version    :       2024.08.08
+#language   :       en
+from maix import display
+from maix import image
+from maix import camera
+from maix import mjpg
+from maix import utils
+import base64
+import time
+import requests
+import json
+from evdev import InputDevice, categorize, ecodes
+import os
+import sys
+sys.path.append("/root/")
+sys.path.append("/root/preset/drivers/pylib/")
+from CocoPi import BUTTON
+
+camera.camera.config(size=(320,240))
+image.load_freetype("/root/preset/fonts/simhei.ttf")
+canvas = image.new(size = (320, 240))
+try:
+    # 获取键盘设备
+    keyboard = InputDevice('/dev/input/event1')  # 替换成实际的键盘设备路径
+except:
+    keyboard = ""
+
+if keyboard=="":
+    canvas.draw_string(0,12, "未检测到键盘", scale = 1.3, color = (255,255,255) , thickness = 1)
+    display.show(canvas)
+    time.sleep(3)
+    sys.exit()
+def v831_display_show_canvas(displayShow):
+    global _canvas_y,_canvas_x
+    CANVASSHOWIMGAGE = ""
+    if ScreenOrientation:
+        displayShowCanvas = image.new(size = (240, 320))
+        displayShowCanvas.draw_rectangle(0,0,240,320, color=(0,0,0), thickness=-1)
+        displayShowCanvas.draw_image(displayShow,_canvas_x,_canvas_y,alpha=1)
+        displayShowVER = displayShowCanvas.crop(0,0,240,320)
+        displayShowVER = displayShowVER.rotate(-90, adjust=1)
+        CANVASSHOWIMGAGE = displayShowVER
+        display.show(displayShowVER)
+    else:
+        displayShowCanvas = image.new(size = (320, 240))
+        displayShowCanvas.draw_rectangle(0,0,320,240, color=(0,0,0), thickness=-1)
+        displayShowCanvas.draw_image(displayShow,_canvas_x,_canvas_y,alpha=1)
+        CANVASSHOWIMGAGE = displayShowCanvas
+        display.show(displayShowCanvas)
+def get_post_chatgpt(datas):
+    global list_num
+    # 目标URL
+    url = "https://gpt.cocorobo.cn/askForTopic"
+    payload = json.dumps({"topic": datas})
+    headers={
+        "Content-Type":"application/json"
+    }
+    response=requests.request("POST", url, headers=headers, data=payload)
+    # try:
+    #     keyboardStr[list_num] = "result"
+    # except:
+    #     keyboardStr[list_num] = "fail"
+    #     pass
+    if response.status_code == 200:
+        # keyboardStr[list_num] = json.loads(response.text)["FunctionResponse"]["result"]
+        result_num = len(json.loads(response.text)["FunctionResponse"]["result"])//20
+        for i in range(result_num+1):
+            keyboardStr.append("")
+            keyboardStr[list_num] = json.loads(response.text)["FunctionResponse"]["result"][i*20:(i+1)*20]
+            list_num = list_num+1
+    else:
+        keyboardStr[list_num] = "fail"
+
+ScreenOrientation = False
+_canvas_x = 0
+_canvas_y = 0
+keyboardStr = ["请输入:",""]
+list_num = 1
+# 判断是否联网
+key_B = BUTTON(8)
+key_C = BUTTON(13)
+key_D = BUTTON(7)
+def wifi_is_content():
+    global getDateNum
+    cmd = "ifconfig"
+
+    res = os.popen(cmd).read()
+    data = False
+    if res.rfind("inet addr:")!=48:
+        data = True
+
+    return data
+if ScreenOrientation:
+    CAMERAROTATE = +180
+else:
+    CAMERAROTATE = +90
+
+ssidInfo = ""
+passwordInfo = ""
+checkConnectState = False
+connectText = ""
+startConnect=False
+wifiConnectState = False
+# PublicIp=""
+PrivateIP=""
+runConnectSig=True
+connectSuccessSig=False
+while True:
+    if wifi_is_content():
+        break
+    else:
+        canvas = camera.capture()
+        if ssidInfo!="" and passwordInfo!="":
+            startConnect=True
+            #connectText = "Waitting for Connection..."
+            #canvas.draw_string(10,40, ssidInfo+" "+str(len(ssidInfo))+" "+str(type(ssidInfo)), scale = 1.5, color = (0,0,0), thickness = 1)
+            canvas.draw_string(10,50, "正在连接WIFI,请等待...", scale = 1.5, color = (0,0,0), thickness = 1)
+            display.show(canvas)
+        if startConnect==True:
+            canvas_1 = image.new(size = (320, 320), color = (255,255,255), mode = "RGB")
+            canvas.draw_image(canvas_1,0,0, alpha=0.4)
+            if wifiConnectState == True:
+                if key_B.is_pressed():
+                    while (key_B.is_pressed() == True):
+                        time.sleep(0.001)
+                    startConnect= False
+                    connectText = ""
+                    checkConnectState = False
+                    connectSuccessSig = False
+                    wifiConnectState = False
+                    runConnectSig== True
+                    ssidInfo=""
+                    passwordInfo=""
+                if checkConnectState == True:
+                    if connectSuccessSig == False:
+                        # PublicIp=getPublicIp()
+                        connectSuccessSig = True
+                    connectText = "Wifi connection successfully!"
+                    # canvas.draw_string(10,80, "The WLAN PUBLIC IP:" + PublicIp, scale = 1.5, color = (0,0,0), thickness = 1)
+                    canvas.draw_string(10,110, "局域网IP:" + PrivateIP, scale = 1.5, color = (0,0,0), thickness = 1)
+                    # canvas.draw_image((image.open("/root/preset/img/restart_ff0000_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+                    ssidInfo=""
+                    passwordInfo=""
+                    canvas.clear()
+                    break
+                else:
+                    pass
+            else:
+                if checkConnectState == False:
+                    os.system("wifi_disconnect_ap_test")
+                    os.system('wifi_connect_chinese_ap_test '+ssidInfo+' '+passwordInfo+'')
+                    checkConnectState = True
+                if checkConnectState == True:
+                    if key_B.is_pressed():
+                        while (key_B.is_pressed() == True):
+                            time.sleep(0.001)
+                        startConnect= False
+                        connectText = ""
+                        checkConnectState = False
+                        connectSuccessSig = False
+                        wifiConnectState = False
+                        runConnectSig== True
+                        passwordInfo = ""
+                        ssidInfo = ""
+                    else:
+                        if runConnectSig== True:
+                            connectText = "正在连接WIFI,请等待..."
+                            runConnectSig= False
+                        else:
+                            passwordInfo = ""
+                            ssidInfo = ""
+                            connectText = "WIFI连接失败!"
+                            canvas.draw_image((image.open("/root/preset/img/restart_ff0000_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+                    
+            
+            canvas.draw_string(10,50, connectText, scale = 1.5, color = (0,0,0) , thickness = 1)
+        else:
+            mks = canvas.find_qrcodes()
+            for mk in mks:
+                #外框数据
+                X = mk['x']
+                Y = mk['y']
+                W = mk['w']
+                H = mk['h']            
+                #二维码信息
+                string = mk['payload']
+                codeData = string.split(";")
+                ssidInfo = codeData[0].split(":")[1]
+                passwordInfo = codeData[1].split(":")[1]
+                #画外框
+                canvas.draw_rectangle(X, Y, X + W, Y + H, color=(0, 0, 255), thickness = 2) 
+                #打印信息
+                canvas.draw_string(int(X) , int(Y - 45) , "WIFI名:"+ssidInfo, scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+                canvas.draw_string(int(X) , int(Y - 25) , "密码:"+passwordInfo, scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+        canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+        v831_display_show_canvas(canvas)
+# 键盘事件
+canvas.draw_string(0,0, str("请输入:"), scale = 1, color = (255,255,255) , thickness = 1)
+v831_display_show_canvas(canvas)
+for event in keyboard.read_loop():
+    if event.type == ecodes.EV_KEY:
+        key_event = categorize(event)
+        if key_event.keystate == key_event.key_down:
+            # print(keyboardStr,key_event.keycode[4:].lower())
+            if key_event.keycode[4:] == "SPACE":
+                keyboardStr[list_num] = keyboardStr[list_num] + " "
+            elif key_event.keycode[4:] == "BACKSPACE":
+                keyboardStr[list_num] = keyboardStr[list_num][:-1]
+                if len(keyboardStr[list_num]) ==0 and list_num>1:
+                    list_num = list_num - 1
+            elif key_event.keycode[4:] == "ENTER":
+                keyboardStr.append("")
+                list_num = list_num + 1
+                get_post_chatgpt(keyboardStr[list_num-1])
+            else:
+                keyboardStr[list_num] = keyboardStr[list_num] + key_event.keycode[4:].lower()
+            # print(list_num,keyboardStr)
+            if len(keyboardStr[list_num]) >40:
+                keyboardStr.append("")
+                list_num = list_num + 1
+            canvas.clear()
+            if list_num>16:
+                for i in range(list_num,list_num-16,-1):
+                    canvas.draw_string(0,15*(i-(list_num-15)), str(keyboardStr[i]), scale = 1, color = (255,255,255) , thickness = 1)
+            else:
+                for i in range(list_num+1):
+                    canvas.draw_string(0,15*i, str(keyboardStr[i]), scale = 1, color = (255,255,255) , thickness = 1)
+            canvas.draw_string(0,0, str("请输入:"), scale = 1, color = (255,255,255) , thickness = 1)
+            v831_display_show_canvas(canvas)
+

+ 216 - 0
preset/app/35_CocoTerminal.py

@@ -0,0 +1,216 @@
+#!/usr/bin/env python
+#version    :       2023.12.31
+#language   :       ch
+from evdev import InputDevice, categorize, ecodes
+import asyncio
+import pty
+import os
+import sys
+from maix import display
+from maix import image
+from maix import camera
+from maix import mjpg
+from maix import utils
+import base64
+import time
+import requests
+import json
+import threading
+
+camera.camera.config(size=(320,240))
+image.load_freetype("/root/preset/fonts/simhei.ttf")
+canvas = image.new(size = (320, 240))
+try:
+    # 获取键盘设备
+    keyboard = InputDevice('/dev/input/event1')  # 替换成实际的键盘设备路径
+except:
+    keyboard = ""
+
+if keyboard=="":
+    canvas.draw_string(0,12, "未检测到键盘", scale = 1.3, color = (255,255,255) , thickness = 1)
+    display.show(canvas)
+    time.sleep(3)
+    sys.exit()
+def v831_display_show_canvas(displayShow):
+    global _canvas_y,_canvas_x
+    CANVASSHOWIMGAGE = ""
+    if ScreenOrientation:
+        displayShowCanvas = image.new(size = (240, 320))
+        displayShowCanvas.draw_rectangle(0,0,240,320, color=(0,0,0), thickness=-1)
+        displayShowCanvas.draw_image(displayShow,_canvas_x,_canvas_y,alpha=1)
+        displayShowVER = displayShowCanvas.crop(0,0,240,320)
+        displayShowVER = displayShowVER.rotate(-90, adjust=1)
+        CANVASSHOWIMGAGE = displayShowVER
+        display.show(displayShowVER)
+    else:
+        displayShowCanvas = image.new(size = (320, 240))
+        displayShowCanvas.draw_rectangle(0,0,320,240, color=(0,0,0), thickness=-1)
+        displayShowCanvas.draw_image(displayShow,_canvas_x,_canvas_y,alpha=1)
+        CANVASSHOWIMGAGE = displayShowCanvas
+        display.show(displayShowCanvas)
+
+    # jpg = utils.rgb2jpg(CANVASSHOWIMGAGE.convert("RGB").tobytes(), CANVASSHOWIMGAGE.width, CANVASSHOWIMGAGE.height)
+    # img_base64 = base64.b64encode(jpg)
+    # img_base64_str = "data:image/jpg;base64," + str(img_base64)[2:-1]
+    # time.sleep(0.1)
+    # try:
+    #     if img_base64_str.rfind("data:image/jpg;base64,")>-1:
+    #         print(img_base64_str)
+    #     pass
+    # except Exception as e:
+    #     #print(str(e))
+    #     pass
+def get_post_chatgpt(datas):
+    # 目标URL
+    url = "https://gpt.cocorobo.cn/v831AskForTopic"
+    payload = json.dumps({"topic":datas})
+    headers={
+        'Content-Type':'application/json'
+    }
+    print("payload"+str(payload))
+    response=requests.request("POST",url,headers=headers,data=payload)
+    print("response.text",response.text)
+    if response.status_code == 200:
+        result_num = len(json.loads(response.text)["FunctionResponse"]["result"])
+        # keyboardStr[list_num] = 
+    else:
+        keyboardStr[list_num] = "fail"
+
+ScreenOrientation = False
+_canvas_x = 0
+_canvas_y = 0
+keyboardStr = [""]
+list_num = 0
+line = b""
+lines = []
+process =  None
+
+keyboard = InputDevice("/dev/input/event1")
+master, slave = pty.openpty()
+
+#等待控制台的输出
+def read_lines(master):
+    global lines, line,keyboardStr,list_num,isShow
+    char = os.read(master, 1)
+    if char == b"\n":
+        # lines.append(line.decode().strip())
+        lines.append(line.decode().rstrip())
+        line = b""
+    else:
+        line += char
+# 用来判断是不是终端有新的输出
+isShow = ""   
+# 输入字符串
+inputStr = "" 
+# 跟踪Ctrl键的状态
+ctrl_pressed = False
+#读取键盘事件写入
+def write_io():
+    global keyboardStr,list_num,isShow,inputStr,ctrl_pressed,lines
+    for event in keyboard.read_loop():
+        if event.type == ecodes.EV_KEY:
+            key_event = categorize(event)
+            if key_event.keystate == key_event.key_down:
+                try:
+                    input_command = ""
+                    if key_event.keycode == "KEY_LEFTCTRL" or key_event.keycode == "KEY_RIGHTCTRL":
+                        ctrl_pressed = True
+                    elif ctrl_pressed and key_event.keycode == "KEY_C":
+                        # print("Ctrl+C 组合键被按下")
+                        input_command = "\x1A\x03\x02\x03\x1D\x1A"
+                        # pass
+                    else:
+                        ctrl_pressed = False
+
+                    if ctrl_pressed == False:
+                        if key_event.keycode[4:] == "SPACE":
+                            inputStr = inputStr + " "
+                            input_command =  " "
+                            lines[len(lines)-1] = "root@CocoPi:/# "+inputStr
+                        elif key_event.keycode[4:] == "SLASH":
+                            inputStr = inputStr + "/"
+                            input_command =  "/"
+                            lines[len(lines)-1] = "root@CocoPi:/# "+inputStr
+                        elif key_event.keycode[4:] == "DOT":
+                            inputStr = inputStr + "."
+                            input_command =  "."
+                            lines[len(lines)-1] = "root@CocoPi:/# "+inputStr
+                        elif key_event.keycode[4:] == "MINUS":
+                            inputStr = inputStr + "_"
+                            input_command =  "_"
+                            lines[len(lines)-1] = "root@CocoPi:/# "+inputStr
+                        elif key_event.keycode[4:] == "BACKSPACE":
+                            inputStr = inputStr[:-1]
+                            input_command = ""
+                            lines[len(lines)-1] = "root@CocoPi:/# "+inputStr
+                            # if len(keyboardStr[list_num]) ==0 and list_num>0:
+                            #     list_num = list_num - 1
+                        elif key_event.keycode[4:] == "ENTER":
+                            inputStr = ""
+                            input_command = "\n"
+                            # time.sleep(1)
+                            # lines.append("root@CocoPi:/# ")
+                        else:
+                            input_command = key_event.keycode[4:].lower()
+                            inputStr = inputStr + key_event.keycode[4:].lower()
+                            # if list_num == len(lines):
+                            lines[len(lines)-1] = "root@CocoPi:/# "+inputStr
+                    print("\x1A\x03\x02\x03\x1D\x1A")
+                    print(input_command)
+                    os.write(master, input_command.encode())
+                except EOFError:
+                    break
+
+async def console_io():
+    global master, slave, process,list_num,keyboardStr,isShow
+    process = await asyncio.create_subprocess_exec('adb_shell', stdin=slave, stdout=slave, stderr=slave)
+
+    while True:
+        #读取所有的行数,放在lines
+        read_lines(master)
+        #屏幕循环的显示所有的数据
+        # print(lines)
+        #屏幕读取
+        if isShow.lower() != " ".join(lines).lower():
+            isShow = " ".join(lines)
+            showTreminal(1)
+            list_num = len(lines)
+        else:
+            pass
+
+    os.close(master)
+    os.close(slave)
+
+def showTreminal(val):
+    global master, slave, process,list_num,keyboardStr,lines,inputStr
+    for i,box in enumerate(lines):
+        if len(box)>0:
+            keyboardStr.append(box)   
+            # if box.rfind("root@CocoPi")>-1 and lines[i-1] == box:
+            #     pass
+            # else:
+            #     keyboardStr.append(box)   
+        elif i == len(lines)-1:
+            # lines.append("root@CocoPi:/# ")
+            keyboardStr.append("root@CocoPi:/# ")
+    
+    list_num = len(keyboardStr)-1
+    canvas.clear()
+    if len(keyboardStr)>20:
+        for i in range(len(keyboardStr)-1,len(keyboardStr)-20,-1):
+            canvas.draw_string(0,12*(i-(len(keyboardStr)-20)), str(keyboardStr[i]), scale = 0.785, color = (255,255,255) , thickness = 1)
+    else:
+        for i in range(len(keyboardStr)):
+            canvas.draw_string(0,12*i, str(keyboardStr[i]), scale = 0.785, color = (255,255,255) , thickness = 1)
+    v831_display_show_canvas(canvas)
+    # display.show(canvas)
+    
+def main():
+    thread = threading.Thread(target=write_io)
+    thread.start()
+    asyncio.run(console_io())
+    thread.join()
+
+
+main()
+

+ 309 - 0
preset/app/36_pictureAnalysis.py

@@ -0,0 +1,309 @@
+from maix import display
+from maix import image
+from maix import camera
+import pyaudio
+import wave
+import os
+from maix import mjpg
+from maix import utils
+import base64
+import time
+import requests
+import json
+import uuid
+import threading
+import socket
+import uuid
+import sys
+sys.path.append('/root/')
+from CocoPi import BUTTON
+
+key_B = BUTTON(8)
+key_C = BUTTON(13)
+key_D = BUTTON(7)
+camera.camera.config(size=(320,240))
+image.load_freetype("/root/preset/fonts/simhei.ttf")
+canvas = image.new(size = (320, 240))
+# 播放
+def voice_numberMap(value):
+    valueScaled = float(value - 0) / float(100)
+    return int(valueScaled * 31)
+
+VOICESTATE = 0
+
+VOICESTREAM = ""
+VOICEPYAUDIO = pyaudio.PyAudio()
+CHUNK = 1024
+
+VOICEPLAYSTATE = True
+VOICEWF = ""
+VOICEPPATH = ""
+
+VOICENUMP = str(voice_numberMap(100))
+time.sleep(0.01)
+SYSTEMVOICE = "amixer cset numid=8,iface=MIXER,name=\"LINEOUT volume\" "+ VOICENUMP+""
+def playVoice():
+    global VOICEPLAYSTATE
+    VOICEPLAYSTATE = True
+    VOICEPLAYSTATE = VoicePlayState()
+
+def VoicePlayState():
+    global VOICESTATE,VOICEDATA,CHUNK,VOICESTREAM,VOICEPYAUDIO,VOICEWF,VOICEPPATH
+    if VOICESTATE == 0:
+        VOICEWF = wave.open(VOICEPPATH, "rb")#(sys.argv[1], "rb"
+        VOICEPYAUDIO = pyaudio.PyAudio()
+
+        VOICESTREAM = VOICEPYAUDIO.open(format=VOICEPYAUDIO.get_format_from_width(VOICEWF.getsampwidth()),channels=VOICEWF.getnchannels(),rate=VOICEWF.getframerate(),output=True)
+
+        VOICEDATA = VOICEWF.readframes(CHUNK)
+        VOICESTATE = 1
+        return True
+    else:
+        if len(VOICEDATA) > 0:
+            try:
+                VOICESTREAM.write(VOICEDATA)
+                VOICEDATA = VOICEWF.readframes(CHUNK)
+                return True
+            except:
+                VOICESTATE = 0
+        else:
+            VOICESTREAM.stop_stream()
+            VOICESTREAM.close()
+            VOICEPYAUDIO.terminate()
+            VOICESTATE = 0
+            return False
+
+# 线程1
+def thread_calsss_fun1():
+    global isStateVoice
+    while True:
+        if isStateVoice==1:
+            getImage()
+        elif VOICEPPATH != "" and isStateVoice == 3: 
+            playVoice()
+
+# 关闭线程
+# CocoPiThread1.join()
+
+# 图片转base64
+def encode_image(image_path):
+    img_data = ""
+    try:
+        with open(image_path, "rb") as f:
+            img_data = f.read()
+    except:
+        pass
+    return str(base64.b64encode(img_data), "utf-8")
+
+def getImage():
+    global imgUrlStr,isStateVoice,cameraImgUrl,VOICEPPATH
+    uid = str(uuid.uuid1().hex)
+    strBase = encode_image(cameraImgUrl)
+    VOICEPPATH = ""
+    params = {
+        "max_tokens": 4096,
+        "messages":[
+            {
+                "role": "user",
+                "content":[
+                    {"text": "图片讲述了什么?","type": "text"},
+                    {"image_url": {"url": f"data:image/jpeg;base64,{strBase}"},"type": "image_url"}
+                ]
+            }
+        ],
+        "uid": uid,
+        "stream": False
+    }
+    headers={
+        "Content-Type":"application/json"
+    }
+    res = requests.post("https://gpt4.cocorobo.cn/imageAnalyse", headers=headers, data=json.dumps(params))
+    try:
+        if res.status_code == 200:
+            isStateVoice = 3
+            aa = json.loads(res.text)["FunctionResponse"]["choices"][0]["message"]["content"]
+            result_num = len(aa)//20
+            for i in range(result_num + 1):
+                imgUrlStr.append("")
+                imgUrlStr[i] = str(aa)[i*20:(i+1)*20]
+            
+            url = "https://gpt4.cocorobo.cn/getV831Audio"
+            payload = json.dumps({"input": aa,"response_format":"mp3","voice": "shimmer","uid":uid})
+            response=requests.request("POST", url, headers=headers, data=payload)
+            if response.status_code == 200:
+                # print(json.loads(response.text)["FunctionResponse"]["url"])
+                a = "https://gpt4.cocorobo.cn" + json.loads(response.text)["FunctionResponse"]["url"]
+                r = requests.get(a)
+                with open("/root/preset/audio/" + uid+".wav","wb") as f:
+                    f.write(r.content)
+                VOICEPPATH = "/root/preset/audio/" + uid+".wav"
+            
+    except:
+        isStateVoice = 3
+        imgUrlStr = ["Fail"]
+        pass
+    
+# 判断联网
+def wifi_is_content():
+    global getDateNum
+    cmd = "ifconfig"
+
+    res = os.popen(cmd).read()
+    data = False
+    if res.rfind("inet addr:")!=48:
+        data = True
+
+    return data
+
+
+def getPrivateIp():
+    st = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
+    try:
+        st.connect(("10.255.255.255",1))
+        IP = st.getsockname()[0]
+    except Exception:
+        IP = "127.0.0.1"
+    finally:
+        st.close()
+    return IP
+
+isStateVoice = 0    # 变量为0开始录音,1 GPT 识别录音结果
+
+ScreenOrientation = False
+CAMERAROTATE = +90
+
+ssidInfo = ""
+passwordInfo = ""
+checkConnectState = False
+connectText = ""
+startConnect=False
+wifiConnectState = False
+# PublicIp=""
+PrivateIP=""
+runConnectSig=True
+connectSuccessSig=False
+
+while True:
+    if wifi_is_content():
+        break
+    else:
+        canvas = camera.capture()
+        if ssidInfo!="" and passwordInfo!="":
+            startConnect=True
+            #connectText = "Waitting for Connection..."
+            #canvas.draw_string(10,40, ssidInfo+" "+str(len(ssidInfo))+" "+str(type(ssidInfo)), scale = 1.5, color = (0,0,0), thickness = 1)
+            canvas.draw_string(10,50, "Connecting to wifi...", scale = 1.5, color = (0,0,0), thickness = 1)
+            display.show(canvas)
+        if startConnect==True:
+            canvas_1 = image.new(size = (320, 320), color = (255,255,255), mode = "RGB")
+            canvas.draw_image(canvas_1,0,0, alpha=0.4)
+            if wifiConnectState == True:
+                if key_B.is_pressed():
+                    while (key_B.is_pressed() == True):
+                        time.sleep(0.001)
+                    startConnect= False
+                    connectText = ""
+                    checkConnectState = False
+                    connectSuccessSig = False
+                    wifiConnectState = False
+                    runConnectSig== True
+                    ssidInfo=""
+                    passwordInfo=""
+                if checkConnectState == True:
+                    if connectSuccessSig == False:
+                        # PublicIp=getPublicIp()
+                        connectSuccessSig = True
+                    connectText = "Wifi connection successfully!"
+                    # canvas.draw_string(10,80, "The WLAN PUBLIC IP:" + PublicIp, scale = 1.5, color = (0,0,0), thickness = 1)
+                    canvas.draw_string(10,110, "THE WLAN PRIVATE IP:" + PrivateIP, scale = 1.5, color = (0,0,0), thickness = 1)
+                    # canvas.draw_image((image.open("/root/preset/img/restart_ff0000_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+                    ssidInfo=""
+                    passwordInfo=""
+                    canvas.clear()
+                    break
+                else:
+                    pass
+            else:
+                if checkConnectState == False:
+                    os.system("wifi_disconnect_ap_test")
+                    os.system('wifi_connect_chinese_ap_test '+ssidInfo+' '+passwordInfo+'')
+                    checkConnectState = True
+                if checkConnectState == True:
+                    if key_B.is_pressed():
+                        while (key_B.is_pressed() == True):
+                            time.sleep(0.001)
+                        startConnect= False
+                        connectText = ""
+                        checkConnectState = False
+                        connectSuccessSig = False
+                        wifiConnectState = False
+                        runConnectSig== True
+                        passwordInfo = ""
+                        ssidInfo = ""
+                    else:
+                        if runConnectSig== True:
+                            connectText = "Connecting to wifi,please wait..."
+                            runConnectSig= False
+                        else:
+                            passwordInfo = ""
+                            ssidInfo = ""
+                            connectText = "Wifi connection failed!"
+                            canvas.draw_image((image.open("/root/preset/img/restart_ff0000_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+                    
+            
+            canvas.draw_string(10,50, connectText, scale = 1.5, color = (0,0,0) , thickness = 1)
+        else:
+            mks = canvas.find_qrcodes()
+            for mk in mks:
+                #外框数据
+                X = mk['x']
+                Y = mk['y']
+                W = mk['w']
+                H = mk['h']            
+                #二维码信息
+                string = mk['payload']
+                codeData = string.split(";")
+                ssidInfo = codeData[0].split(":")[1]
+                passwordInfo = codeData[1].split(":")[1]
+                #画外框
+                canvas.draw_rectangle(X, Y, X + W, Y + H, color=(0, 0, 255), thickness = 2) 
+                #打印信息
+                canvas.draw_string(int(X) , int(Y - 45) , "wifi name:"+ssidInfo, scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+                canvas.draw_string(int(X) , int(Y - 25) , "password:"+passwordInfo, scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+        canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+        display.show(canvas)
+imgUrlStr = []
+# 线程1
+CocoPiThread1 = threading.Thread(target=thread_calsss_fun1)
+# 开启线程
+CocoPiThread1.start()
+cameraImgUrl = ""
+# getImage()
+image_num = 0
+while True:
+    if key_D.is_pressed():
+        isStateVoice = 0
+        imgUrlStr = []
+        VOICEPPATH = ""
+    if len(imgUrlStr) > 0 and isStateVoice ==3:
+        canvas.clear()
+        canvas.draw_image((image.open("/root/preset/img/clockwise_bfbfbf_24x24.png")).rotate(0, adjust=0),2,2,alpha=1)
+        if len(imgUrlStr) > 0:
+            for i in range(len(imgUrlStr)):
+                canvas.draw_string(0,15*(i + 2), str(imgUrlStr[i]), scale = 1, color = (255,255,255) , thickness = 1)
+    elif isStateVoice != 2 and isStateVoice != 1:
+        canvas.clear()
+        canvas = camera.capture()
+        if key_C.is_pressed():
+            while not (key_C.is_pressed() == False):
+                time.sleep(0.1)
+            image_num = image_num + 1
+            cameraImgUrl = "/root/user/img/image"+str(image_num)+ ".jpg"
+            save_path = cameraImgUrl
+            canvas.save(save_path)
+            display.show(canvas)
+            time.sleep(1)
+            imgUrlStr = []
+            isStateVoice = 1
+        canvas.draw_image((image.open("/root/preset/img/camera_bfbfbf_24x24.png")).rotate(0, adjust=0),292,2,alpha=1)
+    display.show(canvas)

+ 299 - 0
preset/app/37_speechToImageSynthesis.py

@@ -0,0 +1,299 @@
+from maix import display
+from maix import image
+from maix import camera
+import pyaudio
+import wave
+import os
+from maix import mjpg
+from maix import utils
+import base64
+import time
+import requests
+import json
+import uuid
+import threading
+import socket
+import uuid
+import sys
+sys.path.append('/root/')
+from CocoPi import BUTTON
+
+key_B = BUTTON(8)
+key_C = BUTTON(13)
+key_D = BUTTON(7)
+camera.camera.config(size=(320,240))
+image.load_freetype("/root/preset/fonts/SourceHanSansCN-Regular.otf")
+canvas = image.new(size = (320, 240))
+# 录音
+WAVE_OUTPUT_FILENAME = "/root/user/audio/record.wav"
+def streamVoice():
+    global WAVE_OUTPUT_FILENAME
+    print(os.path.exists(WAVE_OUTPUT_FILENAME))
+    if(os.path.exists(WAVE_OUTPUT_FILENAME)):
+        os.system("rm "+WAVE_OUTPUT_FILENAME)
+    CHUNK = 1024
+    FORMAT = pyaudio.paInt16
+    CHANNELS = 1
+    RATE = 16000
+    RECORD_SECONDS = 10
+    p = pyaudio.PyAudio()
+    stream = p.open(format=FORMAT,channels=CHANNELS,rate=RATE,input=True,frames_per_buffer=CHUNK)
+    canvas.clear()
+    canvas.draw_string(0,0, "Start", scale = 1, color = (0,255,255) , thickness = 1)
+    display.show(canvas)
+    print("* recording")
+    frames = []    
+    for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
+        data = stream.read(CHUNK,exception_on_overflow = False)
+        frames.append(data)
+
+    print("* done recording")
+
+    canvas.clear()
+    canvas.draw_string(0,0, "End", scale = 1, color = (0,255,255) , thickness = 1)
+    display.show(canvas)
+    stream.stop_stream()
+    stream.close()
+    p.terminate()
+
+    wf = wave.open(WAVE_OUTPUT_FILENAME, "wb")
+    wf.setnchannels(CHANNELS)
+    wf.setsampwidth(p.get_sample_size(FORMAT))
+    wf.setframerate(RATE)
+    wf.writeframes(b"".join(frames))
+    wf.close()
+
+# 获取GPT 回答结果
+def get_post_chatgpt(datas,uid):
+    global list_num
+    # 目标URL
+    url = "https://gpt4.cocorobo.cn/v831AskForTopicNew"
+    payload = json.dumps({"topic": datas})
+    headers={
+        "Content-Type":"application/json"
+    }
+    response=requests.request("POST", url, headers=headers, data=payload)
+    if response.status_code == 200:
+        result = json.loads(response.text)["FunctionResponse"]["result"]
+        url = "https://gpt4.cocorobo.cn/getV831Audio"
+        payload = json.dumps({"input": result,"response_format":"mp3","voice": "shimmer","uid":uid})
+        headers={
+            "Content-Type":"application/json"
+        }
+        response=requests.request("POST", url, headers=headers, data=payload)
+        if response.status_code == 200:
+            print(json.loads(response.text)["FunctionResponse"]["url"])
+            a = "https://gpt4.cocorobo.cn" + json.loads(response.text)["FunctionResponse"]["url"]
+            r = requests.get(a)
+            with open("/root/preset/audio/" + uid+".wav","wb") as f:
+                f.write(r.content)
+        return result
+    else:
+        return ""
+
+# 线程1
+def thread_calsss_fun1():
+    global isStateVoice,voiceResult
+    while True:
+        if isStateVoice==1:
+            streamVoice()
+            time.sleep(0.5)
+            isStateVoice=0
+        elif isStateVoice == 2:
+            voiceResult = getVoiceResult()
+            if len(voiceResult):
+                getImage(voiceResult)
+
+# 关闭线程
+# CocoPiThread1.join()
+
+def getVoiceResult():
+    global WAVE_OUTPUT_FILENAME,voiceResult
+    voiceData = open(WAVE_OUTPUT_FILENAME,'rb')
+    data = {"file": voiceData}
+    param = {}
+    res = requests.post("https://gpt4.cocorobo.cn/transcribe_file_stream", files=data, data=param)
+    try:
+        voiceResult = (json.loads(res.text))["FunctionResponse"]
+    except:
+        voiceResult = ""
+    print("voiceResult:"+str(voiceResult))
+    return voiceResult
+
+def getImage(text):
+    global imgUrlStr,isStateVoice
+    uid = str(uuid.uuid1().hex)
+    param = {
+        "size": "1024x1024",
+        "quality": "hd",
+        "n": 1,
+        "prompt": text,
+        "style":"natural",
+        "uid": uid
+    }
+    res = requests.post("https://gpt4.cocorobo.cn/getImageV831", json=param)
+    try:
+        url = (json.loads(res.text))["FunctionResponse"]["image_url_list"][0]
+        r = requests.get("https://gpt4.cocorobo.cn"+url)
+        with open("/root/user/img/" + uid + ".png","wb") as f:
+            f.write(r.content)
+        
+        imgUrlStr = "/root/user/img/" + uid + ".png"
+        isStateVoice = 3
+    except:
+        isStateVoice = 3
+        pass
+
+# 判断联网
+def wifi_is_content():
+    global getDateNum
+    cmd = "ifconfig"
+
+    res = os.popen(cmd).read()
+    data = False
+    if res.rfind("inet addr:")!=48:
+        data = True
+
+    return data
+
+def getPrivateIp():
+    st = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
+    try:
+        st.connect(("10.255.255.255",1))
+        IP = st.getsockname()[0]
+    except Exception:
+        IP = "127.0.0.1"
+    finally:
+        st.close()
+    return IP
+
+
+voiceResult = ""
+keyboardStr = []
+isStateVoice = 0    # 变量为0开始录音,1 GPT 识别录音结果
+
+ScreenOrientation = False
+CAMERAROTATE = +90
+
+ssidInfo = ""
+passwordInfo = ""
+checkConnectState = False
+connectText = ""
+startConnect=False
+wifiConnectState = False
+# PublicIp=""
+PrivateIP=""
+runConnectSig=True
+connectSuccessSig=False
+
+while True:
+    if wifi_is_content():
+        break
+    else:
+        canvas = camera.capture()
+        if ssidInfo!="" and passwordInfo!="":
+            startConnect=True
+            #connectText = "Waitting for Connection..."
+            #canvas.draw_string(10,40, ssidInfo+" "+str(len(ssidInfo))+" "+str(type(ssidInfo)), scale = 1.5, color = (0,0,0), thickness = 1)
+            canvas.draw_string(10,50, "正在连接WiFi...", scale = 1.5, color = (0,0,0), thickness = 1)
+            display.show(canvas)
+        if startConnect==True:
+            canvas_1 = image.new(size = (320, 320), color = (255,255,255), mode = "RGB")
+            canvas.draw_image(canvas_1,0,0, alpha=0.4)
+            if wifiConnectState == True:
+                if key_B.is_pressed():
+                    while (key_B.is_pressed() == True):
+                        time.sleep(0.001)
+                    startConnect= False
+                    connectText = ""
+                    checkConnectState = False
+                    connectSuccessSig = False
+                    wifiConnectState = False
+                    runConnectSig== True
+                    ssidInfo=""
+                    passwordInfo=""
+                if checkConnectState == True:
+                    if connectSuccessSig == False:
+                        # PublicIp=getPublicIp()
+                        connectSuccessSig = True
+                    connectText = "Wifi connection successfully!"
+                    # canvas.draw_string(10,80, "The WLAN PUBLIC IP:" + PublicIp, scale = 1.5, color = (0,0,0), thickness = 1)
+                    canvas.draw_string(10,110, "局域网IP:" + PrivateIP, scale = 1.5, color = (0,0,0), thickness = 1)
+                    # canvas.draw_image((image.open("/root/preset/img/restart_ff0000_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+                    ssidInfo=""
+                    passwordInfo=""
+                    canvas.clear()
+                    break
+                else:
+                    pass
+            else:
+                if checkConnectState == False:
+                    os.system("wifi_disconnect_ap_test")
+                    os.system('wifi_connect_chinese_ap_test '+ssidInfo+' '+passwordInfo+'')
+                    checkConnectState = True
+                if checkConnectState == True:
+                    if key_B.is_pressed():
+                        while (key_B.is_pressed() == True):
+                            time.sleep(0.001)
+                        startConnect= False
+                        connectText = ""
+                        checkConnectState = False
+                        connectSuccessSig = False
+                        wifiConnectState = False
+                        runConnectSig== True
+                        passwordInfo = ""
+                        ssidInfo = ""
+                    else:
+                        if runConnectSig== True:
+                            connectText = "正在连接WiFi,请等待..."
+                            runConnectSig= False
+                        else:
+                            passwordInfo = ""
+                            ssidInfo = ""
+                            connectText = "WiFi连接失败!"
+                            canvas.draw_image((image.open("/root/preset/img/restart_ff0000_24x24.png")).rotate(0, adjust=0),8,216,alpha=1)
+                    
+            
+            canvas.draw_string(10,50, connectText, scale = 1.5, color = (0,0,0) , thickness = 1)
+        else:
+            mks = canvas.find_qrcodes()
+            for mk in mks:
+                #外框数据
+                X = mk['x']
+                Y = mk['y']
+                W = mk['w']
+                H = mk['h']            
+                #二维码信息
+                string = mk['payload']
+                codeData = string.split(";")
+                ssidInfo = codeData[0].split(":")[1]
+                passwordInfo = codeData[1].split(":")[1]
+                #画外框
+                canvas.draw_rectangle(X, Y, X + W, Y + H, color=(0, 0, 255), thickness = 2) 
+                #打印信息
+                canvas.draw_string(int(X) , int(Y - 45) , "wifi name:"+ssidInfo, scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+                canvas.draw_string(int(X) , int(Y - 25) , "password:"+passwordInfo, scale = 1, color = (255, 0, 0), thickness = 2)  #内框ID
+        canvas.draw_image((image.open("/root/preset/img/exit_ff0000_24x24.png")).rotate(0, adjust=0),288,216,alpha=1)
+        display.show(canvas)
+imgUrlStr = ""
+# 线程1
+CocoPiThread1 = threading.Thread(target=thread_calsss_fun1)
+# 开启线程
+CocoPiThread1.start()
+while True:
+    if key_C.is_pressed():
+        isStateVoice = 2
+        voiceResult = ""
+    elif key_D.is_pressed():
+        isStateVoice = 1
+        imgUrlStr = ""
+    if isStateVoice == 2:
+        canvas.clear()
+        canvas.draw_string(0,0, "图片生成中...", scale = 1, color = (0,255,255) , thickness = 1)
+    elif isStateVoice != 2 and isStateVoice != 1:
+        canvas.clear()
+        if len(imgUrlStr)>0:
+            canvas.draw_image((image.open(imgUrlStr)).rotate(0, adjust=0),0,0,alpha=1)
+        canvas.draw_image(image.open("/root/preset/img/recording.png"),0 , 2,alpha=1)
+        canvas.draw_string(250,0, "C Chart", scale = 1, color = (0,255,255) , thickness = 1)
+    display.show(canvas)

+ 274 - 0
preset/app/38_jumpbot.py

@@ -0,0 +1,274 @@
+#!/usr/bin/env python
+#version    :       2024.03.11
+#language   :       ch
+#hardware   :       PI
+
+import threading
+import time
+import queue
+import math
+import os
+import pyaudio
+import wave
+import sys
+sys.path.append('/root/')
+from CocoPi import QMI8658
+from maix import camera,display,image
+
+event=threading.Event()
+showLock=threading.Lock()
+event.set()
+#配置字体
+image.load_freetype("/root/preset/fonts/botPixel.ttf")
+
+#导入图片资源对象
+jumpbot_logo = image.open("/root/preset/img/jumpbot/oneHeadThreeLeg_128_128.png")
+jumpbot_right_jump = image.open("/root/preset/img/jumpbot/oneHeadThreeLeg_right_jump.png")
+jumpbot_left_jump = image.open("/root/preset/img/jumpbot/oneHeadThreeLeg_left_jump.png")
+jumpbot_middle_jump = image.open("/root/preset/img/jumpbot/oneHeadThreeLeg_middle_jump.png")
+jumpbot_middle_nojump = image.open("/root/preset/img/jumpbot/oneHeadThreeLeg_middle_nojump.png")
+jumpbot_left_nojump = image.open("/root/preset/img/jumpbot/oneHeadThreeLeg_left_nojump.png")
+jumpbot_right_nojump = image.open("/root/preset/img/jumpbot/oneHeadThreeLeg_right_nojump.png")
+
+
+
+#比例转换函数
+def numberMap(value, leftMin, leftMax, rightMin, rightMax):
+    leftSpan = leftMax - leftMin
+    rightSpan = rightMax - rightMin
+    valueScaled = float(value - leftMin) / float(leftSpan)
+    return int(rightMin + (valueScaled * rightSpan))
+
+#音量调节函数
+def voice_numberMap(value):
+    valueScaled = float(value - 0) / float(100)
+    return valueScaled * 31
+
+#创建投影用的画布
+img_drop=image.new(size=(320,240),mode="RGB")
+
+#屏幕显示函数
+def screenShow():
+    from maix import image,display,camera
+    
+    import time
+    global img_drop,lock4,lock5,queue1,queue2,screenCapture,x,y
+    while True:
+        event.wait()
+        if x==1: 
+            #queue1.put(1)
+            try:
+                #showLock.acquire()
+                img_drop.draw_image((screenCapture.rotate(-90,adjust=1)),0,0)
+            #print("rotate time:"+str(time.time()))
+                display.show(img_drop)
+            finally:
+                #showLock.release()
+                pass
+            x=0
+            y=0
+        else:
+            pass
+            #time.sleep(0.01)
+    
+#播放音乐
+
+def playMusic():
+    global lock3,jumpSound
+    import wave
+    import pyaudio
+    import time
+    p = pyaudio.PyAudio()
+    while True:
+        event.wait()
+        if lock3==1:
+            #导入音乐资源对象
+            CHUNK = 1024
+            jumpSound = wave.open(r"/root/preset/audio/jump1.wav", 'rb')
+            stream = p.open(format=p.get_format_from_width(jumpSound.getsampwidth()),channels=jumpSound.getnchannels(),rate=jumpSound.getframerate(),output=True)
+            data = jumpSound.readframes(CHUNK)
+            while len(data) > 0:
+                stream.write(data)
+                data = jumpSound.readframes(CHUNK)
+            stream.stop_stream()
+            stream.close()
+            #p.terminate()
+            lock3=0
+        else:
+            time.sleep(0.01)
+
+#获取MPU数值
+def getMpuData():
+    sys.path.append('/root/')
+    from CocoPi import QMI8658
+    import time
+    global initData,lock1,lock2
+    while True:
+        if lock1==1:
+            if event.is_set():
+                event.clear()
+            else:
+                pass
+            xyz=qmi8658.getPitchYawRollGxGyGz(initData)
+            #print("xyz:"+str(xyz))
+            pitch=round(xyz[0],2)
+            yaw=round(xyz[1],2)
+            #print("yaw:"+str(yaw))
+            queue1.put(yaw)
+            queue2.put(pitch)
+            lock1=0
+            lock2=1
+            event.set()
+        else:
+            time.sleep(0.04)
+
+
+
+#-------------------------------
+#初始化色彩配置
+splash_theme_color = (255,255,255)
+splash_front_color = (60,60,60)
+fontcolor=255
+fontsize=0.75
+fontchange=0
+
+#开机显示
+splash = image.new(size=(240, 320),mode = "RGB")
+splash.draw_rectangle(0,0,240,320,color=splash_theme_color,thickness=-1)
+splash.draw_string(40, 28, "Jump", 1.6, color=(255, 200, 0))
+splash.draw_string(140, 28, "Cat", 1.6, color=(255, 128, 64))
+splash.draw_image(jumpbot_logo.rotate(0, adjust=1),54,100,alpha=1)
+splash.draw_string(40, 240, "NOTE:", 0.75, color=(0, 128, 255))
+splash.draw_string(96, 240, "PLEASE", 0.75, color=(0, 128, 255))
+splash.draw_string(160, 240, "PLACE", 0.75, color=(0, 128, 255))
+splash.draw_string(40, 260, "HORIZONTALLY", 0.75, color=(0, 128, 255))
+splash.draw_string(172, 260, "AND", 0.75, color=(0, 128, 255))
+splash.draw_string(40, 280, "REMAIN", 0.75, color=(0, 128, 255))
+splash.draw_string(110, 280, "STILL!", 0.75, color=(0, 128, 255))
+screenCapture=splash.crop(0,0,240,320)
+img_drop.draw_image((screenCapture.rotate(-90,adjust=1)),0,0)
+display.show(img_drop)
+time.sleep(1)
+
+#配置QMI8658
+qmi8658=QMI8658()
+qmi8658.calibrate()
+initData={}
+initData["AcX"]=qmi8658.get_accel(10)["AcX"]
+initData["AcY"]=qmi8658.get_accel(10)["AcY"]
+initData["AcZ"]=qmi8658.get_accel(10)["AcZ"]
+initData["GyX"]=qmi8658.get_accel(10)["GyX"]
+initData["GyY"]=qmi8658.get_accel(10)["GyY"]
+initData["GyZ"]=qmi8658.get_accel(10)["GyZ"]
+
+#配置图形角色相关参数
+x_speed=0
+y_speed=0
+x_pos=120
+y_pos=160
+x_change=0
+y_change=5
+fowardState=0
+jumpState=0
+Yaw=0
+
+#配置音频
+os.system("amixer cset numid=8,iface=MIXER,name='LINEOUT volume'voice_numberMap(25)")
+
+
+#创建队列
+queue1=queue.Queue()    #用来传递开启位置计算与陀螺仪数据获取的信号YAW
+queue1.put(1)           #用来作为第一次开启位置计算与陀螺仪数据获取的信号
+queue2=queue.Queue()    #用于存放图像数据
+
+#创建信号锁
+lock1=1
+lock2=0
+lock3=0
+lock4=1
+lock5=0
+
+thread2=threading.Thread(target=getMpuData)
+thread2.start()
+thread3=threading.Thread(target=screenShow)
+thread3.start()
+#thread4=threading.Thread(target=playMusic)
+#thread4.start()
+x=0
+y=0
+while True:
+    event.wait()
+    if y==0:
+        splash.clear()
+        splash.draw_rectangle(0,0,240,320,color=splash_theme_color,thickness=-1)
+        #splash.draw_string(80, 8, "pitch:"+str(round(xyz[0],2)), fontsize, color=(0, 0, 0))
+        #splash.draw_string(80, 28, "yaw:"+str(round(xyz[1],2)), fontsize, color=(0, 0, 0))
+        #splash.draw_string(80, 48, "fontcolor:"+str(fontcolor), fontsize, color=(0, 0, 0))
+        #splash.draw_image(jumpbot_left_jump.rotate(0, adjust=1),109,149,alpha=1)
+        #splash.draw_image(jumpbot_right_jump.rotate(0, adjust=0),109,149-int(xyz[0]),alpha=1)
+        #splash.draw_image(jumpbot_right_jump.rotate(0, adjust=0),109-int(xyz[1]),149,alpha=1)
+
+        #提示字显示
+        splash.draw_rectangle(0,280,240,320,color=splash_front_color,thickness=-1)
+        splash.draw_string(48, 286, "JUMP!", fontsize, color=(fontcolor,fontcolor,fontcolor))
+        splash.draw_string(104, 286, "JUMP!", fontsize, color=(fontcolor,fontcolor,fontcolor))
+        splash.draw_string(160, 286, "JUMP!", fontsize, color=(fontcolor,fontcolor,fontcolor))
+        #splash.draw_string(48, 286, "PRESS", fontsize, color=(fontcolor,fontcolor,fontcolor))
+        #splash.draw_string(104, 286, "B", fontsize, color=(fontcolor,fontcolor,fontcolor))
+        #splash.draw_string(120, 286, "TO", fontsize, color=(fontcolor,fontcolor,fontcolor))
+        #splash.draw_string(148, 286, "START", fontsize, color=(fontcolor,fontcolor,fontcolor))
+        if fontcolor==splash_front_color[0]:
+            fontchange=15
+        elif fontcolor==255:
+            fontchange=-15
+        fontcolor=fontcolor+fontchange
+
+        #获取Yaw值
+        if lock2==1:
+            Yaw=queue1.get()
+            Pitch=queue2.get()
+            lock2=0
+            lock1=1
+        else:
+            pass
+
+        if -90<=Yaw and Yaw<=0:
+            fowardState=1
+            x_speed=int(math.sqrt(math.fabs(Yaw)))
+            #x_speed=numberMap(0-yaw,0,90,0,18)
+        elif 0<Yaw and Yaw<=90:
+            fowardState=0
+            x_speed=-int(math.sqrt(math.fabs(Yaw)))
+            #x_speed=numberMap(0-yaw,-90,0,-18,0)
+        else:
+            pass
+        x_pos=x_pos+x_speed
+        if x_pos<0:
+            x_pos=240
+        elif x_pos>240:
+            x_pos=0
+        else:
+            pass
+        if fowardState==0:
+            sprite=jumpbot_left_nojump
+        elif fowardState==1:
+            sprite=jumpbot_right_nojump
+        else:
+            pass
+
+        if y_pos+y_speed>259:
+            y_pos=259
+            y_speed=-35
+            lock3=1
+        else:
+            y_pos=y_pos+y_speed
+            y_speed=y_speed+y_change
+        print("yaw:"+str(Yaw))
+        splash.draw_image(sprite,x_pos-11,y_pos,alpha=1)
+        splash.draw_string(136, 8, "SPEED:"+str(y_speed), fontsize, color=(0, 0, 0))
+        splash.draw_string(144, 28, "YAW:"+str(Yaw), fontsize, color=(0, 128, 255))
+        splash.draw_string(124, 48, "PITCH:"+str(Pitch), fontsize, color=(255, 128, 64))
+        screenCapture=splash.crop(0,0,240,320)
+        #queue2.put(1)
+        x=1
+        y=1

+ 294 - 0
preset/app/39_gluttonousSnake.py

@@ -0,0 +1,294 @@
+#!/usr/bin/env python
+#version    :       2024.03.07
+#language   :       en
+#hardware   :       PI
+
+
+from maix import display
+from maix import image
+from maix import camera
+import os
+import time
+import random
+import sys
+sys.path.append("/root/")
+from CocoPi import QMI8658
+from CocoPi import BUTTON
+from maix import mjpg
+from maix import utils
+import base64
+import time
+
+cameraSize = True
+def CAMERATYPE():
+    global cameraSize
+    try:
+        if os.path.exists("/etc/cameraSize.cfg"):
+            cameraSize = True
+        else:
+            cameraSize = False
+    except:
+        cameraSize = False
+
+CAMERATYPE()
+
+
+def v831_display_show_canvas(displayShow):
+    global _canvas_y,_canvas_x,ScreenOrientation,cameraSize
+    CANVASSHOWIMGAGE = ""
+    if ScreenOrientation:
+        displayShowCanvas = image.new(size = (240, 320))
+        displayShowCanvas.draw_rectangle(0,0,240,320, color=(0,0,0), thickness=-1)
+        displayShowCanvas.draw_image(displayShow,_canvas_x,_canvas_y,alpha=1)
+        displayShowVER = displayShowCanvas.crop(0,0,240,320)
+        displayShowVER = displayShowVER.rotate(-90, adjust=1)
+        display.show(displayShowVER)
+    else:
+        displayShowCanvas = image.new(size = (320, 240))
+        displayShowCanvas.draw_rectangle(0,0,320,240, color=(0,0,0), thickness=-1)
+        displayShowCanvas.draw_image(displayShow,_canvas_x,_canvas_y,alpha=1)
+        display.show(displayShowCanvas)
+
+
+ScreenOrientation = False
+_canvas_x = 0
+_canvas_y = 0
+
+key_C = BUTTON(13)
+
+image.load_freetype("/root/preset/fonts/botPixel.ttf")
+if cameraSize==True:
+    camera.camera.config(size=(320,240))
+else:
+    camera.camera.config(size=(240,320))
+x = random.randrange(100, 141, 10)
+y = random.randrange(100, 141, 10)
+x1 = random.randrange(100, 141, 10)
+y1 = random.randrange(100, 141, 10)
+a = [{"x":x - 30, "y":y}, {"x":x - 20, "y":y}, {"x":x - 10, "y":y}, {"x":x, "y":y}]
+canvas = image.new(size = (320, 240))
+#-------------------------------
+#初始化色彩配置
+splash_theme_color = (255,255,255)
+splash_front_color = (60,60,60)
+fontcolor=255
+fontsize=1.4
+
+#开机显示
+splash = image.new(size=(320, 240),mode = "RGB")
+splash.draw_rectangle(0,0,320,240,color=splash_theme_color,thickness=-1)
+splash.draw_string(60, 48, "Gluttonous", 1.5, color=(255, 200, 0))
+splash.draw_string(120, 88, "Snake", 1.5, color=(255, 128, 64))
+display.show(splash)
+time.sleep(1)
+
+#初始化设置
+qmi8658=QMI8658()
+#校准
+qmi8658.calibrate()
+#标定初始方位
+initData={}
+initData["AcX"]=qmi8658.get_accel(10)["AcX"]
+initData["AcY"]=qmi8658.get_accel(10)["AcY"]
+initData["AcZ"]=qmi8658.get_accel(10)["AcZ"]
+initData["GyX"]=qmi8658.get_accel(10)["GyX"]
+initData["GyY"]=qmi8658.get_accel(10)["GyY"]
+initData["GyZ"]=qmi8658.get_accel(10)["GyZ"]
+
+
+
+angle_x = 0
+angle_y = 0
+score_count = 0
+direction = "RIGHT"
+isFinsh = False
+b = {"x":250, "y":250}
+c = {"x":250, "y":250}
+while True:
+    angle_x = round(qmi8658.getPitchYawRollGxGyGz(initData)[0],2)
+    angle_y = round(qmi8658.getPitchYawRollGxGyGz(initData)[1],2)
+    canvas.clear()
+    if x == x1 and y == y1:
+        x1 = random.randrange(10, 311, 10)
+        y1 = random.randrange(10, 231, 10)
+        score_count = score_count + 1
+        for j in a:
+            if j.get("x") == x1 and j.get("y") == y1:
+                x1 = x1 + 10
+                y1 = y1 + 10
+    else:
+        if angle_y > 30 and direction != "DOWN":
+            direction = "UP"
+            y = y - 10
+            b = {"x":x, "y":y}
+            if x == x1 and y == y1:
+                x1 = random.randrange(10, 311, 10)
+                y1 = random.randrange(10, 231, 10)
+                score_count = score_count + 1
+                a.append({"x":x, "y":y})
+                for j in a:
+                    if j.get("x") == x1 and j.get("y") == y1:
+                        x1 = x1 + 10
+                        y1 = y1 + 10
+            elif y == -10:
+                isFinsh = True
+            else:
+                c = a[0]
+                a.pop(0)
+                for k in a:
+                    if k.get("x") == b.get("x") and k.get("y") == b.get("y"):
+                        isFinsh = True
+                a.append({"x":x, "y":y})
+        elif angle_y < -30 and direction != "UP":
+            direction = "DOWN"
+            y = y + 10
+            b = {"x":x, "y":y}
+            if x == x1 and y == y1:
+                x1 = random.randrange(10, 311, 10)
+                y1 = random.randrange(10, 231, 10)
+                score_count = score_count + 1
+                a.append({"x":x, "y":y})
+                for j in a:
+                    if j.get("x") == x1 and j.get("y") == y1:
+                        x1 = x1 + 10
+                        y1 = y1 + 10
+            elif y == 240:
+                isFinsh = True
+            else:
+                c = a[0]
+                a.pop(0)
+                for k in a:
+                    if k.get("x") == b.get("x") and k.get("y") == b.get("y"):
+                        isFinsh = True
+                a.append({"x":x, "y":y})
+        elif angle_x < -30 and direction != "RIGHT":
+            direction = "LEFT"
+            x = x - 10
+            b = {"x":x, "y":y}
+            if x == x1 and y == y1:
+                x1 = random.randrange(10, 311, 10)
+                y1 = random.randrange(10, 231, 10)
+                score_count = score_count + 1
+                a.append({"x":x, "y":y})
+                for j in a:
+                    if j.get("x") == x1 and j.get("y") == y1:
+                        x1 = x1 + 10
+                        y1 = y1 + 10
+            elif x == -10:
+                isFinsh = True
+            else:
+                c = a[0]
+                a.pop(0)
+                for k in a:
+                    if k.get("x") == b.get("x") and k.get("y") == b.get("y"):
+                        isFinsh = True
+                a.append({"x":x, "y":y})
+        elif angle_x > 30 and direction != "LEFT":
+            direction = "RIGHT"
+            x = x + 10
+            b = {"x":x, "y":y}
+            if x == x1 and y == y1:
+                x1 = random.randrange(10, 311, 10)
+                y1 = random.randrange(10, 231, 10)
+                score_count = score_count + 1
+                a.append({"x":x, "y":y})
+                for j in a:
+                    if j.get("x") == x1 and j.get("y") == y1:
+                        x1 = x1 + 10
+                        y1 = y1 + 10
+            elif x == 320:
+                isFinsh = True
+            else:
+                c = a[0]
+                a.pop(0)
+                for k in a:
+                    if k.get("x") == b.get("x") and k.get("y") == b.get("y"):
+                        isFinsh = True
+                a.append({"x":x, "y":y})
+        else:
+            if direction == "UP":
+                y = y - 10
+                b = {"x":x, "y":y}
+                if y == -10:
+                    isFinsh = True
+                else:
+                    c = a[0]
+                    a.pop(0)
+                    for k in a:
+                        if k.get("x") == b.get("x") and k.get("y") == b.get("y"):
+                            isFinsh = True
+                    a.append({"x":x, "y":y})
+            elif direction == "DOWN":
+                y = y + 10
+                b = {"x":x, "y":y}
+                if y == 240:
+                    isFinsh = True
+                else:
+                    c = a[0]
+                    a.pop(0)
+                    for k in a:
+                        if k.get("x") == b.get("x") and k.get("y") == b.get("y"):
+                            isFinsh = True
+                    a.append({"x":x, "y":y})
+            elif direction == "LEFT":
+                x = x - 10
+                b = {"x":x, "y":y}
+                if x == -10:
+                    isFinsh = True
+                else:
+                    c = a[0]
+                    a.pop(0)
+                    for k in a:
+                        if k.get("x") == b.get("x") and k.get("y") == b.get("y"):
+                            isFinsh = True
+                    a.append({"x":x, "y":y})
+            else:
+                x = x + 10
+                b = {"x":x, "y":y}
+                if x == 320:
+                    isFinsh = True
+                else:
+                    c = a[0]
+                    a.pop(0)
+                    for k in a:
+                        if k.get("x") == b.get("x") and k.get("y") == b.get("y"):
+                            isFinsh = True
+                    a.append({"x":x, "y":y})
+    if isFinsh == True:
+        canvas.clear()
+        canvas.draw_string(60,40, "Gameover!", scale = 1.5, color = (255,255,255) , thickness = 1)
+        canvas.draw_string(85,90, "Score:", scale = 1.5, color = (255,0,0) , thickness = 1)
+        canvas.draw_string(210,90, (str(score_count)), scale = 1.5, color = (255,0,0) , thickness = 1)
+        canvas.draw_string(30,150, "Press", scale = 1, color = (255,255,255) , thickness = 1)
+        canvas.draw_string(105,150, "C", scale = 1, color = (255,255,255) , thickness = 1)
+        canvas.draw_string(125,150, "TO", scale = 1, color = (255,255,255) , thickness = 1)
+        canvas.draw_string(165,150, "Restart!", scale = 1, color = (255,255,255) , thickness = 1)
+        v831_display_show_canvas(canvas)
+        if (key_C.is_pressed()):
+            while key_C.is_pressed():
+                time.sleep(0.001)
+            angle_x = 0
+            angle_y = 0
+            score_count = 0
+            direction = "RIGHT"
+            isFinsh = False
+            x = random.randrange(100, 141, 10)
+            y = random.randrange(100, 141, 10)
+            x1 = random.randrange(100, 141, 10)
+            y1 = random.randrange(100, 141, 10)
+            a = [{"x":x - 30, "y":y}, {"x":x - 20, "y":y}, {"x":x - 10, "y":y}, {"x":x, "y":y}]
+            b = {"x":250, "y":250}
+            c = {"x":250, "y":250}
+    else:
+        canvas.draw_rectangle(c.get("x"),c.get("y"),10, 10, color=(0,0,0), thickness=-1)
+        canvas.draw_rectangle(x1,y1, x1+10,y1+ 10, color=(255,255,255), thickness=-1)
+        for i in a:
+            x = i.get("x")
+            y = i.get("y")
+            canvas.draw_rectangle(x,y, x+10,y+ 10, color=(255,255,255), thickness=-1)
+        v831_display_show_canvas(canvas)
+    if isFinsh == False:
+        time.sleep(0.2)
+    else:
+        pass
+

+ 61 - 0
preset/app/40_soundLoudnessAnalysis.py

@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+#version    :       2024.03.07
+#language   :       en
+
+
+import pyaudio
+import numpy as np
+from maix import camera, image, display
+import time
+
+def waterFallShow(inputVal):
+    global intensity_recorder,intensity_show,img
+    if(len(intensity_recorder)<40):
+        intensity_recorder.append(inputVal)
+    else:
+        for i in range(0,39):
+            intensity_recorder[i]=intensity_recorder[i+1]
+        intensity_recorder[39]=inputVal
+    for i in range(0,len(intensity_recorder)):
+        height=int(intensity_recorder[i])
+        intensity_show[i] = image.new(size=(7, height), color=(40, 144, 152), mode="RGB")
+        img.draw_image(intensity_show[i], i*8, 240-height)
+    
+image.load_freetype("/root/preset/fonts/CascadiaCodePL-Italic.ttf")
+CHUNK = 1024
+FORMAT = pyaudio.paInt16
+CHANNELS = 1
+RATE = 44100
+p = pyaudio.PyAudio()
+
+img = image.new(size=(320, 240), color=(0, 0, 0), mode="RGB")  # 创建一张红色背景图
+stream = p.open(format=FORMAT,
+                channels=CHANNELS,
+                rate=RATE,
+                input=True,
+                frames_per_buffer=CHUNK)
+
+intensity_recorder = []
+intensity_show = [0]*40
+print(len(intensity_show))
+# 循环读取音频数据
+while True:
+    stream.start_stream()
+    str_data = stream.read(CHUNK)  # 从麦克风获取一帧音频数据
+    stream.stop_stream()
+    # 将音频数据转换为NumPy数组
+    arr = np.frombuffer(str_data, dtype=np.int16)
+    # 计算音频数据的绝对值之和,即为声音强度
+    # 1024个16位的wav采样点(-32768~32767)的绝对值之和,需要将其映射到0~1023
+    intensity = int(np.abs(arr).sum()/32768)
+    #print(intensity)
+    img.clear()
+    waterFallShow(intensity)
+    img.draw_string(140, 20, "Loudness of sound:"+str(intensity), scale=1.0,color=(255, 255, 255), thickness=1)
+    display.show(img)
+    print("main_thread_time:", time.time())
+
+# 关闭流和PyAudio对象
+stream.stop_stream()
+stream.close()
+p.terminate()

+ 70 - 0
preset/app/41_soundSpectrumAnalysis.py

@@ -0,0 +1,70 @@
+import pyaudio
+import numpy as np
+from maix import camera, image, display
+import time
+
+CHUNK = 1024
+FORMAT = pyaudio.paInt16
+CHANNELS = 2
+RATE = 44100
+p = pyaudio.PyAudio()
+
+img = image.new(size=(320, 240), color=(0, 0, 0), mode="RGB")  # 创建一张背景图
+stream = p.open(format=FORMAT,
+                channels=CHANNELS,
+                rate=RATE,
+                input=True,
+                frames_per_buffer=CHUNK)
+
+intensity_recorder = []
+intensity_show = [0]*40
+print(len(intensity_show))
+# 循环读取音频数据
+
+f_t = np.fft.fftfreq(CHUNK, 1 / RATE)    # 传入信号长度及采样率,返回对应频率
+
+while True:
+    stream.start_stream()
+    str_data = stream.read(CHUNK)  # 从麦克风获取一帧音频数据
+    stream.stop_stream()
+    print("type str_data:",type(str_data))
+    print("str_data:",str_data)
+    # 将音频数据转换为NumPy数组
+    arr = np.frombuffer(str_data, dtype=np.int16)    #在这里用numpy.frombuffer与
+                                                     #numpy.fromstring效果相同
+    print("arr:",arr)
+    print("type arr1:",type(arr))
+    arr.shape = -1,2
+    # 将数组转置
+    arr = arr.T
+    print("arr2:",arr)
+    print("3",len(arr[0].tolist()))
+    f_signal = np.fft.fft(arr[0])
+    #f_signal=np.abs(f_signal)
+    #print("ft:",f_t)
+    
+    #print("ft len:",len(f_t.tolist()))
+    #print("f_signal:",f_signal)
+    #print("f_signal len:",len(f_signal.tolist()))
+    # 取前512个数据,即正频率部分
+    fft_data = f_signal[:512]
+
+    # 将前512个数据分成32组,每组包含16个数据
+    fft_data = np.split(fft_data, 32)
+
+    # 对每组数据进行平均,得到每组的平均幅值
+    avg_data = np.abs(fft_data).mean(axis=1)
+    print(avg_data)
+    img.clear()
+    for i in range(0,32):
+        height=int(avg_data.tolist()[i]/500)
+        intensity_show[i] = image.new(size=(7, height), color=(40, 144, 152), mode="RGB")
+        img.draw_image(intensity_show[i], i*8, 240-height)
+    #img.draw_string(30, 20, "intensity"+str(intensity), scale=1.0,color=(255, 255, 255), thickness=1)
+    display.show(img)
+    print("main_thread_time:", time.time())
+
+# 关闭流和PyAudio对象
+stream.stop_stream()
+stream.close()
+p.terminate()

+ 39 - 0
preset/app/checkout.py

@@ -0,0 +1,39 @@
+localrep = "/home/backup"
+otaPath = "/root/preset/app/ota.py"
+
+from maix import camera, display, image
+
+image.load_freetype("/root/preset/fonts/simhei.ttf")
+hello_img = image.new(size=(320, 240), color=(0, 0, 0), mode="RGB")
+hello_img.draw_string(10, 115, 'Checkout', scale=1.0, color=(255, 255, 255), thickness=1)
+display.show(hello_img)
+
+import git
+from io import RawIOBase
+
+
+class NewStream(RawIOBase):
+    def write(self, b):
+        hello_img = image.new(size=(320, 240), color=(0, 0, 0), mode="RGB")
+        hello_img.draw_string(10, 115, str(b), scale=1.0, color=(255, 255, 255), thickness=1)
+        display.show(hello_img)
+        return None
+
+
+git.rw()
+steam = NewStream()
+
+if git.activeBranch(localrep) != b'zh':
+    git.checkout(localrep, 'zh', steam)
+else:
+    git.checkout(localrep, 'en', steam)
+
+hello_img = image.new(size=(320, 240), color=(0, 0, 0), mode="RGB")
+hello_img.draw_string(10, 115, 'Reconstruct directory', scale=1.0, color=(255, 255, 255), thickness=1)
+display.show(hello_img)
+
+with open(otaPath) as f:
+    code = f.read()
+exec(code)
+
+git.ro()

+ 130 - 0
preset/app/git.py

@@ -0,0 +1,130 @@
+import os
+import sys
+from io import RawIOBase
+from dulwich import porcelain
+from dulwich.porcelain import get_remote_repo
+from dulwich.repo import Repo
+from dulwich.walk import Walker
+import requests
+
+
+def ro():
+    os.system("/etc/init.d/S01mount_ro start")
+
+
+def rw():
+    os.system("/etc/init.d/S01mount_ro stop")
+
+
+class NoneStream(RawIOBase):
+    """Fallback if stdout or stderr are unavailable, does nothing."""
+
+    def read(self, size=-1):
+        return None
+
+    def readall(self):
+        return None
+
+    def readinto(self, b):
+        return None
+
+    def write(self, b):
+        return None
+
+
+def log(localRep):
+    repo = Repo(localRep)
+    walker = Walker(repo, sorted(repo.get_refs().values(), reverse=True))
+    for entry in walker:
+        commit = entry.commit
+        print(f"commit {commit.id.decode()}")
+        print(f"Author: {commit.author.decode()} <{commit.author.decode()}>")
+        print(f"Date: {commit.author_time}")
+        print()
+        print(f"    {commit.message.decode()}")
+        print()
+
+
+def __log__(localRep):
+    repo = Repo(localRep)
+    walker = Walker(repo, sorted(repo.get_refs().values(), reverse=True))
+    for entry in walker:
+        commit = entry.commit
+        return f"commit {commit.id.decode()}", f"Author: {commit.author.decode()} <{commit.author.decode()}>", \
+               f"Date: {commit.author_time}", f"    {commit.message.decode()}"
+
+
+def showChanges(localRep, outStream=sys.stdout):
+    porcelain.show(localRep, outstream=outStream)
+
+
+def activeBranch(localRep):
+    return porcelain.active_branch(localRep)
+
+
+def checkout(localRep, branch, progStream=None):
+    r = Repo(localRep)
+    if progStream is None:
+        progStream = NoneStream()
+    try:
+        porcelain.checkout_branch(r, 'origin/' + branch, outstream=progStream)
+    except porcelain.CheckoutError as e:
+        print("CheckoutError:", e)
+        porcelain.reset(r, 'hard')
+        porcelain.checkout_branch(r, 'origin/' + branch, outstream=progStream)
+
+
+def pull(localRep, progStream=None, depth=3):
+    if progStream is None:
+        progStream = NoneStream()
+    porcelain.pull(localRep, refspecs=porcelain.active_branch(localRep), outstream=progStream, depth=depth)
+
+
+def reset(localRep):
+    repo = Repo(localRep)
+    head_ref = repo.head()
+    head_commit = repo[head_ref]
+    parent_commit = repo[head_commit.parents[0]]
+    porcelain.reset(repo, 'hard', parent_commit.tree)
+
+
+def recovery(localRep):
+    r = Repo(localRep)
+    porcelain.reset(r, 'hard')
+
+
+def clone(source, target=None, depth: int = None):
+    porcelain.clone(source, target, depth=depth)
+
+
+def isOnline(localRep):
+    r = Repo(localRep)
+    (remote_name, remote_location) = get_remote_repo(r, None)
+    try:
+        response = requests.get(remote_location)
+        if response.status_code == 200:
+            # print("Connection successful.")
+            return True
+        else:
+            # print(f"Connection failed with status code: {response.status}")
+            return False
+    except Exception as e:
+        # print(f"Connection failed: {e}")
+        return False
+    
+def swRemote(localRep, remote_url):
+    r = Repo(localRep)
+    porcelain.remote_remove(r,'origin')
+    porcelain.remote_add(r,'origin',remote_url)
+
+def swRemote_force(localRep, remote_url):
+    r = Repo(localRep)
+    porcelain.remote_remove(r,'origin')
+    porcelain.remote_add(r,'origin',remote_url)
+    porcelain.fetch(localRep)
+    porcelain.pull(localRep, refspecs=porcelain.active_branch(localRep), force=True)
+
+
+if __name__ == '__main__':
+    localrep = "/home/backup"
+    log(localrep)

+ 5 - 0
preset/app/ota.py

@@ -0,0 +1,5 @@
+import os
+
+os.system('chmod -R 777 /home')
+os.system('rsync -r --checksum /home/backup/ /root')
+os.system("ps | grep main.py | grep -v grep | awk '{print $1}' | xargs kill")

+ 47 - 0
preset/app/pull.py

@@ -0,0 +1,47 @@
+localrep = "/home/backup"
+otaPath = "/root/preset/app/ota.py"
+
+from maix import camera, display, image  # 引入python模块包
+
+image.load_freetype("/root/preset/fonts/simhei.ttf")
+hello_img = image.new(size=(320, 240), color=(0, 0, 0), mode="RGB")
+hello_img.draw_string(10, 115, 'Pull', scale=1.0, color=(255, 255, 255), thickness=1)
+display.show(hello_img)
+
+import git, time
+
+if not git.isOnline(localrep):
+    hello_img = image.new(size=(320, 240), color=(0, 0, 0), mode="RGB")
+    hello_img.draw_string(10, 115, 'Network connection error', scale=1.0, color=(255, 255, 255), thickness=1)
+    display.show(hello_img)
+    time.sleep(2)
+    exit()
+
+from io import RawIOBase
+
+
+class NewStream(RawIOBase):
+    def write(self, b):
+        hello_img = image.new(size=(320, 240), color=(0, 0, 0), mode="RGB")
+        hello_img.draw_string(10, 115, str(b), scale=1.0, color=(255, 255, 255), thickness=1)
+        display.show(hello_img)
+        return None
+
+
+git.rw()
+steam = NewStream()
+git.pull(localrep, steam)
+
+hello_img = image.new(size=(320, 240), color=(0, 0, 0), mode="RGB")
+commit, Author, Date, message = git.__log__(localrep)
+hello_img.draw_string(10, 50, commit, scale=1.0, color=(255, 255, 255), thickness=1)
+hello_img.draw_string(10, 100, Author, scale=1.0, color=(255, 255, 255), thickness=1)
+hello_img.draw_string(10, 150, Date, scale=1.0, color=(255, 255, 255), thickness=1)
+hello_img.draw_string(10, 200, message, scale=1.0, color=(255, 255, 255), thickness=1)
+display.show(hello_img)
+
+with open(otaPath) as f:
+    code = f.read()
+exec(code)
+
+git.ro()

+ 23 - 0
preset/app/reset.py

@@ -0,0 +1,23 @@
+localrep = "/home/backup"
+otaPath = "/root/preset/app/ota.py"
+
+from maix import camera, display, image
+
+image.load_freetype("/root/preset/fonts/simhei.ttf")
+hello_img = image.new(size=(320, 240), color=(0, 0, 0), mode="RGB")
+hello_img.draw_string(10, 115, 'Reset', scale=1.0, color=(255, 255, 255), thickness=1)
+display.show(hello_img)
+
+import git
+
+git.rw()
+git.reset(localrep)
+hello_img = image.new(size=(320, 240), color=(0, 0, 0), mode="RGB")
+hello_img.draw_string(10, 115, 'Reconstruct directory', scale=1.0, color=(255, 255, 255), thickness=1)
+display.show(hello_img)
+
+with open(otaPath) as f:
+    code = f.read()
+exec(code)
+
+git.ro()

+ 10 - 0
preset/app/swremote.py

@@ -0,0 +1,10 @@
+localrep = "/home/backup"
+remote_url = "https://git.cocorobo.cn/liushuai/CocoPi_upgrade.git"
+
+import git
+
+git.rw()
+
+git.swRemote(localrep, remote_url)
+
+git.ro()

+ 18 - 0
preset/config/banner

@@ -0,0 +1,18 @@
+=========================================================
+    ______                         ______
+   /\  _  \                       /\  _  \  __
+   \ \ \/\_\    ____    ____   ___\ \ \_\ \/\_\
+    \ \ \/_/_  / __ \  / __ \ / __'\ \  __/\/_/_
+     \ \ \_\ \/\ \_\ \/\ \__//\ \_\ \ \ \/   /\ \
+      \ \____/\ \____/\ \____\ \____/\ \_\   \ \_\
+       \/___/  \/___/  \/____/\/___/  \/_/    \/_/
+  __
+ /\ \       __                           ----------------
+ \ \ \     /\_\    ____  __  __  __  _    pi.cocorobo.cn
+  \ \ \    \/_/_ /  _  \/\ \/\ \/\ \/ \  ----------------
+   \ \ \____ /\ \/\ \/\ \ \ \_\ \/>  </   SYSTEM VERSION
+    \ \_____\\ \_\ \_\ \_\ \____//\_/\_\ -  V6 24.0808  -
+     \/_____/ \/_/\/_/\/_/\/___/ \//\/_/ ----------------
+
+=========================================================
+

+ 198 - 0
preset/config/update.py

@@ -0,0 +1,198 @@
+#version:       2024.03.16
+
+import os
+import time
+
+time.sleep(1)
+#关闭全部应用
+print("Close app!")
+os.system("touch /tmp/disable")
+
+#获取/root/下所有文件最高操作权限
+print("Get root authority!")
+os.system("sync")
+os.system("chmod 777 /root/")
+
+
+try:
+    print("Start remove /root/CocoPi_intro_manual.pdf!")
+    os.system("rm /root/CocoPi_intro_manual.pdf")
+    print("remove /root/CocoPi_intro_manual.pdf successful!")
+except:
+    print("remove /root/CocoPi_intro_manual.pdf failed!")
+
+try:
+    print("Start remove /root/CocoPi_intro_manual.html!")
+    os.system("rm /root/CocoPi_intro_manual.html")
+    print("remove /root/CocoPi_intro_manual.html successful!")
+except:
+    print("remove /root/CocoPi_intro_manual.html failed!")
+
+try:
+    print("Start remove /root/main.py!")
+    os.system("rm /root/main.py")
+    print("remove /root/main.py successful!")
+except:
+    print("remove /root/main.py failed!")
+
+
+
+try:
+    print("Start remove /root/CocoPi.py!")
+    os.system("rm /root/CocoPi.py")
+    print("remove /root/CocoPi.py successful!")
+except:
+    print("remove /root/CocoPi.py failed!")
+
+try:
+    print("Start remove /home/backup/CocoPi.py!")
+    os.system("rm /home/backup/CocoPi.py")
+    print("remove /home/backup/CocoPi.py successful!")
+except:
+    print("remove /home/backup/CocoPi.py failed!")
+
+try:
+    print("Start remove /home/backup/main.py!")
+    os.system("rm /home/backup/main.py")
+    print("remove /home/backup/main.py successful!")
+except:
+    print("remove /home/backup/main.py failed!")
+
+try:
+    print("Start remove /home/backup/CocoPi_intro_manual.html!")
+    os.system("rm /home/backup/CocoPi_intro_manual.html")
+    print("remove /home/backup/CocoPi_intro_manual.html successful!")
+except:
+    print("remove /home/backup/CocoPi_intro_manual.html failed!")
+
+try:
+    print("Start remove /home/backup/CocoPi_intro_manual.pdf!")
+    os.system("rm /home/backup/CocoPi_intro_manual.pdf")
+    print("remove /home/backup/CocoPi_intro_manual.pdf successful!")
+except:
+    print("remove /home/backup/CocoPi_intro_manual.pdf failed!")
+
+try:
+    print("Start remove /home/backup/readme.txt!")
+    os.system("rm /home/backup/readme.txt")
+    print("remove /home/backup/readme.txt successful!")
+except:
+    print("remove /home/backup/readme.txt failed!")
+
+try:
+    print("Start remove /home/backup/user_latest_code.png!")
+    os.system("rm /home/backup/user_latest_code.png")
+    print("remove /home/backup/user_latest_code.png successful!")
+except:
+    print("remove /home/backup/user_latest_code.png failed!")
+
+try:
+    print("Start remove /home/backup/user_latest_code.xml!")
+    os.system("rm /home/backup/user_latest_code.xml")
+    print("remove /home/backup/user_latest_code.xml successful!")
+except:
+    print("remove /home/backup/user_latest_code.xml failed!")
+
+try:
+    print("Start remove /home/backup/user_latest_code.py!")
+    os.system("rm /home/backup/user_latest_code.py")
+    print("remove /home/backup/user_latest_code.py successful!")
+except:
+    print("remove /home/backup/user_latest_code.py failed!")
+
+try:
+    print("Start remove /home/backup/preset/!")
+    os.system("rm -r /home/backup/preset/")
+    print("remove /home/backup/preset/ successful!")
+except:
+    print("remove /home/backup/preset/ failed!")
+
+try:
+    print("Start remove /home/backup/user/!")
+    os.system("rm -r /home/backup/user/")
+    print("remove /home/backup/user/ successful!")
+except:
+    print("remove /home/backup/user/ failed!")
+
+try:
+    print("Start remove /etc/banner!")
+    os.system("rm /etc/banner")
+
+    print("remove /etc/banner successful!")
+except:
+    print("remove /etc/banner failed!")
+
+try:
+    print("Start copy /root/CocoPi.pyc /home/backup/CocoPi.pyc!")
+    os.system("cp /root/CocoPi.pyc /home/backup/CocoPi.pyc")
+    print("copy /root/CocoPi.pyc /home/backup/CocoPi.pyc successful!")
+except:
+    print("copy /root/CocoPi.pyc /home/backup/CocoPi.pyc failed!")
+
+try:
+    print("Start move /root/main1.py /root/main.py!")
+    os.system("mv /root/main1.py /root/main.py")
+    print("move /root/main1.py /root/main.py successful!")
+except:
+    print("move /root/main1.py /root/main.py failed!")
+
+try:
+    print("Start copy /root/main.py /home/backup/main.py!")
+    os.system("cp /root/main.py /home/backup/main.py")
+    print("copy /root/main.py /home/backup/main.py successful!")
+except:
+    print("copy /root/main.py /home/backup/main.py failed!")
+
+
+try:
+    print("Start move /root/banner /etc/banner!")
+    os.system("mv /root/banner /etc/banner")
+    print("move /root/banner /etc/banner successful!")
+except:
+    print("move /root/banner /etc/banner failed!")
+
+#升级摄像头固件
+try:
+    print("Start update camera fireware!")
+    os.system("update_dtb /dev/mmcblk0 /root/CR5205.dtb")
+    print("Update camera fireware successfully!")
+except:
+    print("Update camera fireware failed!")
+    pass
+print("Update camera fireware completed!")
+
+#更新摄像头配置
+try:
+    print("Start update camera cfg!")
+    os.system("mv /root/libisp_ini.so /usr/lib/eyesee-mpp/libisp_ini.so")
+    print("Update camera cfg successfully!")
+except:
+    print("Update camera cfg failed!")
+    pass
+print("Update camera cfg completed!")
+
+
+#删除摄像头升级文件
+try:
+    print("Start remove camera fireware!")
+    os.system("rm /root/CR5205.dtb")
+    print("Remove update files successfully!")
+except:
+    print("Remove update files failed!")
+    pass
+print("Remove update files completed!")
+
+#创建摄像头型号文件
+try:
+    print("Start touch camera cfg!")
+    os.system("touch /etc/cameraSize.cfg")
+    print("Touch camera cfg successfully!")
+except:
+    print("touch camera cfg failed!")
+    pass
+print("Touch camera cfg completed!")
+
+
+
+print("update completed! !")
+os.system("sync && reboot")

BIN
preset/drivers/ASR/CocoPi_Asr_Model/CocoPi_Asr_Model_V2.1.bin


+ 40 - 0
preset/drivers/ASR/CocoPi_Asr_Model/CocoPi_Asr_Model_V2.1.param

@@ -0,0 +1,40 @@
+7767517
+38 38
+Input                    the_inputs               0 1 the_inputs_blob 0=80 1=192 2=1 -23328=1,1129045493 -23329=1,146.879105
+Convolution              CNNLayer/Layer0/conv2d_0 1 1 the_inputs_blob CNNLayer/Layer0/bn_0_blob 0=32 1=3 4=1 5=1 6=288 20=1 21=53 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,42.510239
+ReLU                     CNNLayer/Layer0/act_0    1 1 CNNLayer/Layer0/bn_0_blob CNNLayer/Layer0/act_0_blob 20=1 21=18174 22=11 23=1 -23328=1,1 -23329=1,377.228546
+Convolution              CNNLayer/Layer0/conv2d_1 1 1 CNNLayer/Layer0/act_0_blob CNNLayer/Layer0/bn_1_blob 0=32 1=3 3=2 15=1 16=1 5=1 6=9216 20=1 21=54 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,115.930809
+ReLU                     CNNLayer/Layer0/act_1    1 1 CNNLayer/Layer0/bn_1_blob CNNLayer/Layer0/act_1_blob 20=1 21=16952 22=13 23=1 -23328=1,1 -23329=1,239.896164
+Convolution              CNNLayer/Layer1/conv2d_0 1 1 CNNLayer/Layer0/act_1_blob CNNLayer/Layer1/bn_0_blob 0=64 1=3 4=1 5=1 6=18432 20=1 21=62 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,102.771324
+ReLU                     CNNLayer/Layer1/act_0    1 1 CNNLayer/Layer1/bn_0_blob CNNLayer/Layer1/act_0_blob 20=1 21=19335 22=13 23=1 -23328=1,1 -23329=1,242.566650
+Convolution              CNNLayer/Layer1/conv2d_1 1 1 CNNLayer/Layer1/act_0_blob CNNLayer/Layer1/bn_1_blob 0=64 1=3 4=1 5=1 6=36864 20=1 21=75 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,128.985413
+ReLU                     CNNLayer/Layer1/act_1    1 1 CNNLayer/Layer1/bn_1_blob CNNLayer/Layer1/act_1_blob 20=1 21=23371 22=14 23=1 -23328=1,1 -23329=1,183.991562
+Convolution              CNNLayer/Layer1/conv2d_2 1 1 CNNLayer/Layer1/act_1_blob CNNLayer/Layer1/bn_2_blob 0=64 1=3 4=1 5=1 6=36864 20=1 21=91 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,101.899826
+ReLU                     CNNLayer/Layer1/act_2    1 1 CNNLayer/Layer1/bn_2_blob CNNLayer/Layer1/act_2_blob 20=1 21=19583 22=14 23=1 -23328=1,1 -23329=1,121.794250
+Convolution              CNNLayer/Layer1/conv2d_3 1 1 CNNLayer/Layer1/act_2_blob CNNLayer/Layer1/bn_3_blob 0=64 1=3 3=2 15=1 16=1 5=1 6=36864 20=1 21=42 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,50.628410
+ReLU                     CNNLayer/Layer1/act_3    1 1 CNNLayer/Layer1/bn_3_blob CNNLayer/Layer1/act_3_blob 20=1 21=22749 22=14 23=1 -23328=1,1 -23329=1,70.297211
+Convolution              CNNLayer/Layer2/conv2d_0 1 1 CNNLayer/Layer1/act_3_blob CNNLayer/Layer2/bn_0_blob 0=128 1=3 4=1 5=1 6=73728 20=1 21=56 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,41.081566
+ReLU                     CNNLayer/Layer2/act_0    1 1 CNNLayer/Layer2/bn_0_blob CNNLayer/Layer2/act_0_blob 20=1 21=25403 22=14 23=1 -23328=1,1 -23329=1,63.695854
+Convolution              CNNLayer/Layer2/conv2d_1 1 1 CNNLayer/Layer2/act_0_blob CNNLayer/Layer2/bn_1_blob 0=128 1=3 4=1 5=1 6=147456 20=1 21=127 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,35.993683
+ReLU                     CNNLayer/Layer2/act_1    1 1 CNNLayer/Layer2/bn_1_blob CNNLayer/Layer2/act_1_blob 20=1 21=28004 22=14 23=1 -23328=1,1 -23329=1,61.522362
+Convolution              CNNLayer/Layer2/conv2d_2 1 1 CNNLayer/Layer2/act_1_blob CNNLayer/Layer2/bn_2_blob 0=128 1=3 4=1 5=1 6=147456 20=1 21=60 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,34.816036
+ReLU                     CNNLayer/Layer2/act_2    1 1 CNNLayer/Layer2/bn_2_blob CNNLayer/Layer2/act_2_blob 20=1 21=27511 22=14 23=1 -23328=1,1 -23329=1,58.461849
+Convolution              CNNLayer/Layer2/conv2d_3 1 1 CNNLayer/Layer2/act_2_blob CNNLayer/Layer2/bn_3_blob 0=128 1=3 3=2 15=1 16=1 5=1 6=147456 20=1 21=53 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,24.326862
+ReLU                     CNNLayer/Layer2/act_3    1 1 CNNLayer/Layer2/bn_3_blob CNNLayer/Layer2/act_3_blob 20=1 21=19057 22=14 23=1 -23328=1,1 -23329=1,28.295811
+Convolution              CNNLayer/Layer3/conv2d_0 1 1 CNNLayer/Layer2/act_3_blob CNNLayer/Layer3/bn_0_blob 0=256 1=3 4=1 5=1 6=294912 20=1 21=86 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,23.165630
+ReLU                     CNNLayer/Layer3/act_0    1 1 CNNLayer/Layer3/bn_0_blob CNNLayer/Layer3/act_0_blob 20=1 21=21833 22=14 23=1 -23328=1,1 -23329=1,30.869581
+Convolution              CNNLayer/Layer3/conv2d_1 1 1 CNNLayer/Layer3/act_0_blob CNNLayer/Layer3/bn_1_blob 0=256 1=3 4=1 5=1 6=589824 20=1 21=57 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,14.938457
+ReLU                     CNNLayer/Layer3/act_1    1 1 CNNLayer/Layer3/bn_1_blob CNNLayer/Layer3/act_1_blob 20=1 21=25376 22=14 23=1 -23328=1,1 -23329=1,23.137289
+Convolution              CNNLayer/Layer3/conv2d_2 1 1 CNNLayer/Layer3/act_1_blob CNNLayer/Layer3/bn_2_blob 0=256 1=3 4=1 5=1 6=589824 20=1 21=53 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,6.515434
+ReLU                     CNNLayer/Layer3/act_2    1 1 CNNLayer/Layer3/bn_2_blob CNNLayer/Layer3/act_2_blob 20=1 21=20284 22=14 23=1 -23328=1,1 -23329=1,8.066409
+Convolution              CNNLayer/Layer3/conv2d_3 1 1 CNNLayer/Layer3/act_2_blob CNNLayer/Layer3/bn_3_blob 0=256 1=3 4=1 5=1 6=589824 20=1 21=274 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,3.419349
+ReLU                     CNNLayer/Layer3/act_3    1 1 CNNLayer/Layer3/bn_3_blob CNNLayer/Layer3/act_3_blob 20=1 21=21679 22=13 23=1 -23328=1,1 -23329=1,9.049037
+Convolution              CNNLayer/Layer3/conv2d_4 1 1 CNNLayer/Layer3/act_3_blob CNNLayer/Layer3/bn_4_blob 0=256 1=3 4=1 5=1 6=589824 20=1 21=241 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,3.201896
+ReLU                     CNNLayer/Layer3/act_4    1 1 CNNLayer/Layer3/bn_4_blob CNNLayer/Layer3/act_4_blob 20=1 21=24244 22=12 23=1 -23328=1,1 -23329=1,18.951967
+Convolution              CNNLayer/Layer3/conv2d_5 1 1 CNNLayer/Layer3/act_4_blob CNNLayer/Layer3/bn_5_blob 0=256 1=3 4=1 5=1 6=589824 20=1 21=244 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,10.851162
+ReLU                     CNNLayer/Layer3/act_5    1 1 CNNLayer/Layer3/bn_5_blob CNNLayer/Layer3/act_5_blob 20=1 21=32485 22=14 23=1 -23328=1,1 -23329=1,21.514734
+Permute                  Permute0                 1 1 CNNLayer/Layer3/act_5_blob Permute0_blob 0=3 -23328=1,0 -23329=1,21.514734
+Reshape                  Reshape0                 1 1 Permute0_blob Reshape0_blob 0=2560 1=1 2=24 -23328=1,0 -23329=1,21.514734
+Permute                  Permute1                 1 1 Reshape0_blob Permute1_blob 0=4 -23328=1,0 -23329=1,21.514734
+Convolution              FC                       1 1 Permute1_blob FC_bn_blob 0=1250 1=1 5=1 6=3200000 20=1 21=28 22=15 23=0 24=2 25=1 -23328=1,1 -23329=1,0.956139
+Reshape                  Reshape1                 1 1 FC_bn_blob Reshape1_blob 0=1250 1=24 3=1 -23328=1,0 -23329=1,0.956139

BIN
preset/drivers/ASR/Pinyin_Lexicon/Pinyin_Lexicon.bin


BIN
preset/drivers/ASR/Pinyin_Lexicon/Pinyin_Lexicon.sfst


BIN
preset/drivers/ASR/Pinyin_Lexicon/Pinyin_Lexicon.sym


BIN
preset/drivers/ASR/Pinyin_Lexicon/Pinyin_Lexicon_Words.bin


BIN
preset/drivers/ASR/Pinyin_Lexicon/Pinyin_Lexicon_Words_utf.bin


BIN
preset/drivers/CR5205/CR5205.dtb


BIN
preset/drivers/CR5205/libisp_ini.so


BIN
preset/drivers/CR9685/CR9685.dtb


BIN
preset/drivers/CR9685/libisp_ini.so


BIN
preset/drivers/HCSR04/hcsr04.ko


BIN
preset/drivers/UVC/_coco_camera.so


+ 183 - 0
preset/drivers/pylib/GPTrequest.py

@@ -0,0 +1,183 @@
+##################################
+#            GPTrequest          #
+##################################
+#Version date   :       2024-07-08
+#region         :       CH
+
+import uuid
+import requests
+import json
+import base64
+import os
+
+try:
+    class LazyImport:
+        def __init__(self, module_name):
+            self.module_name = module_name
+            self.module = None
+        def __getattr__(self, name):
+            if self.module is None:
+                self.module = __import__(self.module_name)
+            return getattr(self.module, name)
+    uuid = LazyImport("uuid")
+    requests = LazyImport("requests")
+    json = LazyImport("json")
+    base64 = LazyImport("base64")
+
+except ModuleNotFoundError as e:
+    pass
+
+class GPTrequest():
+    def __init__(self):
+        self.uid = str(uuid.uuid1().hex)
+        #获取hardware mac地址
+        cmd="cat /sys/class/sunxi_info/sys_info"
+        rec=os.popen(cmd).read()
+        self.hwMac=rec[rec.find("sunxi_serial      : ")+20:rec.find("sunxi_serial      : ")+52]
+        print(self.hwMac)
+       
+    # 文字生成图片
+    def get_text_to_img(self,text):
+        uid = str(uuid.uuid1().hex)
+        param = {
+            "size": "1024x1024",
+            "quality": "standard",
+            "n": 1,
+            "prompt": text,
+            "style":"natural",
+            "uid": uid
+        }
+        headers={
+            "Content-Type":"application/json",
+            "hwMac":self.hwMac
+        }
+        imgUrl = ""
+        res = requests.post("https://gpt4.cocorobo.cn/getImageV831", headers=headers, json=param)
+        try:
+            url = (json.loads(res.text))["FunctionResponse"]["image_url_list"][0]
+            r = requests.get("https://gpt4.cocorobo.cn"+url)
+            with open("/root/user/img/" + uid + ".png","wb") as f:
+                f.write(r.content)
+            imgUrl = "/root/user/img/" + uid + ".png"
+        except:
+            imgUrl = ""
+        return imgUrl
+     
+    # 图片转base64
+    def encode_image(self,image_path):
+        img_data = ""
+        try:
+            with open(image_path, "rb") as f:
+                img_data = f.read()
+        except:
+            pass
+        return str(base64.b64encode(img_data), "utf-8")
+
+    # 通过图片获取文字
+    def get_image_to_text(self,imgUrl,textDesc):
+        uid = str(uuid.uuid1().hex)
+        strBase = self.encode_image(imgUrl)
+        params = {
+            "max_tokens": 4096,
+            "messages":[
+                {
+                    "role": "user",
+                    "content":[
+                        {"text": textDesc,"type": "text"},
+                        {"image_url": {"url": f"data:image/jpeg;base64,{strBase}"},"type": "image_url"}
+                    ]
+                }
+            ],
+            "uid": uid,
+            "stream": False
+        }
+        headers={
+            "Content-Type":"application/json",
+            "hwMac":self.hwMac
+        }
+        textContent = ""
+        res = requests.post("https://gpt4.cocorobo.cn/imageAnalyse", headers=headers, data=json.dumps(params))
+        try:
+            if res.status_code == 200:
+                textContent = json.loads(res.text)["FunctionResponse"]["choices"][0]["message"]["content"]
+                
+        except:
+            textContent = ""
+        return textContent
+    
+    # 文字生成音頻文件
+    def get_text_to_voice(self,text):
+        uid = str(uuid.uuid1().hex)
+        url = "https://gpt4.cocorobo.cn/getV831Audio"
+        payload = json.dumps({"input": text,"response_format":"mp3","voice": "shimmer","uid":uid})
+        
+        headers={
+            "Content-Type":"application/json",
+            "hwMac":self.hwMac
+        }
+        response=requests.request("POST", url, headers=headers, data=payload)
+        voiceFilePath = ""
+        try:
+            if response.status_code == 200:
+                # print(json.loads(response.text)["FunctionResponse"]["url"])
+                a = "https://gpt4.cocorobo.cn" + json.loads(response.text)["FunctionResponse"]["url"]
+                r = requests.get(a)
+                with open("/root/preset/audio/" + uid+".wav","wb") as f:
+                    f.write(r.content)
+                voiceFilePath = "/root/preset/audio/" + uid+".wav"
+        except:
+            voiceFilePath = ""
+        return voiceFilePath
+    
+    # 音频转文字
+    def get_voice_to_text(self,voicePath):
+        voiceData = open(voicePath,'rb')
+        data = {"file": voiceData}
+        param = {}
+        headers={
+            "hwMac":self.hwMac
+        }
+        res = requests.post("https://gpt4.cocorobo.cn/transcribe_file_stream",headers=headers, files=data, data=param)
+        try:
+            voiceResult = (json.loads(res.text))["FunctionResponse"]
+        except:
+            voiceResult = ""
+        return voiceResult
+
+    # gpt 對話,並生成音頻文件
+    def get_post_chatgpt(self,datas):
+        url = "https://gpt4.cocorobo.cn/v831AskForTopicNew"
+        payload = json.dumps({"topic": datas})
+        headers={
+            "Content-Type":"application/json",
+            "hwMac":self.hwMac
+        }
+        response=requests.request("POST", url, headers=headers, data=payload)
+        result = ""
+        try:
+            result = json.loads(response.text)["FunctionResponse"]["result"]
+        except:
+            result = ""
+        # print("resule:"+str(result))
+        return result
+    
+    
+    def get_post_AI_Intelligence(self,id,text):
+        url = "https://gpt4.cocorobo.cn/ai_agent_chat"
+        params = {
+            "id":id,
+            "userId":self.hwMac,
+            "message":text,
+            "file_ids": []
+        }
+        headers={
+            "Content-Type":"application/json",
+            "hwMac":self.hwMac
+        }
+        textContent = ""
+        res = requests.post(url, headers=headers, data=json.dumps(params))
+        try:
+            textContent = json.loads(res.text)["FunctionResponse"]["message"]
+        except:
+            textContent = ""
+        return textContent

BIN
preset/img/animal/animal1.jpg


BIN
preset/img/animal/animal10.jpg


BIN
preset/img/animal/animal11.jpg


BIN
preset/img/animal/animal12.jpg


BIN
preset/img/animal/animal13.jpg


BIN
preset/img/animal/animal14.jpg


BIN
preset/img/animal/animal15.jpg


BIN
preset/img/animal/animal16.jpg


BIN
preset/img/animal/animal17.jpg


BIN
preset/img/animal/animal18.jpg


BIN
preset/img/animal/animal19.jpg


BIN
preset/img/animal/animal2.jpg


BIN
preset/img/animal/animal20.jpg


BIN
preset/img/animal/animal21.jpg


BIN
preset/img/animal/animal22.jpg


BIN
preset/img/animal/animal23.jpg


BIN
preset/img/animal/animal24.jpg


BIN
preset/img/animal/animal25.jpg


BIN
preset/img/animal/animal26.jpg


BIN
preset/img/animal/animal27.jpg


BIN
preset/img/animal/animal28.jpg


BIN
preset/img/animal/animal29.jpg


BIN
preset/img/animal/animal3.jpg


BIN
preset/img/animal/animal30.jpg


BIN
preset/img/animal/animal31.jpg


BIN
preset/img/animal/animal32.jpg


BIN
preset/img/animal/animal33.jpg


BIN
preset/img/animal/animal34.jpg


BIN
preset/img/animal/animal35.jpg


BIN
preset/img/animal/animal36.jpg


BIN
preset/img/animal/animal4.jpg


BIN
preset/img/animal/animal5.jpg


Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov