Navigation

    全志在线开发者论坛

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • 社区主页
    1. Home
    2. kw___
    K
    • Profile
    • Following 0
    • Followers 0
    • my integral 312
    • Topics 2
    • Posts 6
    • Best 1
    • Groups 0

    kw___LV 3

    @kw___

    312
    integral
    2
    Reputation
    6
    Profile views
    6
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    kw___ Unfollow Follow

    Best posts made by kw___

    • 基于D1开发板的 微信/支付宝 物联网(MQTT)支付平台

      准备工作(支付宝沙盒信息获取)

      登录 开发者中心控制台 (alipay.com) 使用支付宝进行登录。

      image-20211116231806340.png

      进入沙箱环境 开放平台-沙箱环境 (alipay.com)

      image-20211116232045464.png

      如果《RSA2密钥(公钥模式) 》的查看是灰色的,点击启用。点击查看可获取应用公钥,应用私钥和支付宝公钥。

      image-20211116232249649.png

      下载并安装沙盒版的支付宝应用。通过提供的账号登录沙盒版支付宝,进行付款。

      image-20211116232448676.png
      image-20211116232613047.png

      (微信个人无法申请 APPID 等信息,且没有提供沙盒平台,所以无法进行测试。提供的 JAR 包里面是有晕哥提供的 APPID 等信息,可以进行测试。提供的 java 源码已经将微信的 APPID 等信息删除)

      服务器端搭建

      linux 平台搭建

      sudo apt install openjdk-8-jdk mosquitto
      

      修改 D1PayServer.jar 压缩包中的 zfbinfo.properties 文件,将 appid,public_key(应用公钥),private_key(应用私钥),alipay_public_key(支付宝公钥)替换成自己支付宝沙盒提供的。

      image-20211117164251960.png

      然后将 D1PayServer.jar 上传至 linux 平台运行。

      java -jar D1PayServer.jar
      

      运行效果:

      image-20211117164122389.png

      客户端运行

      烧写 tina_d1-nezha_uart0.img 镜像,内核已经修改为默认 HDMI 输出,分辨率为 480P(720x480)。

      连接 wifi

      wifi_connect_ap_test GL-MT300N-V2-0be goodlife
      

      修改应用配置文件:

      vim /bin/D1Pay/D1PayClientConfig.json
      
      {
          "device_id":"kw",
          "mqtt_server_ip":"192.168.8.108", 
          "mqtt_sub_top":"d1_pay_client",
          "mqtt_pub_top":"d1_pay_server",
          "fb":"/dev/fb0",
          "input":"/dev/input/event2"
      }
      
      

      修改 mqtt_server_ip 为自己的 mqtt 服务器的地址,input 修改为自己的触摸设配。

      运行应用程序

      root@TinaLinux:/# d1_pay_launche
      

      image-20211117170015046.png

      运行效果(使用的HDMI屏幕,拥有触摸,分辨率 800x480),完成支付后将会播报语音以及控制一个 GPIO 输出 5 秒的高电平。

      image-20211117211305734.png

      image-20211117211337299.png

      image-20211117211354427.png

      客户端添加一个商品信息

      商品信息保存在 /bin/D1Pay/ProductList/ 目录下,每一件商品对应一个文件夹。每一个文件夹都有 Image.png ProductDescribe.txt文件,Image.png为 350x350 像素的商品图片,ProductDescribe.txt为描述文件,包含商品名,价格,付款成功后控制的 GPIO,以及商品详细介绍。

      .
      ├── D1 Board
      │   ├── Image.png
      │   └── ProductDescribe.txt
      ├── D1 IC
      │   ├── Image.png
      │   └── ProductDescribe.txt
      └── XR806 Board
          ├── Image.png
          └── ProductDescribe.txt
      

      ProductDescribe.txt 文件第一行为商品名字,第二行为价格(价格必须保留小数两位),第三(商品id)行为付款成功后控制的 GPIO(1-GPIOD11, 2-GPIO12, 3-GPIO13)。余下信息均为商品描述信息。

      cat D1 Board/ProductDescribe.txt
      D1 Board
      599.99
      1
      CPU : C906 64bit RISC-V 32 KB I-cache + 32 KB D-cache
      DSP :
      HiFi4 DSP  600MHz
      32 KB I-cache + 32 KB D-cache
      64 KB I-ram + 64 KB D-ram
      Memory :
      DDR2/DDR3, up to 2 GB
      SD3.0/eMMC 5.0, SPI Nor/Nand Flash
      

      客户端与服务端数据交互格式

      通信数据采用 json 数据,定义的数据存在多余的,部分并没有使用到

      客户端发送订单信息至服务器

      {
      	"device_id":"kw",           设备id
      	"msg_type":"0",             0客户端发送订单 1服务器返回收款信息至客户端 2支付成功服务器返回至客户端
      	"product_id":"1",           商品id 用于控制 GPIO
      	"product_name":"D1 IC",     商品名称
      	"pay_way":"0",              0支付宝 1微信
      	"price":"34.97"             价格
      }
      

      服务器返回生成的支付二维码信息至客户端

      {
      	"device_id":"kw",                设备id
      	"msg_type":"1",                  0客户端发送订单 1服务器返回收款信息至客户端 2支付成功服务器返回至客户端	
      	"product_id":"1",                商品id 用于控制 GPIO
      	"pay_way":"0",                   0支付宝 1微信
      	"return":"ok", 					 ok err
      	"price":"34.97",                 价格
      	"out_trade_no":"63827381363",    订单号
      	"pay_qrcode":"xxxweduwqcfgy3t72" 用于生成二维码
      }
      

      支付成功服务器返回至客户端,支付失败则不返回

      {
      	"device_id":"kw",              设备id
      	"msg_type":"2",                0客户端发送订单 1服务器返回收款信息至客户端 2支付成功服务器返回至客户端	
      	"product_id":"1",              商品id 用于控制 GPIO
      	"pay_way":"0",                 0支付宝 1微信
      	"return":"ok",                 ok err
      	"price":"34.97",               价格
      	"out_trade_no":"63827381363"   订单号 
      }
      

      服务器端工程结构

      eva@ubuntu:~/Desktop/d1_pay_server_master$ tree
      .
      ├── D1PayServer
      │   ├── pom.xml
      │   ├── resource
      │   │   └── zfbinfo.properties
      │   ├── src
      │   │   ├── main
      │   │   │   └── java
      │   │   │       └── com
      │   │   │           └── nuist
      │   │   │               └── kw
      │   │   │                   └── D1PayServer
      │   │   │                       ├── AliPayThread.java
      │   │   │                       ├── App.java
      │   │   │                       ├── CommonUtils.java
      │   │   │                       ├── MyConfig.java
      │   │   │                       ├── OrderInformation.java
      │   │   │                       ├── PaymentInformation.java
      │   │   │                       ├── PayThread.java
      │   │   │                       ├── ResultInformation.java
      │   │   │                       └── WxPayThread.java
      
      

      zfbinfo.properties 保存支付宝 APPID 等信息

      App.java 初始化一个 mqtt 服务器,main 入口

      MyConfig.java 微信 APPID 等信息

      PayThread.java 当 mqtt 服务器收到一个订单消息,进行判断是支付宝支付,还是微信支付,然后开启相应的支付处理线程

      AliPayThread.java 支付宝支付线程,负责请求支付二维码,循环判断订单支付结果,3 分钟未支付,则不再处理。

      WxPayThread.java 微信支付线程,负责请求支付二维码,循环判断订单支付结果,3 分钟未支付,则不再处理。

      OrderInformation.java PaymentInformation.java ResultInformation.java 负责构造通信数据字符串。

      Maven 项目依赖

      <!-- 微信sdk -->
      <dependency>    
      <groupId>com.github.wxpay</groupId>    
      <artifactId>wxpay-sdk</artifactId>    
      <version>0.0.3</version>
      </dependency>
      <!-- 支付宝sdk -->
      <dependency>
      <groupId>com.alipay.sdk</groupId>
      <artifactId>alipay-sdk-java</artifactId>
      <version>4.10.209.ALL</version>
      </dependency>
      <!-- mqtt sdk -->
      <dependency>
      <groupId>org.eclipse.paho</groupId>
      <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
      <version>1.2.5</version>
      </dependency>
      <!-- json -->
      <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.47</version>
      </dependency>
      

      客户端工程结构

      客户端代码结构如下,app 存放的是应用代码,build 存放的是编译生成的 .o 文件以及顶层 Makefile(使用的百问网的 lvgl 移植的 Makefile),build.sh 编译脚本,lirary 存放的是库源码,Makefile 硬链接指向 build/Makefile,out 为输出的应用程序目录。

      eva@ubuntu:~/Desktop/d1_pay_client$
      .
      ├── app
      │   ├── app.mk
      │   ├── include
      │   ├── launcher_ui.c   # UI 界面
      │   ├── launcher_ui.h   
      │   ├── lv_drv_init.c   # 驱动初始化
      │   ├── lv_drv_init.h
      │   ├── main.c          # 程序入口
      │   ├── mqtt_client.c   # mqtt 客户端初始化 数据处理
      │   ├── mqtt_client.h
      │   ├── pin_control.c   # 引脚控制,增加引脚修改该文件
      │   ├── pin_control.h
      │   ├── play_pay_result.c # 语音播报
      │   ├── play_pay_result.h
      │   ├── untilities.c     # 提供一些函数
      │   └── untilities.h
      ├── build
      │   └── Makefile
      ├── build.sh
      ├── lirary
      ├── Makefile
      └── out
          ├── bin
          ├── etc
          └── lib
      
      

      build.sh 中指定编译工具链,通过 ./build.sh 进行编译,./build.sh clean 进行清除编译中间文件。

      修改引脚修改 pin_control.c 如下部分(计算公式 32*n+i)

      image-20211117231147776.png

      mosquitto编译

      应用程序使用了 mosquitto 库,build.sh并不会去编译它,所以这个需要单独编译,编译完成后,将库拷贝到 out/lib 目录下。mosquitto 在 lirary 目录下,在 lirary 目录下新建一个 mosquitto-risc 目录,用于保存编译输出文件。

      设置交叉编译工具链

      vim ~/.bashrc
      export PATH=$PATH:/home/eva/d1/D1/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/bin/
      source ~/.bashrc
      

      交叉编译 uuid

      tar -vxf libuuid-1.0.3.tar.gz
      ./configure --prefix=/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc CC=riscv64-unknown-linux-gnu-gcc --host=riscv64-unknown-linux-gnu
      
      make && make install
      

      交叉编译 openssl 库

      tar -vxf openssl-1.0.2g.tar.gz
      ./config no-asm shared --prefix=/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc
      #删除Makefile中的-m64(一共有两个),修改Makefile中的
      CC= riscv64-unknown-linux-gnu-gcc
      AR= riscv64-unknown-linux-gnu-ar $(ARFLAGS) r
      RANLIB= riscv64-unknown-linux-gnu-ranlib
      NM= riscv64-unknown-linux-gnu-nm
      
      make && make install
      

      交叉编译 mosquitto

      tar -vxf mosquitto-1.5.tar.gz
      
      make WITH_SRV=no CC=riscv64-unknown-linux-gnu-gcc CXX=riscv64-unknown-linux-gnu-g++ CFLAGS="-I /home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc/include -I /home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc/include" LDFLAGS="-L/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc/lib -L/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc/lib -lssl -lcrypto -luuid"
      
      make DESTDIR=/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc install
      

      D1 内核配置

      配置编译环境

      source build/envsetup.sh
      lunch d1_nezha-tina
      

      开启 nfs

      make kernel_menuconfig
      
      File systems  --->
      	[*] Network File Systems  --->     
        │ │    <*>   NFS client support                                         │ │  
        │ │    <*>     NFS client support for NFS version 2                     │ │  
        │ │    [*]     NFS client support for NFS version 3                     │ │  
        │ │    [*]       NFS client support for the NFSv3 ACL protocol extension│ │  
        │ │    [*]     NFS client support for NFS version 4                     │ │  
        │ │    [*]   NFS client support for NFSv4.1                             │ │  
        │ │    [*]     NFS client support for NFSv4.2                           │ │  
        │ │    (kernel.org) NFSv4.1 Implementation ID Domain                    │ │  
        │ │    [*]     NFSv4.1 client support for migration                     │ │  
        │ │    [*]   Use the legacy NFS DNS resolver
      

      修改开机默认 HDMI 输出(如果开机不是默认 HDMI 输出,开机后再启动 HDMI 输出,会输出有问题)

      修改 uboot 设备树文件

      ./D1/device/config/chips/d1/configs/nezha/uboot-board.dts
      
      214 行
              disp_init_enable         = <1>;
              disp_mode                = <0>;
      
      -       screen0_output_type      = <1>;
      -       screen0_output_mode      = <4>;
      -
      -       screen1_output_type      = <3>;
      -       screen1_output_mode      = <10>;
      -
      -       screen1_output_format    = <0>;
      -       screen1_output_bits      = <0>;
      -       screen1_output_eotf      = <4>;
      -       screen1_output_cs        = <257>;
      -       screen1_output_dvi_hdmi  = <2>;
      -       screen1_output_range     = <2>;
      -       screen1_output_scan      = <0>;
      -       screen1_output_aspect_ratio = <8>;
      -
      -       dev0_output_type         = <1>;
      -       dev0_output_mode         = <4>;
      +    screen0_output_type      = <3>;
      +    screen0_output_mode      = <10>;
      +
      +    screen0_output_format    = <0>;
      +    screen0_output_bits      = <0>;
      +    screen0_output_eotf      = <4>;
      +    screen0_output_cs        = <257>;
      +    screen0_output_dvi_hdmi  = <2>;
      +    screen0_output_range     = <2>;
      +    screen0_output_scan      = <0>;
      +    screen0_output_aspect_ratio = <8>;
      +
      +    screen1_output_type      = <1>;
      +    screen1_output_mode      = <4>;
      +
      +    dev0_output_type         = <4>;
      +    dev0_output_mode         = <2>;
              dev0_screen_id           = <0>;
      -       dev0_do_hpd              = <0>;
      -
      -       dev1_output_type         = <4>;
      -       dev1_output_mode         = <10>;
      -       dev1_screen_id           = <1>;
      -       dev1_do_hpd              = <1>;
      +       dev0_do_hpd              = <1>;
      
              def_output_dev           = <0>;
              hdmi_mode_check          = <1>;
      

      修改 linux 设备树文件

      ./D1/device/config/chips/d1/configs/nezha/linux-5.4/board.dts
      
      1128 行
              disp_init_enable         = <1>;
              disp_mode                = <0>;
      
      -       screen0_output_type      = <1>;
      -       screen0_output_mode      = <4>;
      -
      -       screen1_output_type      = <3>;
      -       screen1_output_mode      = <10>;
      -
      -       screen1_output_format    = <0>;
      -       screen1_output_bits      = <0>;
      -       screen1_output_eotf      = <4>;
      -       screen1_output_cs        = <257>;
      -       screen1_output_dvi_hdmi  = <2>;
      -       screen1_output_range     = <2>;
      -       screen1_output_scan      = <0>;
      -       screen1_output_aspect_ratio = <8>;
      -
      -       dev0_output_type         = <1>;
      -       dev0_output_mode         = <4>;
      +    screen0_output_type      = <3>;
      +    screen0_output_mode      = <10>;
      +
      +    screen0_output_format    = <0>;
      +    screen0_output_bits      = <0>;
      +    screen0_output_eotf      = <4>;
      +    screen0_output_cs        = <257>;
      +    screen0_output_dvi_hdmi  = <2>;
      +    screen0_output_range     = <2>;
      +    screen0_output_scan      = <0>;
      +    screen0_output_aspect_ratio = <8>;
      +
      +    screen1_output_type      = <1>;
      +    screen1_output_mode      = <4>;
      +
      +    dev0_output_type         = <4>;
      +    dev0_output_mode         = <2>;
              dev0_screen_id           = <0>;
      -       dev0_do_hpd              = <0>;
      -
      -       dev1_output_type         = <4>;
      -       dev1_output_mode         = <10>;
      -       dev1_screen_id           = <1>;
      -       dev1_do_hpd              = <1>;
      +       dev0_do_hpd              = <1>;
      
              def_output_dev           = <0>;
              hdmi_mode_check          = <1>;
      

      dev0_output_mode 为分辨率,这里设置为 480P

      enum disp_tv_mode {
          DISP_TV_MOD_480I = 0,
          DISP_TV_MOD_576I = 1,
          DISP_TV_MOD_480P = 2,
          DISP_TV_MOD_576P = 3,
          DISP_TV_MOD_720P_50HZ = 4,
          DISP_TV_MOD_720P_60HZ = 5,
          DISP_TV_MOD_1080I_50HZ = 6,
          DISP_TV_MOD_1080I_60HZ = 7,
          DISP_TV_MOD_1080P_24HZ = 8,
          DISP_TV_MOD_1080P_50HZ = 9,
          DISP_TV_MOD_1080P_60HZ = 0xa,
          /***/
      

      编译 uboot

      cboot
      muboot
      

      进入顶层目录,编译其它部分

      make -j8
      pack
      

      代码,固件下载
      D1PayPack.zip

      演示视频

      posted in D1-H/D1s
      K
      kw___

    Latest posts made by kw___

    • xr806使用tcp socket与手机通信

      参考:基于星辰处理器的全志XR806开源鸿蒙开发板上手体验 - 极术社区 - 连接开发者与智能计算生态 (aijishu.com) 搭建环境。并成功编译。

      项目源码 : https://gitee.com/kingwho/smart-home

      在同一个局域网中,手机与xr806连接后,手机 APP 每隔 1s,发送按键的值给 xr806,用于控制xr806的led,然后xr806在返回按键,温度,适度(温度,适度为模拟数据)数据给手机app显示。

      将 smart_home 放入 device/xradio/xr806/ohosdemo 下的目录,并修改 device/xradio/xr806/ohosdemo/BUILD.gn 为

      group("ohosdemo") {
          deps = [
              #"hello_demo:app_hello",
              #"iot_peripheral:app_peripheral",
              #"wlan_demo:app_WlanTest",
              "smart_home:app_smart_home",
          ]
      }
      

      目录结构

      .
      ├── BUILD.gn
      └── src
          ├── main.c
          ├── tcp_net_socket.c
          └── tcp_net_socket.h
      

      使用 WIFI 编译时会报错,进行如下操作即可,在随后的编译中可能还会出现,再次如下操作执行即可。

      cd device/xradio/xr806/xr_skylark/project/demo/wlan_ble_demo/image/xr806
      cp image_wlan_ble.cfg image_wlan_ble.cfg.bk
      cat image_auto_cal.cfg > image_wlan_ble.cfg
      

      cjson使用这些宏会报错,建议直接使用 cjson 宏定义后面函数。

      #define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
      #define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
      #define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
      #define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
      #define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
      #define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
      #define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s))
      

      xr806连接WIFI后 IP地址可由串口输出打印查看

      [net INF] msg <wlan scan success>
      GetScanInfoList Success.
      AddDeviceConfig Success.
      [net INF] no need to switch wlan mode 0
      en1: Trying to associate with 94:83:c4:0e:70:be (SSID='GL-MT300N-V2-0be' freq=2437 MHz)
      ConnectTo Success
      en1: Associated with 94:83:c4:0e:70:be
      en1: WPA: Key negotiation completed with 94:83:c4:0e:70:be [PTK=CCMP GTK=CCMP]
      en1: CTRL-EVENT-CONNECTED - Connection to 94:83:c4:0e:70:be completed [id=0 id_str=]
      [net INF] msg <wlan connected>
      [net INF] netif is link up
      [net INF] start DHCP...
      [net INF] netif (IPv4) is up
      [net INF] address: 192.168.8.248
      [net INF] gateway: 192.168.8.1
      [net INF] netmask: 255.255.255.0
      [net INF] msg <network IPv6 state>
      [net INF] IPv6 addr state change: 0x0 --> 0x1
      [net INF] msg <>
      

      xr806 的固件更新后,需要使用下载器软件重新加载下固件,否则下载的可能还是上次的固件。

      BUILD.gn

      import("//device/xradio/xr806/liteos_m/config.gni")
      
      static_library("app_smart_home") {
         configs = []
         sources = [
            "src/main.c",
            "src/tcp_net_socket.c",
         ]
         cflags = board_cflags
         include_dirs = board_include_dirs
         include_dirs += [
            "//kernel/liteos_m/kernel/arch/include",
           "//base/iot_hardware/peripheral/interfaces/kits",
            "//utils/native/lite/include",
            "//foundation/communication/wifi_lite/interfaces/wifiservice",
            "//third_party/lwip/src/include",
            "//third_party/cJSON",
         ]
      }
      

      tcp_net_socket.c

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include "lwip/sockets.h"
      
      int tcp_server_init(int port)
      {
          int sfd = 0;
          struct sockaddr_in saddr;
          sfd = socket(AF_INET,SOCK_STREAM,0);
          
          memset(&saddr, 0, sizeof(struct sockaddr));
          saddr.sin_family  = AF_INET;
          saddr.sin_port    = htons(port);
          saddr.sin_addr.s_addr = INADDR_ANY;
          bind(sfd, (struct  socket*)&saddr, sizeof(struct sockaddr));
      
          listen(sfd,5);
      
          return sfd;
      }
      
      int tcp_server_accept(int sfd)
      {
          int cfd = 0;
          struct  sockaddr_in caddr;
          memset(&caddr, 0, sizeof(struct sockaddr));
          int addrl = sizeof(struct sockaddr);
          cfd = accept(sfd , (struct sockaddr*)&caddr , &addrl);
          return cfd;
      }
      

      main.c

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include "ohos_init.h"
      #include "kernel/os/os.h"
      #include "iot_gpio.h"
      #include "wifi_device.h"
      #include "cJSON.h"
      #include "lwip/sockets.h"
      #include "tcp_net_socket.h"
      
      
      static void wifi_connect(char *ssid, char *passwd);
      static OS_Thread_t g_main_thread;
      
      static void MainThread(void *arg)
      {
      
      	unsigned int led_pin = 21; /* GPIOA_PIN21 */
      	unsigned int key_pin = 11; /* GPIOA_PIN11 */
      	IotGpioValue key_value;
      	int led_value = 0;
      	unsigned int tem = 0, hum = 0, s = 0;
      	cJSON* dev_dat = NULL;
      
          int sfd = 0;
          int cfd = 0;
      	char send_buf[512] = {0};
      	char recv_buf[512] = {0};
      
      	wifi_connect("GL-MT300N-V2-0be", "goodlife");
      
      	IoTGpioInit(led_pin);
      	IoTGpioSetDir(led_pin, IOT_GPIO_DIR_OUT);
      	IoTGpioInit(key_pin);
      	IoTGpioSetDir(key_pin, IOT_GPIO_DIR_IN);
      
      	sfd = tcp_server_init(8080);
          cfd = tcp_server_accept(sfd);
      
      	while (1) {
      
      		srand( s++ );
      		tem = rand()%10 + 20;
      		hum = rand()%20 + 40;
      		IoTGpioGetInputVal(key_pin, &key_value);
      		printf("kw : hello world! key : %d tem : %d hum : %d\r\n", key_value, tem, hum);
      		IoTGpioSetOutputVal(led_pin, led_value);
      
      		recv(cfd, recv_buf, sizeof(recv_buf), 0);
      		memset(send_buf, 0, sizeof(send_buf));
      
      		sprintf(send_buf, "{\"led\":\"%d\",\"key\":\"%d\",\"tem\":\"%d\",\"hum\":\"%d\"}",\
      
      						led_value, key_value, tem, hum);		
      
      		send(cfd,send_buf, strlen(send_buf),0);
      		dev_dat = cJSON_Parse(recv_buf);
      		led_value = cJSON_GetObjectItem(dev_dat, "led")->valuestring[0] - '0';		
      		printf("led data : %d\r\n", led_value);
      		cJSON_Delete(dev_dat);
      	}
      
      }
      
      static void wifi_connect(char *ssid, char *passwd)
      {
      
      	char *ssid_want_connect = ssid;
      	char *psk = passwd;
      
      	if (WIFI_SUCCESS != EnableWifi()) {
      		printf("Error: EnableWifi fail.\n");
      		return;
      	}
      
      	printf("EnableWifi Success.\n");
      
      	if (WIFI_STA_ACTIVE == IsWifiActive())
      		printf("Wifi is active.\n");
      	OS_Sleep(1);
      
      	if (WIFI_SUCCESS != Scan()) {
      		printf("Error: Scan fail.\n");
      		return;
      	}
      
      	printf("Wifi Scan Success.\n");
      	OS_Sleep(1);
      
      	WifiScanInfo scan_results[30];
      	unsigned int scan_num = 30;
      
      	if (WIFI_SUCCESS != GetScanInfoList(scan_results, &scan_num)) {
      		printf("Error: GetScanInfoList fail.\n");
      		return;
      	}
      
      
      	WifiDeviceConfig config = { 0 };
      	int netId = 0;
      
      	int i;
      	for (i = 0; i < scan_num; i++) {
      		if (0 == strcmp(scan_results[i].ssid, ssid_want_connect)) {
      			memcpy(config.ssid, scan_results[i].ssid,
      			       WIFI_MAX_SSID_LEN);
      			memcpy(config.bssid, scan_results[i].bssid,
      			       WIFI_MAC_LEN);
      			strcpy(config.preSharedKey, psk);
      			config.securityType = scan_results[i].securityType;
      			config.wapiPskType = WIFI_PSK_TYPE_ASCII;
      			config.freq = scan_results[i].frequency;
      			break;
      		}
      	}
      
      	if (i >= scan_num) {
      		printf("Error: No found ssid in scan_results\n");
      		return;
      	}
      	printf("GetScanInfoList Success.\n");
      	if (WIFI_SUCCESS != AddDeviceConfig(&config, &netId)) {
      		printf("Error: AddDeviceConfig Fail\n");
      		return;
      	}
      	printf("AddDeviceConfig Success.\n");
      
      	if (WIFI_SUCCESS != ConnectTo(netId)) {
      		printf("Error: ConnectTo Fail\n");
      		return;
      	}
      
      	printf("ConnectTo Success\n");
      	OS_Sleep(3);
      	WifiLinkedInfo get_linked_res;
      
      	if (WIFI_SUCCESS != GetLinkedInfo(&get_linked_res)) {
      		printf("Error: GetLinkedInfo Fail\n");
      		return;
      	}
      	printf("GetLinkedInfo Success.\n");
      
      	printf("ssid: %s\n", get_linked_res.ssid);
      	printf("bssid: ");
      	for (int j = 0; j < WIFI_MAC_LEN; j++) {
      		printf("%02X", get_linked_res.bssid[j]);
      	}
      
      	printf("\n");
      	printf("rssi: %d\n", get_linked_res.rssi);
      
      	unsigned char get_mac_res[WIFI_MAC_LEN];
      	if (WIFI_SUCCESS != GetDeviceMacAddress(get_mac_res)) {
      		printf("Error: GetDeviceMacAddress Fail\n");
      		return;
      	}
      	printf("GetDeviceMacAddress Success.\n");
      	for (int j = 0; j < WIFI_MAC_LEN - 1; j++) {
      		printf("%02X:", get_mac_res[j]);
      	}
      	printf("%02X\n", get_mac_res[WIFI_MAC_LEN - 1]);
      
      }
      void SmartHome(void)
      {
      	if (OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL,
      			    OS_THREAD_PRIO_APP, 8 * 1024) != OS_OK) {
      		printf("[ERR] Create MainThread Failed\n");
      	}
      }
      SYS_RUN(SmartHome);
      

      APP 采用 APIClode 开发,使用 html js 进行开发

      APICloude Studio 软件下载,以及使用:

      https://docs.apicloud.com/apicloud3/#wifi-preview

      手机安装 Apploader,可以进行调试

      安装Apploader下载 : https://docs.apicloud.com/Download/download

      将 SmartHome 导入 APICloude Studio

      html/main.html 对应登录界面, 如下可修改默认 IP 和端口号

          <div id="bt_log">
              <form name="myForm" action="" onsubmit="return validateForm()" method="post">
                 <div><label>IP地址</label><input type="text" name="ip" value="192.168.8.248"></div>
                  <div><label>端口号</label><input type="text" name="port" value="8080"></div>
                  <div><input type="submit" class="btn" value="登录" onmouseover="this.style.backgroundPosition='left -36px'"
                      onmouseout="this.style.backgroundPosition='left top'"></div>
              </form>
      
           </div>
      

      log.png

      html/user_app.html 对应应用界面,与 xr806 在同一个局域网中,同进行通信,通信使用的为 json 数据。

      app.png

      posted in XR806
      K
      kw___
    • Reply: 基于D1开发板的 微信/支付宝 物联网(MQTT)支付平台

      编译了 freetype 能够显示中文了

      输出目录 /home/eva/Desktop/d1_pay_client/lirary/freetype-tmp
      freetype 目录 /home/eva/Desktop/d1_pay_client/lirary/freetype-2.11.0
      交叉工具链 riscv64-unknown-linux-gnu-gcc

      ./configure --host=riscv64-unknown-linux-gnu  --enable-shared --enable-static --with-zlib=no --with-bzip2=no --with-png=no --with-harfbuzz=no
      
      make
      
      make DESTDIR=/home/eva/Desktop/d1_pay_client/lirary/freetype-tmp install
      

      d1_pay_client-v2.tar
      out.tar

      QQ截图20211119221453.png
      QQ截图20211119221514.png
      QQ截图20211119221532.png

      posted in D1-H/D1s
      K
      kw___
    • 基于D1开发板的 微信/支付宝 物联网(MQTT)支付平台

      准备工作(支付宝沙盒信息获取)

      登录 开发者中心控制台 (alipay.com) 使用支付宝进行登录。

      image-20211116231806340.png

      进入沙箱环境 开放平台-沙箱环境 (alipay.com)

      image-20211116232045464.png

      如果《RSA2密钥(公钥模式) 》的查看是灰色的,点击启用。点击查看可获取应用公钥,应用私钥和支付宝公钥。

      image-20211116232249649.png

      下载并安装沙盒版的支付宝应用。通过提供的账号登录沙盒版支付宝,进行付款。

      image-20211116232448676.png
      image-20211116232613047.png

      (微信个人无法申请 APPID 等信息,且没有提供沙盒平台,所以无法进行测试。提供的 JAR 包里面是有晕哥提供的 APPID 等信息,可以进行测试。提供的 java 源码已经将微信的 APPID 等信息删除)

      服务器端搭建

      linux 平台搭建

      sudo apt install openjdk-8-jdk mosquitto
      

      修改 D1PayServer.jar 压缩包中的 zfbinfo.properties 文件,将 appid,public_key(应用公钥),private_key(应用私钥),alipay_public_key(支付宝公钥)替换成自己支付宝沙盒提供的。

      image-20211117164251960.png

      然后将 D1PayServer.jar 上传至 linux 平台运行。

      java -jar D1PayServer.jar
      

      运行效果:

      image-20211117164122389.png

      客户端运行

      烧写 tina_d1-nezha_uart0.img 镜像,内核已经修改为默认 HDMI 输出,分辨率为 480P(720x480)。

      连接 wifi

      wifi_connect_ap_test GL-MT300N-V2-0be goodlife
      

      修改应用配置文件:

      vim /bin/D1Pay/D1PayClientConfig.json
      
      {
          "device_id":"kw",
          "mqtt_server_ip":"192.168.8.108", 
          "mqtt_sub_top":"d1_pay_client",
          "mqtt_pub_top":"d1_pay_server",
          "fb":"/dev/fb0",
          "input":"/dev/input/event2"
      }
      
      

      修改 mqtt_server_ip 为自己的 mqtt 服务器的地址,input 修改为自己的触摸设配。

      运行应用程序

      root@TinaLinux:/# d1_pay_launche
      

      image-20211117170015046.png

      运行效果(使用的HDMI屏幕,拥有触摸,分辨率 800x480),完成支付后将会播报语音以及控制一个 GPIO 输出 5 秒的高电平。

      image-20211117211305734.png

      image-20211117211337299.png

      image-20211117211354427.png

      客户端添加一个商品信息

      商品信息保存在 /bin/D1Pay/ProductList/ 目录下,每一件商品对应一个文件夹。每一个文件夹都有 Image.png ProductDescribe.txt文件,Image.png为 350x350 像素的商品图片,ProductDescribe.txt为描述文件,包含商品名,价格,付款成功后控制的 GPIO,以及商品详细介绍。

      .
      ├── D1 Board
      │   ├── Image.png
      │   └── ProductDescribe.txt
      ├── D1 IC
      │   ├── Image.png
      │   └── ProductDescribe.txt
      └── XR806 Board
          ├── Image.png
          └── ProductDescribe.txt
      

      ProductDescribe.txt 文件第一行为商品名字,第二行为价格(价格必须保留小数两位),第三(商品id)行为付款成功后控制的 GPIO(1-GPIOD11, 2-GPIO12, 3-GPIO13)。余下信息均为商品描述信息。

      cat D1 Board/ProductDescribe.txt
      D1 Board
      599.99
      1
      CPU : C906 64bit RISC-V 32 KB I-cache + 32 KB D-cache
      DSP :
      HiFi4 DSP  600MHz
      32 KB I-cache + 32 KB D-cache
      64 KB I-ram + 64 KB D-ram
      Memory :
      DDR2/DDR3, up to 2 GB
      SD3.0/eMMC 5.0, SPI Nor/Nand Flash
      

      客户端与服务端数据交互格式

      通信数据采用 json 数据,定义的数据存在多余的,部分并没有使用到

      客户端发送订单信息至服务器

      {
      	"device_id":"kw",           设备id
      	"msg_type":"0",             0客户端发送订单 1服务器返回收款信息至客户端 2支付成功服务器返回至客户端
      	"product_id":"1",           商品id 用于控制 GPIO
      	"product_name":"D1 IC",     商品名称
      	"pay_way":"0",              0支付宝 1微信
      	"price":"34.97"             价格
      }
      

      服务器返回生成的支付二维码信息至客户端

      {
      	"device_id":"kw",                设备id
      	"msg_type":"1",                  0客户端发送订单 1服务器返回收款信息至客户端 2支付成功服务器返回至客户端	
      	"product_id":"1",                商品id 用于控制 GPIO
      	"pay_way":"0",                   0支付宝 1微信
      	"return":"ok", 					 ok err
      	"price":"34.97",                 价格
      	"out_trade_no":"63827381363",    订单号
      	"pay_qrcode":"xxxweduwqcfgy3t72" 用于生成二维码
      }
      

      支付成功服务器返回至客户端,支付失败则不返回

      {
      	"device_id":"kw",              设备id
      	"msg_type":"2",                0客户端发送订单 1服务器返回收款信息至客户端 2支付成功服务器返回至客户端	
      	"product_id":"1",              商品id 用于控制 GPIO
      	"pay_way":"0",                 0支付宝 1微信
      	"return":"ok",                 ok err
      	"price":"34.97",               价格
      	"out_trade_no":"63827381363"   订单号 
      }
      

      服务器端工程结构

      eva@ubuntu:~/Desktop/d1_pay_server_master$ tree
      .
      ├── D1PayServer
      │   ├── pom.xml
      │   ├── resource
      │   │   └── zfbinfo.properties
      │   ├── src
      │   │   ├── main
      │   │   │   └── java
      │   │   │       └── com
      │   │   │           └── nuist
      │   │   │               └── kw
      │   │   │                   └── D1PayServer
      │   │   │                       ├── AliPayThread.java
      │   │   │                       ├── App.java
      │   │   │                       ├── CommonUtils.java
      │   │   │                       ├── MyConfig.java
      │   │   │                       ├── OrderInformation.java
      │   │   │                       ├── PaymentInformation.java
      │   │   │                       ├── PayThread.java
      │   │   │                       ├── ResultInformation.java
      │   │   │                       └── WxPayThread.java
      
      

      zfbinfo.properties 保存支付宝 APPID 等信息

      App.java 初始化一个 mqtt 服务器,main 入口

      MyConfig.java 微信 APPID 等信息

      PayThread.java 当 mqtt 服务器收到一个订单消息,进行判断是支付宝支付,还是微信支付,然后开启相应的支付处理线程

      AliPayThread.java 支付宝支付线程,负责请求支付二维码,循环判断订单支付结果,3 分钟未支付,则不再处理。

      WxPayThread.java 微信支付线程,负责请求支付二维码,循环判断订单支付结果,3 分钟未支付,则不再处理。

      OrderInformation.java PaymentInformation.java ResultInformation.java 负责构造通信数据字符串。

      Maven 项目依赖

      <!-- 微信sdk -->
      <dependency>    
      <groupId>com.github.wxpay</groupId>    
      <artifactId>wxpay-sdk</artifactId>    
      <version>0.0.3</version>
      </dependency>
      <!-- 支付宝sdk -->
      <dependency>
      <groupId>com.alipay.sdk</groupId>
      <artifactId>alipay-sdk-java</artifactId>
      <version>4.10.209.ALL</version>
      </dependency>
      <!-- mqtt sdk -->
      <dependency>
      <groupId>org.eclipse.paho</groupId>
      <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
      <version>1.2.5</version>
      </dependency>
      <!-- json -->
      <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.47</version>
      </dependency>
      

      客户端工程结构

      客户端代码结构如下,app 存放的是应用代码,build 存放的是编译生成的 .o 文件以及顶层 Makefile(使用的百问网的 lvgl 移植的 Makefile),build.sh 编译脚本,lirary 存放的是库源码,Makefile 硬链接指向 build/Makefile,out 为输出的应用程序目录。

      eva@ubuntu:~/Desktop/d1_pay_client$
      .
      ├── app
      │   ├── app.mk
      │   ├── include
      │   ├── launcher_ui.c   # UI 界面
      │   ├── launcher_ui.h   
      │   ├── lv_drv_init.c   # 驱动初始化
      │   ├── lv_drv_init.h
      │   ├── main.c          # 程序入口
      │   ├── mqtt_client.c   # mqtt 客户端初始化 数据处理
      │   ├── mqtt_client.h
      │   ├── pin_control.c   # 引脚控制,增加引脚修改该文件
      │   ├── pin_control.h
      │   ├── play_pay_result.c # 语音播报
      │   ├── play_pay_result.h
      │   ├── untilities.c     # 提供一些函数
      │   └── untilities.h
      ├── build
      │   └── Makefile
      ├── build.sh
      ├── lirary
      ├── Makefile
      └── out
          ├── bin
          ├── etc
          └── lib
      
      

      build.sh 中指定编译工具链,通过 ./build.sh 进行编译,./build.sh clean 进行清除编译中间文件。

      修改引脚修改 pin_control.c 如下部分(计算公式 32*n+i)

      image-20211117231147776.png

      mosquitto编译

      应用程序使用了 mosquitto 库,build.sh并不会去编译它,所以这个需要单独编译,编译完成后,将库拷贝到 out/lib 目录下。mosquitto 在 lirary 目录下,在 lirary 目录下新建一个 mosquitto-risc 目录,用于保存编译输出文件。

      设置交叉编译工具链

      vim ~/.bashrc
      export PATH=$PATH:/home/eva/d1/D1/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/bin/
      source ~/.bashrc
      

      交叉编译 uuid

      tar -vxf libuuid-1.0.3.tar.gz
      ./configure --prefix=/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc CC=riscv64-unknown-linux-gnu-gcc --host=riscv64-unknown-linux-gnu
      
      make && make install
      

      交叉编译 openssl 库

      tar -vxf openssl-1.0.2g.tar.gz
      ./config no-asm shared --prefix=/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc
      #删除Makefile中的-m64(一共有两个),修改Makefile中的
      CC= riscv64-unknown-linux-gnu-gcc
      AR= riscv64-unknown-linux-gnu-ar $(ARFLAGS) r
      RANLIB= riscv64-unknown-linux-gnu-ranlib
      NM= riscv64-unknown-linux-gnu-nm
      
      make && make install
      

      交叉编译 mosquitto

      tar -vxf mosquitto-1.5.tar.gz
      
      make WITH_SRV=no CC=riscv64-unknown-linux-gnu-gcc CXX=riscv64-unknown-linux-gnu-g++ CFLAGS="-I /home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc/include -I /home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc/include" LDFLAGS="-L/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc/lib -L/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc/lib -lssl -lcrypto -luuid"
      
      make DESTDIR=/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc install
      

      D1 内核配置

      配置编译环境

      source build/envsetup.sh
      lunch d1_nezha-tina
      

      开启 nfs

      make kernel_menuconfig
      
      File systems  --->
      	[*] Network File Systems  --->     
        │ │    <*>   NFS client support                                         │ │  
        │ │    <*>     NFS client support for NFS version 2                     │ │  
        │ │    [*]     NFS client support for NFS version 3                     │ │  
        │ │    [*]       NFS client support for the NFSv3 ACL protocol extension│ │  
        │ │    [*]     NFS client support for NFS version 4                     │ │  
        │ │    [*]   NFS client support for NFSv4.1                             │ │  
        │ │    [*]     NFS client support for NFSv4.2                           │ │  
        │ │    (kernel.org) NFSv4.1 Implementation ID Domain                    │ │  
        │ │    [*]     NFSv4.1 client support for migration                     │ │  
        │ │    [*]   Use the legacy NFS DNS resolver
      

      修改开机默认 HDMI 输出(如果开机不是默认 HDMI 输出,开机后再启动 HDMI 输出,会输出有问题)

      修改 uboot 设备树文件

      ./D1/device/config/chips/d1/configs/nezha/uboot-board.dts
      
      214 行
              disp_init_enable         = <1>;
              disp_mode                = <0>;
      
      -       screen0_output_type      = <1>;
      -       screen0_output_mode      = <4>;
      -
      -       screen1_output_type      = <3>;
      -       screen1_output_mode      = <10>;
      -
      -       screen1_output_format    = <0>;
      -       screen1_output_bits      = <0>;
      -       screen1_output_eotf      = <4>;
      -       screen1_output_cs        = <257>;
      -       screen1_output_dvi_hdmi  = <2>;
      -       screen1_output_range     = <2>;
      -       screen1_output_scan      = <0>;
      -       screen1_output_aspect_ratio = <8>;
      -
      -       dev0_output_type         = <1>;
      -       dev0_output_mode         = <4>;
      +    screen0_output_type      = <3>;
      +    screen0_output_mode      = <10>;
      +
      +    screen0_output_format    = <0>;
      +    screen0_output_bits      = <0>;
      +    screen0_output_eotf      = <4>;
      +    screen0_output_cs        = <257>;
      +    screen0_output_dvi_hdmi  = <2>;
      +    screen0_output_range     = <2>;
      +    screen0_output_scan      = <0>;
      +    screen0_output_aspect_ratio = <8>;
      +
      +    screen1_output_type      = <1>;
      +    screen1_output_mode      = <4>;
      +
      +    dev0_output_type         = <4>;
      +    dev0_output_mode         = <2>;
              dev0_screen_id           = <0>;
      -       dev0_do_hpd              = <0>;
      -
      -       dev1_output_type         = <4>;
      -       dev1_output_mode         = <10>;
      -       dev1_screen_id           = <1>;
      -       dev1_do_hpd              = <1>;
      +       dev0_do_hpd              = <1>;
      
              def_output_dev           = <0>;
              hdmi_mode_check          = <1>;
      

      修改 linux 设备树文件

      ./D1/device/config/chips/d1/configs/nezha/linux-5.4/board.dts
      
      1128 行
              disp_init_enable         = <1>;
              disp_mode                = <0>;
      
      -       screen0_output_type      = <1>;
      -       screen0_output_mode      = <4>;
      -
      -       screen1_output_type      = <3>;
      -       screen1_output_mode      = <10>;
      -
      -       screen1_output_format    = <0>;
      -       screen1_output_bits      = <0>;
      -       screen1_output_eotf      = <4>;
      -       screen1_output_cs        = <257>;
      -       screen1_output_dvi_hdmi  = <2>;
      -       screen1_output_range     = <2>;
      -       screen1_output_scan      = <0>;
      -       screen1_output_aspect_ratio = <8>;
      -
      -       dev0_output_type         = <1>;
      -       dev0_output_mode         = <4>;
      +    screen0_output_type      = <3>;
      +    screen0_output_mode      = <10>;
      +
      +    screen0_output_format    = <0>;
      +    screen0_output_bits      = <0>;
      +    screen0_output_eotf      = <4>;
      +    screen0_output_cs        = <257>;
      +    screen0_output_dvi_hdmi  = <2>;
      +    screen0_output_range     = <2>;
      +    screen0_output_scan      = <0>;
      +    screen0_output_aspect_ratio = <8>;
      +
      +    screen1_output_type      = <1>;
      +    screen1_output_mode      = <4>;
      +
      +    dev0_output_type         = <4>;
      +    dev0_output_mode         = <2>;
              dev0_screen_id           = <0>;
      -       dev0_do_hpd              = <0>;
      -
      -       dev1_output_type         = <4>;
      -       dev1_output_mode         = <10>;
      -       dev1_screen_id           = <1>;
      -       dev1_do_hpd              = <1>;
      +       dev0_do_hpd              = <1>;
      
              def_output_dev           = <0>;
              hdmi_mode_check          = <1>;
      

      dev0_output_mode 为分辨率,这里设置为 480P

      enum disp_tv_mode {
          DISP_TV_MOD_480I = 0,
          DISP_TV_MOD_576I = 1,
          DISP_TV_MOD_480P = 2,
          DISP_TV_MOD_576P = 3,
          DISP_TV_MOD_720P_50HZ = 4,
          DISP_TV_MOD_720P_60HZ = 5,
          DISP_TV_MOD_1080I_50HZ = 6,
          DISP_TV_MOD_1080I_60HZ = 7,
          DISP_TV_MOD_1080P_24HZ = 8,
          DISP_TV_MOD_1080P_50HZ = 9,
          DISP_TV_MOD_1080P_60HZ = 0xa,
          /***/
      

      编译 uboot

      cboot
      muboot
      

      进入顶层目录,编译其它部分

      make -j8
      pack
      

      代码,固件下载
      D1PayPack.zip

      演示视频

      posted in D1-H/D1s
      K
      kw___
    • Reply: 【走过路过的朋友不要错过】全志在线(bbs.aw-ol.com)做项目赠送哪吒开发板活动

      @whycan 在 【走过路过的朋友不要错过】全志在线(bbs.aw-ol.com)做项目赠送哪吒开发板活动 中说:

      退款

      可以的

      posted in D1-H/D1s
      K
      kw___
    • Reply: 【走过路过的朋友不要错过】全志在线(bbs.aw-ol.com)做项目赠送哪吒开发板活动

      @whycan 在 【走过路过的朋友不要错过】全志在线(bbs.aw-ol.com)做项目赠送哪吒开发板活动 中说:

      项目 (二): 基于MQTT的微信或支付宝收款平台

      **目标:**基于D1哪吒开发板/联网/HDMI显示收款二维码/扫码付款成功后声光提醒用户并触发IO动作(模拟开锁等)

      要求:
      ① 开源并在本站发帖详细记录过程,其他网友可以仿制实现

      ② 搭建MQTT服务器,搭建微信支付/支付宝支付服务器端。

      ③ 哪吒D1开发板HDMI显示从服务器推送的付款二维码,扫码付款成功,服务器推送信息给哪吒D1,哪吒通过喇叭播放支付宝/微信到账xxx元,并触发IO动作。

      ④ 需要微信支付appid等信息可以联系我,需要linux服务器也可以联系我。

      ⑤⑥⑦⑧⑨ 要求与一楼相同

      你好,这个项目还能接收吗,我要报名

      posted in D1-H/D1s
      K
      kw___