5.11 综合案例2.0-WS2812个性氛围灯带(2.2版本接口有更新)

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

点击跳转HaaS506官方最新案例







简介

LED灯带广泛应用于家具、汽车、广告、照明、轮船、酒吧等行业。跳动的彩色灯光也变成了城市夜晚的靓丽风景。
本案例通过手机控制RGB灯光模式,点击相应的按钮就可以改变LED灯光模式。

准备

本案例需要的硬件

器材数量
HaaS506开发板1
WS2812灯带(30灯)1
SIM卡1
杜邦线若干

硬件连接图

连接时注意灯带信号方向,本案例使用SPI控制LED灯带。
在这里插入图片描述

代码流程

1、连接阿里云平台。
2、编写灯带8种状态,默认为关闭状态
3、配置iot云端下发属性,当云端模式改变时,发送到设备端,改变灯光状态。

功能实现

1、物联网平台开发

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

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

  • 选择产品功能定义编辑草稿
    在这里插入图片描述
  • 添加自定义功能
  • 添加标识符数据类型(标识符要与代码一致)
  • 点击发布上线
    在这里插入图片描述
  • 点击确定
    在这里插入图片描述

2、设备端开发

  • 第一次使用开发板的读者可以按照haas5062.0开发教程-导学篇搭建开发环境。

  • 搭建完后复制以下代码到Visual Studio Code,复制产品证书到代码相应位置。
    在这里插入图片描述

  • 2.2版本获取IMEI号接口有更新,需要更改了以下内容(Ctrl+F 查找modem)

# 获取设备的IMEI 作为deviceName 进行动态注册
deviceName = modem.getDevImei()
...

改为

# 获取设备的IMEI 作为deviceName 进行动态注册
deviceName = modem.info.getDevImei()
...

  • main.py
# coding=utf-8
from driver import GPIO
from ws2812 import WS2812
from driver import SPI
import network
import ujson
import utime as time
import modem
from  aliyunIoT import Device
import kv
from driver import TIMER
import _thread
from driver import WDT

import math
 
#当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 mode,breathing_light
    params=request['params']
    params=eval(params)
    if "mode" in params:
        mode=params["mode"]
    if 'breath' in params:
        breathing_light = params["breath"]
        

#当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)   
    

mode_data = {}
def upload_mode():
    global mode_data,mode,breathing_light
    print(mode,'------------------------------')
    mode_data["mode"]= mode
    mode_data["breath"]= breathing_light

    mode_data_str=ujson.dumps(mode_data)
    data={
        'params':mode_data_str
        }      
    ret = device.postProps(data)

turn = 0
def bre_light(operation):
    global breathing_light,light,turn
    if breathing_light:
        if turn:
            operation = operation*(-1)
        else:
            operation = operation*1
        light = light + operation
        if light < 10:
            turn = 1
        if light > 245:
            turn = 0

    else:
        light = 255





if __name__ == '__main__':
    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.info.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)
    #以上是阿里云联网动态注册部分


    spi=SPI()
    spi.open("led_strip")
    strip = WS2812(spi,led_count=30,intensity=1)

    #实例化一个看门狗
    wdt = WDT()
    #开启看门狗
    wdt.open('wdt0')

    print("LED reading-------- ")
    time.sleep(2)
    breathing_light = 1     #呼吸灯开关
    mode = 0
    num = 1     #循环次数
    num_4 = 0
    turn_off = True    #关闭所有灯光
    light = 255       #灯带亮度
    upload_mode()

    while True:

        '''
        write_in_data(red,green,blue,order,on_off)
            red,green,blue  表示对应3原色
            order  第几个灯,灯的位置
            on_off  0把数据保存在data,1把data的信息显示在灯带上
        '''
        #反向彩色跑马灯
        if mode == 1:   
            turn_off = True  
            if num%3 ==1:       #选择data的RGB数值
                red,green,blue = 255,0,0
            if num%3 ==2:
                red,green,blue = 0,255,0       
            if num%3 ==0:
                red,green,blue = 0,0,255

            num2 = 31-(num%31)      #序号反向
            strip.write_in_data(red,green,blue,num2,1)       #写入并显示彩灯颜色
            wdt.feed()
            time.sleep_ms(150)

        #蓝色跑马灯
        elif mode == 2:  
            turn_off = True     
            red,green,blue = 0,0,255
            strip.write_in_data(red,green,blue,num,1)       #写入并显示彩灯颜色
            wdt.feed()
            time.sleep_ms(150)

        #彩色跑马灯  
        elif mode == 3:      
            turn_off = False  
            if num%3 ==1:       #选择data的RGB数值
                red,green,blue = light,0,0
            if num%3 ==2:
                red,green,blue = 0,light,0       
            if num%3 ==0:
                red,green,blue = 0,0,light

            strip.write_in_data(red,green,blue,num,1)       #写入并显示彩灯颜色
            wdt.feed()
            time.sleep_ms(150)
         
        #霓虹灯
        elif mode == 4:   
            turn_off = False 
            for i in range(31):
                if num_4%3 ==1:       #选择data的RGB数值
                    red,green,blue = light,0,0
                if num_4%3 ==2:
                    red,green,blue = 0,light,0       
                if num_4%3 ==0:
                    red,green,blue = 0,0,light 
                strip.write_in_data(red,green,blue,num_4,0)       #写入data 不显示彩灯颜色
                time.sleep_us(900)
                num_4+=1
            time.sleep_ms(150)
            strip.send_data()       #显示data灯光数据
            wdt.feed()
            if num_4%30>2:
                num_4 = 0

        #蓝色呼吸灯
        elif mode == 5:     
            turn_off = False  
            red,green,blue = 0,0,light
            strip.write_in_data(red,green,blue,num,0)       #写入data 不显示彩灯颜色
            if num%30 == 0:
                strip.write_in_data(red,green,blue,num,1)       #写入并显示彩灯颜色
                bre_light(-2)
                wdt.feed()
                # print('------------mode 5---------------')
            time.sleep_us(400)

        #彩色呼吸灯
        elif mode == 6:
            turn_off = False 
            bre_light(-5)
            num_6 = 1
            for i in range(31):
                if num_6%3 ==1:       #选择data的RGB数值
                    red,green,blue = light,0,0
                if num_6%3 ==2:
                    red,green,blue = 0,light,0       
                if num_6%3 ==0:
                    red,green,blue = 0,0,light 
                strip.write_in_data(red,green,blue,num_6,0)       #写入data 不显示彩灯颜色
                time.sleep_us(900)
                num_6+=1
            strip.send_data()       #显示data灯光数据
            wdt.feed()

        #流水灯
        elif mode ==7:
            turn_off = False  
            red,green,blue = 0,light,0
            bre_light(-3)
            strip.write_in_data(red,green,blue,num,1)       #写入并显示彩灯颜色
            wdt.feed()
            time.sleep_ms(10)

        #限制模式,打印没有该模式
        elif mode > 7:     
            print(" haven't this mode")

        #模式0 ,关闭所有灯光
        else:
            strip.turn_off()
            wdt.feed()
            time.sleep(1)


        num+=1
        if turn_off :
            strip.turn_off()        #灭灯
  • ws2812.py
import utime as time

class WS2812:
    """
    Driver for WS2812 RGB LEDs. May be used for controlling single LED or chain
    of LEDs.
    Example of use:
        chain = WS2812(spi_bus=1, led_count=4)
        data = [
            (255, 0, 0),    # red
            (0, 255, 0),    # green
            (0, 0, 255),    # blue
            (85, 85, 85),   # white
        ]
        chain.show(data)
    Version: 1.0
    """

    def __init__(self, spiObj, led_count=1, intensity=1):
        """
        Params:
        * spiObj
        * led_count: count of LEDs
        * intensity:light intensity (float up to 1)
        """
        self.led_count = led_count
        self.intensity = intensity
        self.buf_bytes = (0x88, 0x8e, 0xe8, 0xee)
        self.datas = []

        # prepare SPI data buffer (4 bytes for each color)
        self.buf_length = self.led_count * 3 * 4
        self.buf = bytearray(self.buf_length)
        # SPI init
        self.spiObj=spiObj
        # turn LEDs off
        # self.show([])


    def send_buf(self,data):
        """
        Send buffer over SPI.
        """
        self.spiObj.write(data)
    
  
    def update_buf(self, data, start=0):
        """
        Fill a part of the buffer with RGB data.
        Order of colors in buffer is changed from RGB to GRB because WS2812 LED
        has GRB order of colors. Each color is represented by 4 bytes in buffer
        (1 byte for each 2 bits).
        Returns the index of the first unfilled LED
        Note: If you find this function ugly, it's because speed optimisations
        beated purity of code.
        """
        mask = 0x03
        index = start * 12
        for red, green, blue in data: 
            red = int(red * self.intensity)
            green = int(green * self.intensity)
            blue = int(blue * self.intensity)

            self.buf[index] = self.buf_bytes[green >> 6 & mask]
            self.buf[index+1] = self.buf_bytes[green >> 4 & mask]
            self.buf[index+2] = self.buf_bytes[green >> 2 & mask]
            self.buf[index+3] = self.buf_bytes[green & mask]

            self.buf[index+4] = self.buf_bytes[red >> 6 & mask]
            self.buf[index+5] = self.buf_bytes[red >> 4 & mask]
            self.buf[index+6] = self.buf_bytes[red >> 2 & mask]
            self.buf[index+7] = self.buf_bytes[red & mask]

            self.buf[index+8] = self.buf_bytes[blue >> 6 & mask]
            self.buf[index+9] = self.buf_bytes[blue >> 4 & mask]
            self.buf[index+10] = self.buf_bytes[blue >> 2 & mask]
            self.buf[index+11] = self.buf_bytes[blue & mask]

            index += 12

        return index // 12

    def fill_buf(self, data):
        """
        Fill buffer with RGB data.
        All LEDs after the data are turned off.
        """
        end = self.update_buf(data)
        # # turn off the rest of the LEDs
        off = self.buf_bytes[0]
        for index in range(end * 12, self.buf_length):
            self.buf[index] = off
            index += 1

    # 关闭所有led灯
    def turn_off(self):
        self.fill_buf([])
        self.datas = []
        data=self.buf[:]
        # print(data)
        self.send_buf(data)
      
    def send_data(self):
        n = len(self.datas)
        self.update_buf(self.datas)
        data=self.buf[:12*n]
        self.send_buf(data)

    def write_in_data(self,red,green,blue,order,on_off):
        # global data2,n
        order = order%(self.led_count + 1)
        if order > 0:
            n = len(self.datas)
            if n >= order:
                self.datas[order-1] = (red,green,blue)
                # print(self.datas,'------------')
            if n < order:
                data2 = []
                for i in range (order-n-1):
                    data2.append((0,0,0))
                data2.append((red,green,blue))
                self.datas = self.datas + data2
            # print('self.datas:',self.datas)
            n = len(self.datas)
            # print(n,'--------------')
            if on_off:
                self.send_data()
            else:
                pass
        
  • board.json
{
    "name": "haas506",
    "version": "1.0.0",
    "io": {
     "led_strip": {
        "type": "SPI",
        "port": 0,
        "mode": "master",
        "freq": 3200000
                
      },  
      "wdt0": {
        "type": "WDT",
        "timeout": 6
      },
      "cs": {
        "type": "GPIO",
        "port": 15,
        "dir": "output",
        "pull": "pullup"
      },   
      "serial1": {
        "type": "UART",
        "port": 0,
        "dataWidth": 8,
        "baudRate": 115200,
        "stopBits": 1,
        "flowControl": "disable",
        "parity": "none",
        "timeout": 1000
      },
      "serial2": {
        "type": "UART",
        "port": 1,
        "dataWidth": 8,
        "baudRate": 9600,
        "stopBits": 1,
        "flowControl": "disable",
        "parity": "none",
        "timeout": 1000
      },
      "serial3": {
        "type": "UART",
        "port": 2,
        "dataWidth": 8,
        "baudRate": 115200,
        "stopBits": 1,
        "flowControl": "disable",
        "parity": "none",
        "timeout": 1000
      }
    },
    "debugLevel": "ERROR",
    "repl": "enable",
    "replPort":0
  }

调试

1、串口调试工具log,网络连接成功成功连接阿里云
在这里插入图片描述

2、云端有数据传入,打开实时刷新,显示数据会自动更新。
在这里插入图片描述

3、物联网应用开发

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

3.1新建‘普通项目’

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

3.2关联产品和设备

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

3.3新建‘移动应用’

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

3.4页面设计

将组件拖到中间画布区
在这里插入图片描述
开关组件设置
在这里插入图片描述

  • 配置交互
    在这里插入图片描述
    依次设置其他开关组件
    反向彩色跑马灯
    在这里插入图片描述
    蓝色跑马灯
    在这里插入图片描述
    彩色跑马灯
    在这里插入图片描述
    霓虹灯
    在这里插入图片描述
    蓝色呼吸灯
    在这里插入图片描述
    彩色呼吸灯
    在这里插入图片描述
    流水灯
    在这里插入图片描述

3.5预览和发布上线

在页面‘’保存‘’并点击‘预览’进行预览。
在这里插入图片描述
手机扫描二维码,可以在手机看查看数据。

在这里插入图片描述

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值