当前位置:网站首页>Internet of things development practice 18 scenario linkage: how does an intelligent light perceive light? (I) (learning notes)
Internet of things development practice 18 scenario linkage: how does an intelligent light perceive light? (I) (learning notes)
2022-06-11 21:53:00 【Xiaohui_ Super】
Learn only as yourself 《 The development of the Internet of things 》 Learning notes of , Link to the original course : Geek time 《 The development of the Internet of things 》—— Guo Chaobin
List of articles
First step : Communications technology
Mr. Guo suggested choosing BLE Low power Bluetooth technology as a means of communication for light sensor devices . Because the deployment position of sensors is flexible , So you can't use the power cord directly , But need to use wireless communication technology , Again because BLE Power consumption ratio Wi-Fi low , So we choose BLE Communications technology .
BLE The device can be in 4 Working in two modes :
- Broadcast mode (Boradcaster), Simple broadcast mode . In this mode, the device cannot be connected , Data can only be broadcast at certain intervals , Use of other equipment , For example, mobile phone scanning processing .
- Slave mode (Peripheral), In this mode, the device can still broadcast data , It can also be connected . Once the connection is established , Both parties can communicate in two directions .
- Host mode (Central), In this mode, the device cannot broadcast , But you can scan the surrounding Bluetooth broadcast packets , Discover other devices , Then initiate the connection to these devices .
- Observer mode (Observer), In this mode, the device is like the host mode , And no broadcast , Instead, scan the surrounding Bluetooth broadcast packets , But the difference is , It will not establish a connection with the slave . Generally, the gateway that collects the broadcast packets of Bluetooth devices works in this mode .
In this lecture , The light sensor only needs to provide light intensity data , So we can make it work in broadcast mode .
The second step : Choose development board
The development board is still NodeMCU, You need to use a method based on ESP32 Chip NodeMCU Development board , It also supports Wi-Fi And low power Bluetooth communication technology , There are still a lot of it ADC Interface .
The third step : Get ready MicroPython Environmental Science
Environment construction can refer to 《 The development of the Internet of things 》16 Actual combat preparation : How to build a hardware development environment ?( Learning notes )
Step four : Build the hardware circuit of the light sensor
The following is Mr. Guo's wiring diagram :

Mr. Guo chose to be based on PT550 Environmental protection photodiode light sensor components , It is more sensitive , The measurement range is 0Lux~6000Lux.
This component outputs analog quantity through signal pin , We read NodeMCU ESP32 Of ADC Value of analog-to-digital converter (ADC7,GPIO35), You can get the intensity of the light . The larger the number , It means that the greater the light intensity .
ADC The maximum accuracy supported is 12 bit, The corresponding decimal system is 0~4095, We need to compare the voltage value with ADC Value to do a linear transformation , You can refer to the following code ( From the original )
from machine import ADC
from machine import Pin
class LightSensor():
def __init__(self, pin):
self.light = ADC(Pin(pin))
def value(self):
value = self.light.read()
print("Light ADC value:", value)
return int(value/4096*6000)
Step five : Programming Bluetooth
NodeMCU ESP32 The firmware of has been integrated BLE function , But we also need to define a certain format for broadcast packet data , So that other devices can successfully parse and use the scanned data .
How to define the format of Bluetooth broadcast packets ? Mr. Guo recommended Xiaomi's customized MiBeacon Bluetooth protocol .
In order to make it convenient for users to use Mi Jia APP And Bluetooth gateway , Can quickly find and communicate with BLE The device is connected , millet IoT Platform in BLE In the broadcast of the equipment ( be based on BLE agreement 4.0), Added Xiaomi service data (ServiceData UUID 0xFE95, namely Mibeacon), send BLE The device can identify its own identity and type when broadcasting data , It can be recognized and connected by users or Bluetooth gateway in time ; Besides , In order to better improve BLE The ability of intelligent equipment ,BLE MiBeacon The protocol also supports developers to meet their actual needs , Select Add Object Field , Through the gateway to Xiaomi IoT The platform reports BLE Event information and status information of equipment ( attribute ), Realize the functions of remote reporting and intelligent linkage of equipment status .
https://iot.mi.com/
MiBeacon The broadcast packet format of Bluetooth protocol is based on BLE Of GAP(Generic Access Profile) To formulate the .GAP Control the broadcast and connection of Bluetooth , Which controls how devices are discovered , And how to interact .
say concretely ,GAP Two ways are defined to let the device broadcast data :
One is broadcast data (Advertising Data payload), This is a must , Data length is 31 Bytes ;
The other is to scan the reply data (Scan Response payload), It is based on Bluetooth host devices ( Like mobile phone. ) Scan request sent (Scan Request) To respond to some additional information . The data length is the same as broadcast data .
( Be careful , bluetooth 5.0 There is extended broadcast data in , Data length and other characteristics are different , But it doesn't involve , So I won't introduce .)
therefore , As long as the broadcast message contains the following specified information , It can be considered as conforming to MiBeacon Bluetooth protocol .
1 . Advertising Data in Service Data(0x16) contain Mi Service UUID The radio bag ,UUID yes 0xFE95.
2 . Scan Response in Manufacturer Specific Data(0xFF) Broadcast package containing Xiaomi company identification code , Identification code ID yes 0x038F.
among , Whether in the Advertising Data in , still Scan Response in , Are defined in a unified format . According to the broadcast message format definition of the figure , Please refer to the table below .—— original text
| name | length (byte) | Whether must | describe |
|---|---|---|---|
| Frame Control | 2 | must | Control bits |
| Product ID | 2 | must | product ID, Need to be in Xiaomi IoT Development platform application |
| Frame Counter | 1 | must | Serial number , Used to remove heavy |
| MAC Address | 6 | be based on Frame Control | equipment Mac Address |
| Capability | 1 | be based on Frame Control | Equipment capacity |
| I/O capability | 2 | be based on Capacity | I/O Ability , At present, there is only high security level BLE This field is only used for access |
| Object | n( According to the actual demand ) | be based on Frame Control | Trigger event or broadcast attribute |
| Random Number | 3 | be based on Frame Control | Required if encrypted , And Frame Counter Merge into 4 byte Counter, Used to prevent replay |
| Message Integrity Check | 4 | be based on Frame Control | Required if encrypted ,MIC Four bytes |
Because we need to increase the ability of the light sensor to broadcast light intensity data , So we need to focus on Object The definition of .

according to MiBeacon The definition of , Light sensor Object ID yes 0x1007, Data length 3 Bytes , The range of values is 0~120000.
The following is the reference code provided by Mr. Guo 【 Slightly modified , Otherwise I can't run on my board 】:
#file: ble_lightsensor.py
import bluetooth
import struct
import time
from ble_advertising import advertising_payload
from micropython import const
_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_INDICATE_DONE = const(20)
_FLAG_READ = const(0x0002)
_FLAG_NOTIFY = const(0x0010)
_ADV_SERVICE_DATA_UUID = 0xFE95
_SERVICE_UUID_ENV_SENSE = 0x181A
_CHAR_UUID_AMBIENT_LIGHT = 'FEC66B35-937E-4938-9F8D-6E44BBD533EE'
# Service environmental sensing
_ENV_SENSE_UUID = bluetooth.UUID(_SERVICE_UUID_ENV_SENSE)
# Characteristic ambient light density
_AMBIENT_LIGHT_CHAR = (
bluetooth.UUID(_CHAR_UUID_AMBIENT_LIGHT),
_FLAG_READ | _FLAG_NOTIFY ,
)
_ENV_SENSE_SERVICE = (
_ENV_SENSE_UUID,
(_AMBIENT_LIGHT_CHAR,),
)
# https://specificationrefs.bluetooth.com/assigned-values/Appearance%20Values.pdf
_ADV_APPEARANCE_GENERIC_AMBIENT_LIGHT = const(1344)
class BLELightSensor:
def __init__(self, ble, name='Nodemcu'):
self._ble = ble
self._ble.active(True)
self._ble.irq(self._irq)
((self._handle,),) = self._ble.gatts_register_services((_ENV_SENSE_SERVICE,))
self._connections = set()
time.sleep_ms(500)
self._payload = advertising_payload(
name=name, services=[_ENV_SENSE_UUID], appearance=_ADV_APPEARANCE_GENERIC_AMBIENT_LIGHT
)
self._sd_adv = None
self._advertise()
def _irq(self, event, data):
# Track connections so we can send notifications.
if event == _IRQ_CENTRAL_CONNECT:
conn_handle, _, _ = data
self._connections.add(conn_handle)
elif event == _IRQ_CENTRAL_DISCONNECT:
conn_handle, _, _ = data
self._connections.remove(conn_handle)
# Start advertising again to allow a new connection.
self._advertise()
elif event == _IRQ_GATTS_INDICATE_DONE:
conn_handle, value_handle, status = data
def set_light(self, light_den, notify=False):
self._ble.gatts_write(self._handle, struct.pack("!h", int(light_den)))
self._sd_adv = self.build_mi_sdadv(light_den)
self._advertise()
if notify:
for conn_handle in self._connections:
if notify:
# Notify connected centrals.
self._ble.gatts_notify(conn_handle, self._handle)
def build_mi_sdadv(self, density):
uuid = 0xFE95
fc = 0x0010
pid = 0x0002
fcnt = 0x01
mac = self._ble.config('mac')
objid = 0x1007
objlen = 0x03
objval = density
service_data = struct.pack("<3HB",uuid,fc,pid,fcnt)+mac[1]+struct.pack("<H2BH",objid,objlen,0,objval)
print("Service Data:",service_data)
return advertising_payload(service_data=service_data)
def _advertise(self, interval_us=500000):
self._ble.gap_advertise(interval_us, adv_data=self._payload)
time.sleep_ms(100)
print("sd_adv",self._sd_adv)
if self._sd_adv is not None:
print("sdddd_adv",self._sd_adv)
self._ble.gap_advertise(interval_us, adv_data=self._sd_adv)
# File: main.py
from ble_lightsensor import BLELightSensor
from lightsensor import LightSensor
import time
import bluetooth
def main():
ble = bluetooth.BLE()
ble.active(True)
ble_light = BLELightSensor(ble)
light = LightSensor(35)
light_density = light.value()
i = 0
while True:
# Write every second, notify every 10 seconds.
i = (i + 1) % 10
ble_light.set_light(light_density, notify=i == 0)
print("Light Lux:", light_density)
light_density = light.value()
time.sleep_ms(1000)
if __name__ == "__main__":
main()
In addition to the above 3 individual Python Script , I need one more ble_advertising.py, You can go to MicroPython Official Bluetooth Get... From the example , Address :https://github.com/micropython/micropython/tree/master/examples/bluetooth
radio broadcast service data I have adjusted this function for a long time without success , Finally found ....:
Here is my use of ble_advertising.py Script files :
# Helpers for generating BLE advertising payloads.
from micropython import const
import struct
import bluetooth
# Advertising payloads are repeated packets of the following form:
# 1 byte data length (N + 1)
# 1 byte type (see constants below)
# N bytes type-specific data
_ADV_TYPE_FLAGS = const(0x01)
_ADV_TYPE_NAME = const(0x09)
_ADV_TYPE_UUID16_COMPLETE = const(0x3)
_ADV_TYPE_UUID32_COMPLETE = const(0x5)
_ADV_TYPE_UUID128_COMPLETE = const(0x7)
_ADV_TYPE_UUID16_MORE = const(0x2)
_ADV_TYPE_UUID32_MORE = const(0x4)
_ADV_TYPE_UUID128_MORE = const(0x6)
_ADV_TYPE_APPEARANCE = const(0x19)
_ADV_TYPE_SERVICE_DATA = const(0x16)
# Generate a payload to be passed to gap_advertise(adv_data=...).
def advertising_payload(limited_disc=False, br_edr=False, name=None, services=None, appearance=0, service_data = None):
payload = bytearray()
def _append(adv_type, value):
nonlocal payload
payload += struct.pack("BB", len(value) + 1, adv_type) + value
_append(
_ADV_TYPE_FLAGS,
struct.pack("B", (0x01 if limited_disc else 0x02) + (0x18 if br_edr else 0x04)),
)
if name:
_append(_ADV_TYPE_NAME, name)
if services:
for uuid in services:
b = bytes(uuid)
if len(b) == 2:
_append(_ADV_TYPE_UUID16_COMPLETE, b)
elif len(b) == 4:
_append(_ADV_TYPE_UUID32_COMPLETE, b)
elif len(b) == 16:
_append(_ADV_TYPE_UUID128_COMPLETE, b)
# See org.bluetooth.characteristic.gap.appearance.xml
if appearance:
_append(_ADV_TYPE_APPEARANCE, struct.pack("<h", appearance))
if service_data:
_append(_ADV_TYPE_SERVICE_DATA, service_data)
return payload
def decode_field(payload, adv_type):
i = 0
result = []
while i + 1 < len(payload):
if payload[i + 1] == adv_type:
result.append(payload[i + 2 : i + payload[i] + 1])
i += 1 + payload[i]
return result
def decode_name(payload):
n = decode_field(payload, _ADV_TYPE_NAME)
return str(n[0], "utf-8") if n else ""
def decode_services(payload):
services = []
for u in decode_field(payload, _ADV_TYPE_UUID16_COMPLETE):
services.append(bluetooth.UUID(struct.unpack("<h", u)[0]))
for u in decode_field(payload, _ADV_TYPE_UUID32_COMPLETE):
services.append(bluetooth.UUID(struct.unpack("<d", u)[0]))
for u in decode_field(payload, _ADV_TYPE_UUID128_COMPLETE):
services.append(bluetooth.UUID(u))
return services
def demo():
payload = advertising_payload(
name="micropython",
services=[bluetooth.UUID(0x181A), bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")],
)
print(payload)
print(decode_name(payload))
print(decode_services(payload))
if __name__ == "__main__":
demo()
Step six : Verify the light sensor
Next, we need to verify whether the equipment is working properly , First, use the serial port terminal to check the program operation , The terminal prints the message sent by the device Service Data, And light intensity and light sensor ADC value :

Next, download a Bluetooth debugging with your mobile phone APP, The original text recommends 3 paragraph (LightBlue、nRFConnect、BLEScanner), You can also use any other similar software .
The Bluetooth name of the device is “Nodemcu”, This is BLELightSensor Class __init__() Function ,

Check the Bluetooth broadcast package , There's something wrong with it ...( Is it the debugging assistant ?)

边栏推荐
- Classes and objects (3)
- Binary search - Learning
- Bipartite King
- Customer information management software
- Uncover the secret of the popular app. Why is it so black
- C语言实现八种排序 - 归并排序
- Redis basic data type (set)
- Redis basic data type (Zset) ordered collection
- 判断大小端存储两种办法
- [niuke.com] dp31 [template] complete Backpack
猜你喜欢

EndnoteX9简介及基本教程使用说明

The upcoming launch of the industry's first retail digital innovation white paper unlocks the secret of full link digital success

How to use RPA robot to start the first step of digital transformation of freight forwarding industry?
![[niuke.com] ky41 put apples](/img/55/cc246aed1438fdd245530beb7574f0.jpg)
[niuke.com] ky41 put apples

快速排序的优化

Leetcode-98- validate binary search tree

JVM | virtual machine stack (local variable table; operand stack; dynamic link; method binding mechanism; method call; method return address)

华为设备配置HoVPN
![[today in history] June 11: the co inventor of Monte Carlo method was born; Google launched Google Earth; Google acquires waze](/img/eb/147d4aac20639d50b204dcf424c9e2.png)
[today in history] June 11: the co inventor of Monte Carlo method was born; Google launched Google Earth; Google acquires waze

Flutter series: detailed explanation of container layout commonly used in flutter
随机推荐
Experiment 10 Bezier curve generation - experiment improvement - control point generation of B-spline curve
206.反转链表
ESP32C3 Arduino库使用方法
Leetcode-43- string multiplication
如何使用事物码 SAT 查找某个 SAPGUI 屏幕字段对应的后台存储数据库表的名称试读版
In the post epidemic era, how can enterprise CIOs improve enterprise production efficiency through distance
【历史上的今天】6 月 11 日:蒙特卡罗方法的共同发明者出生;谷歌推出 Google 地球;谷歌收购 Waze
69. x的平方根
Redis data type (string)
类与对象(3)
C语言实现八种排序(3)
Master of a famous school has been working hard for 5 years. AI has no paper. How can the tutor free range?
Classes and objects (1)
Customer information management software
Codeworks round 744 (Div. 3) problem solving Report
Flutter series: detailed explanation of container layout commonly used in flutter
行而不辍,未来可期|云扩科技入选上海市专精特新企业
Classes and objects (3)
The network connection is normal, but Baidu web page can not be opened and displayed. You can't access this website solution
Redis transaction