5.22 综合案例2.0-4G远程遥控车DEMO(2.2版本接口有更新)

最新案例教程点击下方链接跳转,CSDN已停止更新

点击跳转HaaS506官方最新案例







简介

  常见的无线遥控小车和飞机操作范围都是在几十米, 远的几百米, 再远的几公里, 传输距离大受限制。如果能够利用4g/5g信号连上互联网来接收指令, 这样只要有信号的地方, 就可以不限距离的操作。在未来也是一个颇有发展空间的领域。
  本案例只是简单对小车进行遥控,没有安装摄像头(暂不支持摄像头)。

准备

本案例需要的硬件

器材数量
HaaS506开发板1
L298N电机驱动板模块2
电动智能小车底座1套
5V移动电源1
SIM卡1
杜邦线若干

硬件连接图

在这里插入图片描述

代码流程

1、连接阿里云平台。
2、设置小车状态位,根据状态位改变小车的运动模式。
3、IoT Studio 移动应用下发状态,改变小车运动状态。

1、物联网平台开发

第一次使用物联网平台的读者,需要开通实例后使用物联网平台功能。也可以使用免费的公共实例进行开发,在阿里云物联网平台中,左上角选择‘华东2-上海’,点击‘公共实例’,即可开通。

1、平台产品创建可参考haas506 2.0开发教程-aliyunIoT
2、创建产品属性(添加物模型)

  • 选择产品功能定义编辑草稿
    在这里插入图片描述

  • 添加自定义功能

  • 添加标识符数据类型(标识符要与代码一致)

  • 点击发布上线
    在这里插入图片描述
    在这里插入图片描述

  • 点击确定
    在这里插入图片描述

2、设备端开发

  • 第一次使用开发板的读者可以按照haas5062.0开发教程-导学篇搭建开发环境。
  • 搭建完后复制以下代码到Visual Studio Code,复制产品证书到代码相应位置。
    在这里插入图片描述
  • 2.2版本获取IMEI号接口有更新,需要更改以下内容(Ctrl+F 查找modem)
# 获取设备的IMEI 作为deviceName 进行动态注册
deviceName = modem.info.getDevImei()
...

  • main.py
# coding=utf-8
import network
import ujson
import utime as time
import modem
from  aliyunIoT import Device
import kv
from driver import GPIO

#当iot设备连接到物联网平台的时候触发'connect' 事件
def on_connect(data):
    global module_name,default_ver,productKey,deviceName,deviceSecret,on_trigger,on_download,on_verify,on_upgrade
    print('***** connect lp succeed****')
    data_handle = {}
    data_handle['device_handle'] = device.getDeviceHandle()


#当连接断开时,触发'disconnect'事件
def on_disconnect():
    print('linkkit is disconnected')


#当iot云端下发属性设置时,触发'props'事件
def on_props(request):
    global state
    params=request['params']
    state_data=eval(params)
    if 'state' in state_data :
        state = state_data['state']


#当iot云端调用设备service时,触发'service'事件
def on_service(id,request):
    print('clound req id  is {} , req is {}'.format(id,request))
#当设备跟iot平台通信过程中遇到错误时,触发'error'事件
def on_error(err):
    print('err msg is {} '.format(err))

#网络连接的回调函数
def on_4g_cb(args):
     global g_connect_status
     pdp = args[0]
     netwk_sta = args[1]
     if netwk_sta == 1:
         g_connect_status = True
     else:
         g_connect_status = False

#网络连接
def connect_network():
     global net,on_4g_cb,g_connect_status
     #NetWorkClient该类是一个单例类,实现网络管理相关的功能,包括初始化,联网,状态信息等.
     net = network.NetWorkClient()
     g_register_network = False
     if net._stagecode is not None and net._stagecode == 3 and net._subcode == 1:
         g_register_network = True
     else:
         g_register_network = False
     if g_register_network:
    #注册网络连接的回调函数on(self,id,func);  1代表连接,func 回调函数  ;return 0 成功
         net.on(1,on_4g_cb)    
         net.connect(None)
     else:
         print('网络注册失败')
     while True:
         if g_connect_status:
             print('网络连接成功')
             break
         time.sleep_ms(20)

#动态注册回调函数
def on_dynreg_cb(data):
     global deviceSecret,device_dyn_resigter_succed
     deviceSecret = data
     device_dyn_resigter_succed = True


 # 连接物联网平台
def dyn_register_device(productKey,productSecret,deviceName):
    global on_dynreg_cb,device,deviceSecret,device_dyn_resigter_succed
    key = '_amp_customer_devicesecret'
    deviceSecretdict = kv.get(key)
    print("deviceSecretdict:",deviceSecretdict)
    if isinstance(deviceSecretdict,str):    
        deviceSecret = deviceSecretdict 

    if deviceSecretdict is None or deviceSecret is None:
        key_info = {
            'productKey': productKey  ,
            'productSecret': productSecret ,
            'deviceName': deviceName
            }
        # 动态注册一个设备,获取设备的deviceSecret
        #下面的if防止多次注册,当前若是注册过一次了,重启设备再次注册就会卡住,
        if not device_dyn_resigter_succed:
            device.register(key_info,on_dynreg_cb)   

state_data = {}
def upload_state():
    global state_data,state
    state_data["state"]= state
    state_data_str=ujson.dumps(state_data)
    data={
        'params':state_data_str
        }      
    device.postProps(data)

def left_n(n):
    if n == 0:
        left_neg0.write(0)
        left_neg1.write(0)
    if n == 1:
        left_neg0.write(1)
        left_neg1.write(0)
    if n == -1:
        left_neg0.write(0)
        left_neg1.write(1)

def right_n(n):
    if n == 0:
        right_neg0.write(0)
        right_neg1.write(0)
    if n == 1:
        right_neg0.write(1)
        right_neg1.write(0)
    if n == -1:
        right_neg0.write(0)
        right_neg1.write(1)

def left_p(p):
    if p == 0:
        left_pos0.write(0)
        left_pos1.write(0)
    if p == 1:
        left_pos0.write(1)
        left_pos1.write(0)
    if p == -1:
        left_pos0.write(0)
        left_pos1.write(1)

def right_p(p):
    if p == 0:
        right_pos0.write(0)
        right_pos1.write(0)
    if p == 1:
        right_pos0.write(1)
        right_pos1.write(0)
    if p == -1:
        right_pos0.write(0)
        right_pos1.write(1)




if __name__ == '__main__':
    ret = modem.sim.getStatus()
    print('ret:',ret)
    ICCID=None
    g_connect_status = False
    net = None
    device = None
    deviceSecret = None
    deviceName = None
    productKey = "your  productKey "
    productSecret = "your  productSecret "
    device_dyn_resigter_succed = False

    # 连接网络
    connect_network()
     # 获取设备的IMEI 作为deviceName 进行动态注册
    deviceName = modem.getDevImei()
    #获取设备的ICCID
    ICCID=modem.sim.getIccid()
    #初始化物联网平台Device类,获取device实例
    device = Device()
    if deviceName is not None and len(deviceName) > 0 :
     #动态注册一个设备
        dyn_register_device(productKey,productSecret,deviceName)
    else:
        print("获取设备IMEI失败,无法进行动态注册")
    while deviceSecret is None:
        time.sleep(0.2)
    print('动态注册成功:' + deviceSecret)

    key_info = {
        'region' : 'cn-shanghai' ,
        'productKey': productKey ,
        'deviceName': deviceName ,
        'deviceSecret': deviceSecret ,
        'keepaliveSec': 60,
        }
    #打印设备信息
    print(key_info)

    #device.ON_CONNECT 是事件,on_connect是事件处理函数/回调函数
    device.on(device.ON_CONNECT,on_connect)
    device.on(device.ON_DISCONNECT,on_disconnect)
    device.on(device.ON_PROPS,on_props)
    device.on(device.ON_SERVICE,on_service)
    device.on(device.ON_ERROR,on_error)
    device.connect(key_info)
    time.sleep(2)
    state = 0
    upload_state()


    #主程序
    #实例化电机引脚
    left_neg0=GPIO()
    left_neg0.open('left_n0')
    left_neg1=GPIO()
    left_neg1.open('left_n1')
    right_neg0=GPIO()
    right_neg0.open('right_n0')
    right_neg1=GPIO()
    right_neg1.open('right_n1')
    left_pos0 = GPIO()
    left_pos0.open('left_p0')
    left_pos1 = GPIO()
    left_pos1.open('left_p1')
    right_pos0 = GPIO()
    right_pos0.open('right_p0')
    right_pos1 = GPIO()
    right_pos1.open('right_p1')
    left_n(0)
    right_n(0)
    left_p(0)
    right_p(0)

    while True:
        if state == 1:  #前
            left_n(1)
            right_n(1)
            left_p(1)
            right_p(1)
        elif state == 2:  #后
            left_n(-1)
            right_n(-1)
            left_p(-1)
            right_p(-1)
        elif state == 3:   #右移
            left_n(-1)
            right_n(1)
            left_p(1)
            right_p(-1)
        elif state == 4:  #左移
            left_n(1)
            right_n(-1)
            left_p(-1)
            right_p(1)
        elif state == 5:   #右转
            left_n(1)
            right_n(-1)
            left_p(1)
            right_p(-1)
        elif state == 6:  #左转
            left_n(-1)
            right_n(1)
            left_p(-1)
            right_p(1)
        else :             #停止
            left_n(0)
            right_n(0)
            left_p(0)
            right_p(0)
        time.sleep_ms(50)

  • board.json
{
  "version": "2.0.0",
  "io": {
    "left_n0": {
          "type": "GPIO",
          "port": 15,
          "dir": "output",
          "pull": "pullup"
          },
    "left_n1": {
          "type": "GPIO",
          "port": 16,
          "dir": "output",
          "pull": "pullup"
          },
    "right_n0": {
          "type": "GPIO",
          "port": 18,
          "dir": "output",
          "pull": "pullup"
          },
    "right_n1": {
          "type": "GPIO",
          "port": 17,
          "dir": "output",
          "pull": "pullup"
          },
    "left_p0": {
            "type": "GPIO",
            "port": 32,
            "dir": "output",
            "pull": "pullup"
            },
    "left_p1": {
            "type": "GPIO",
            "port": 24,
            "dir": "output",
            "pull": "pullup"
            },
    "right_p0": {
            "type": "GPIO",
            "port": 19,
            "dir": "output",
            "pull": "pullup"
            },
    "right_p1": {
            "type": "GPIO",
            "port": 20,
            "dir": "output",
            "pull": "pullup"
            }
      },
      "debugLevel": "ERROR",
      "repl": "enable",
      "replPort": 0
  }
  

调试

1、设备上线时,上传小车停止状态。
在这里插入图片描述

3、物联网应用开发

以下是物联网应用开发流程,接下来按以下流程介绍移动端应用的开发。

3.1新建‘普通项目’

  • 使用阿里云IoTStudio创建项目。
  • 在项目管理新建空白项目
    在这里插入图片描述
    在这里插入图片描述

3.2关联产品和设备

在这里插入图片描述
在这里插入图片描述

3.3新建‘移动应用’

在这里插入图片描述
在这里插入图片描述
改页面名称
在这里插入图片描述
在这里插入图片描述
点击上图红框中的‘组件’,就可以看到可用的组件列表。各组件的使用说明请参考组件说明

3.4页面设计

将横向分栏 按钮组件从上到下拖到中间画布区在这里插入图片描述

根据自己喜好排布按钮位置,调整上边距,按钮内容、字号等属性。
在这里插入图片描述

  • 配置交互
    在这里插入图片描述
    前进按钮配置设备,点击保存
    在这里插入图片描述
    其他按钮用一样的方式配置
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

其他略

3.5预览和发布上线

在页面‘’保存‘’并点击‘预览’进行预览。
在这里插入图片描述
手机扫描二维码,可以用手机遥控小车。
在这里插入图片描述

  • 4
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值