WiFi 智能灯
| 第1行: | 第1行: | ||
| + | |||
| + | |||
| + | |||
== 概述 == | == 概述 == | ||
| − | Open | + | OpenLight 球泡灯: |
| + | |||
| + | [[文件:Openlight-bulb-1024.jpg | 800px]] | ||
| + | |||
| + | |||
| + | |||
| + | OpenLight 独立控制器: | ||
| + | |||
| + | [[文件:OpenLight-Controller-2.jpg | 600px]] | ||
| + | [[文件:Openlight-ctrl-demo.jpg | 600px]] | ||
| + | |||
| + | |||
| + | [[文件:Noduino-works-with-logo.png | 600px]] | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | == Quick Start == | ||
| + | |||
| + | 快速上手视频:http://v.youku.com/v_show/id_XMTY1MTMzMjA0NA==.html | ||
| + | |||
| + | |||
| + | [[文件:Maike-wifi-bulb-2955-all.jpg]] | ||
| + | |||
| + | * 灯通电,等待 8 s左右 | ||
| + | * 灯在红色渐变,表示灯在等待配网 | ||
| + | * 如果不在红色渐变,请开关三次(开 – 灯亮 – 关,重复三次),可进入红色渐变等待配网状态 | ||
| + | * 手机连接 WiFi 路由,微信扫描右侧二维码,点击 ”配置设备上网“ | ||
| + | * 按提示输入 WiFi 密码,点 “连接”,等待配网完成(注意,设备不支持 5G WiFi,只支持 2.4G;另外企业级安全认证也不支持) | ||
| + | * WiFi 配置完成后,微信自动进入局域网发现设备模式,其会列出设备列表 | ||
| + | * 点击第一个设备,进入页面,在页面最下面会有 “绑定设备” 按钮 (如果已经绑定过改设备,最下面的按钮为“进入公众号”),点击按钮,完成设备绑定 | ||
| + | * 完成后,点“进入公众号”,在公众号菜单的 “智能设备”,即可列出你绑定的所有设备,点一个设备,即可进入设备控制页 | ||
| + | |||
| + | |||
| + | [[文件:Openlight-ui.jpg | 640px]] | ||
| + | |||
| + | |||
| + | ;;其他说明: | ||
| + | |||
| + | * 其他人需要控制设备,需要先连接到同样的路由器,在设备通电的情形下,扫描同样的二维码,点“设备已联网,跳过此步”,直接“发现”、“绑定设备” 即可在公众号菜单“智能设备里控制 | ||
| + | * 灯泡要迁移到其他的路由,可开关三次,扫描二维码配一下网络即可,无需再绑定 | ||
| + | * 灯泡从家移到公司,找不到原来的路由会自动进入等待配网状态(红色渐变),扫描二维码配一下网络即可 | ||
| + | * 开关 6次(开 – 灯亮 – 关,重复 6次),可恢复出厂设置 | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | == Open API == | ||
| + | |||
| + | Afer you guys 'Link Device' in WeChat, Enter Official Account: | ||
| + | |||
| + | |||
| + | * click "Devices" to list your binding devices | ||
| + | * select your OpenLight in the list, enter control page, click upright corner, then Copy URL | ||
| + | * paste the URL into web browser (Chrome or Safari) to access the control page in browser | ||
| + | * check the source code of the page to get the following variables: | ||
| + | |||
| + | |||
| + | <source lang=php> | ||
| + | var devid = YOUR_DEVICE_ID; | ||
| + | var mqtt_uname = xxxxxxxx; | ||
| + | var mqtt_pass = TTTTTTTTTTTTTTTT; < ---- 3600s life time | ||
| + | var mqtt_server = xxx.xxx.xxx.xxx; | ||
| + | var mqtt_port = xxx; | ||
| + | </source> | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | === node.js === | ||
| + | |||
| + | Prepare the node.js: | ||
| + | |||
| + | <source lang=bash> | ||
| + | # download the node-v6.9.1-xxx.tgz from http://nodejs.org | ||
| + | $ tar xf node-v6.9.1-*.tar.xz | ||
| + | $ sudo cp -a node-v6.9.1*/* /usr/local/ | ||
| + | $ sudo npm install -g MQTTClient | ||
| + | $ sudo npm install -g request | ||
| + | </source> | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | ==== Turn Off ==== | ||
| + | |||
| + | Using the node.js to switch off the OpenLigh: | ||
| + | |||
| + | <source lang=bash> | ||
| + | $ cat light-off.js | ||
| + | #! /usr/bin/env node | ||
| + | |||
| + | var opt = { | ||
| + | username: "YOUR_mqtt_uname", | ||
| + | password: "" | ||
| + | }; | ||
| + | var http_req = require('/usr/local/lib/node_modules/request'); | ||
| + | http_req.post( | ||
| + | 'http://api.noduino.org/user/token', | ||
| + | { json: {user_id: opt.username} }, | ||
| + | function (error, response, body) { | ||
| + | if (!error && response.statusCode == 200) { | ||
| + | console.log(body); | ||
| + | |||
| + | opt.password = body.user_token; | ||
| + | |||
| + | var MQTTClient = require('MQTTClient').Client; | ||
| + | var client = new MQTTClient('mqtt.noduino.org', 1883, opt); | ||
| + | client.connect(function () { | ||
| + | console.log("connect ok!"); | ||
| + | |||
| + | var pubopt = { | ||
| + | qos_level: 2 | ||
| + | }; | ||
| + | |||
| + | var state = { | ||
| + | on: 0 <---- off | ||
| + | }; | ||
| + | var data = '{"m":"set", "d":{' + '"s":' + state.on + '}}'; | ||
| + | client.publish('app2dev/YOUR_DEVICE_ID', data, pubopt, function (message_id) { | ||
| + | console.log("public ok! message_id = " + message_id); | ||
| + | process.exit(0); | ||
| + | }); | ||
| + | }); | ||
| + | } else { | ||
| + | console.log("Request the user token failed"); | ||
| + | process.exit(1); | ||
| + | } | ||
| + | } | ||
| + | ); | ||
| + | |||
| + | $ ./light-off.js | ||
| + | </source> | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | ==== Turn On ==== | ||
| + | |||
| + | Turn on the OpenLight: | ||
| + | |||
| + | <source lang=bash> | ||
| + | $ cat light-on.js | ||
| + | #! /usr/bin/env node | ||
| + | |||
| + | var opt = { | ||
| + | username: "YOUR_mqtt_uname", | ||
| + | password: "" | ||
| + | }; | ||
| + | var http_req = require('/usr/local/lib/node_modules/request'); | ||
| + | http_req.post( | ||
| + | 'http://api.noduino.org/user/token', | ||
| + | { json: {user_id: opt.username, app_id:"mj2030064278", app_key:"0077d4829f52b1b2d668f8a82c5f5ded"} }, | ||
| + | function (error, response, body) { | ||
| + | if (!error && response.statusCode == 200) { | ||
| + | console.log(body); | ||
| + | |||
| + | opt.password = body.user_token; | ||
| + | |||
| + | var MQTTClient = require('MQTTClient').Client; | ||
| + | var client = new MQTTClient('mqtt.noduino.org', 1883, opt); | ||
| + | client.connect(function () { | ||
| + | console.log("connect ok!"); | ||
| + | |||
| + | var pubopt = { | ||
| + | qos_level: 2 | ||
| + | }; | ||
| + | |||
| + | var state = { | ||
| + | on: 1 <---- on | ||
| + | }; | ||
| + | var data = '{"m":"set", "d":{' + '"s":' + state.on + '}}'; | ||
| + | client.publish('app2dev/YOUR_DEVICE_ID', data, pubopt, function (message_id) { | ||
| + | console.log("public ok! message_id = " + message_id); | ||
| + | process.exit(0); | ||
| + | }); | ||
| + | }); | ||
| + | } else { | ||
| + | console.log("Request the user token failed"); | ||
| + | process.exit(1); | ||
| + | } | ||
| + | } | ||
| + | ); | ||
| + | |||
| + | $ ./light-on.js | ||
| + | </source> | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | ==== Setup Color ==== | ||
| + | |||
| + | Change the color of the OpenLight: | ||
| + | |||
| + | <source lang=bash> | ||
| + | $ cat light-color.js | ||
| + | #! /usr/bin/env node | ||
| + | |||
| + | var opt = { | ||
| + | username: "YOUR_mqtt_uname", | ||
| + | password: "" | ||
| + | }; | ||
| + | |||
| + | var http_req = require('/usr/local/lib/node_modules/request'); | ||
| + | http_req.post( | ||
| + | 'http://api.noduino.org/user/token', | ||
| + | { json: {user_id: opt.username, app_id:"mj2030064278", app_key:"0077d4829f52b1b2d668f8a82c5f5ded"} }, | ||
| + | function (error, response, body) { | ||
| + | if (!error && response.statusCode == 200) { | ||
| + | console.log(body); | ||
| + | |||
| + | opt.password = body.user_token; | ||
| + | |||
| + | var MQTTClient = require('MQTTClient').Client; | ||
| + | var client = new MQTTClient('mqtt.noduino.org', 1883, opt); | ||
| + | client.connect(function () { | ||
| + | console.log("connect ok!"); | ||
| + | |||
| + | var pubopt = { | ||
| + | qos_level: 2 | ||
| + | }; | ||
| + | |||
| + | var state = { | ||
| + | red: 0, | ||
| + | green: 0, | ||
| + | blue: 255, <--------- outputting full power of the blue channel | ||
| + | white: 0, | ||
| + | on: 1 | ||
| + | }; | ||
| + | |||
| + | data = '{"m":"set", "d":{' + '"r":' + state.red + ',"g":' + state.green | ||
| + | + ',"b":' + state.blue + ',"w":' + state.white | ||
| + | + ',"s":' + state.on + '}}'; | ||
| + | client.publish('app2dev/YOUR_DEVICE_ID', data, pubopt, function (message_id) { | ||
| + | console.log("public ok! message_id = " + message_id); | ||
| + | process.exit(0); | ||
| + | }); | ||
| + | }); | ||
| + | } else { | ||
| + | console.log("Request the user token failed"); | ||
| + | process.exit(1); | ||
| + | } | ||
| + | } | ||
| + | ); | ||
| + | |||
| + | $ ./light-color.js | ||
| + | </source> | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | ==== FAQ ==== | ||
| + | |||
| + | <font color=red><b>If you get the following error:</b></font> | ||
| + | |||
| + | <source lang=bash> | ||
| + | /usr/local/lib/node_modules/MQTTClient/client.js:56 | ||
| + | throw Error('user names are kept to 12 characters or fewer'); | ||
| + | ^ | ||
| + | |||
| + | Error: user names are kept to 12 characters or fewer | ||
| + | </source> | ||
| + | |||
| + | Please patch the /usr/local/lib/node_modules/MQTTClient/client.js to remove the line of checking the length of username and password: | ||
| + | |||
| + | <source lang=bash> | ||
| + | --- a/client.js | ||
| + | +++ b/client.js | ||
| + | @@ -52,10 +52,10 @@ var Client = exports.Client = function (host, port, options) { | ||
| + | options.alive_timer = 30; | ||
| + | options.ping_timer = parseInt(options.alive_timer * 0.6 * 1000); | ||
| + | // 用户名和密码 | ||
| + | - if (typeof options.username == 'string' && options.username.length > 12) | ||
| + | - throw Error('user names are kept to 12 characters or fewer'); | ||
| + | - if (typeof options.password == 'string' && options.password.length > 12) | ||
| + | - throw Error('passwords are kept to 12 characters or fewer'); | ||
| + | + //if (typeof options.username == 'string' && options.username.length > 12) | ||
| + | + // throw Error('user names are kept to 12 characters or fewer'); | ||
| + | + //if (typeof options.password == 'string' && options.password.length > 12) | ||
| + | + // throw Error('passwords are kept to 12 characters or fewer'); | ||
| + | // Will flag | ||
| + | if (options.will_flag && (typeof options.will_topic != 'string' || typeof options.will_message != 'string')) | ||
| + | throw Error('missing will_topic or will_message when will_flag is set'); | ||
| + | </source> | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | === HTML5 === | ||
| + | |||
| + | The device control page in WeChat is a H5 page. Using a MQTT client implement in javascript , using the mqttws31.js library: | ||
| + | |||
| + | <source lang=javascript> | ||
| + | var client_id = parseInt(Math.random() * 10000, 10) + '_' + mqtt_uname; | ||
| + | var client = new Paho.MQTT.Client(mqtt_server, mqtt_port, "/mqtt", client_id); | ||
| + | function failConnect(e) { | ||
| + | console.log("connect failed"); | ||
| + | console.log(e); | ||
| + | console.log("reconnecting ..."); | ||
| + | client.connect({userName: mqtt_uname, password: mqtt_pass, onSuccess:onConnect, onFailure: failConnect, mqttVersion:3}); | ||
| + | } | ||
| + | function onConnect() { | ||
| + | console.log("onConnect OK!"); | ||
| + | subscribe('dev2app/' + devid); | ||
| + | } | ||
| + | function subscribe(topic) { | ||
| + | client.subscribe(topic); | ||
| + | } | ||
| + | function onMessageArrived (message) { | ||
| + | console.log("Arrived Message: [", message.payloadString, "]"); | ||
| + | try { | ||
| + | job = JSON.parse(message.payloadString); | ||
| + | set = job.d; | ||
| + | } catch(e) { | ||
| + | console.log("JSON object error!"); | ||
| + | alert("JSON error, RX data is: " + message.payloadString); | ||
| + | return; | ||
| + | } | ||
| + | if(job.m == 'set' || job.m == 'status') { | ||
| + | //console.log("set ui state"); | ||
| + | set_ui_state(set); | ||
| + | } | ||
| + | if(job.m == 'offline') { | ||
| + | blockUI(); | ||
| + | } | ||
| + | } | ||
| + | function onDisConnect() { | ||
| + | console.log("reconnecting ..."); | ||
| + | client.connect({userName: mqtt_uname, password: mqtt_pass, onSuccess:onConnect, onFailure: failConnect, mqttVersion:3}); | ||
| + | } | ||
| + | function mqtt_publish(msg){ | ||
| + | var topic = 'app2dev/' + devid; | ||
| + | message = new Paho.MQTT.Message(msg); | ||
| + | message.destinationName = topic; | ||
| + | client.send(message); | ||
| + | console.log("publish message: " + msg); | ||
| + | } | ||
| + | function mqtt_init() { | ||
| + | client.connect({userName: mqtt_uname, password: mqtt_pass, onSuccess:onConnect, onFailure: failConnect, mqttVersion:3}); | ||
| + | client.onMessageArrived = onMessageArrived; | ||
| + | client.onConnectionLost = onDisConnect; | ||
| + | } | ||
| + | mqtt_init(); | ||
| + | </source> | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | == 极客定制 == | ||
| + | |||
| + | === 编译固件 === | ||
获取 noduino-sdk: | 获取 noduino-sdk: | ||
| 第20行: | 第364行: | ||
<source lang=bash> | <source lang=bash> | ||
| − | $ cd ../sketch/ | + | $ cd ../sketch/open-light |
| − | $ make | + | $ make |
</source> | </source> | ||
| + | <br><br> | ||
| − | [[文件: | + | === 烧写固件 === |
| + | |||
| + | ==== Serial ==== | ||
| + | |||
| + | Prepare a USB2UART board, something like FT232RL or CP2102/CP2104: | ||
| + | |||
| + | [[文件:Ft232.jpg | 800px]] | ||
| + | |||
| + | |||
| + | |||
| + | '''Upload firmware throught serial for OpenLight Bulb:''' | ||
| + | |||
| + | [[文件:Openlight-bulb-upload-serial-900.jpg | 600px]]] | ||
| + | |||
| + | |||
| + | '''Upload firmware throught serial for OpenLight Controller:''' | ||
| + | |||
| + | [[文件:5pin.jpg]] | ||
| + | |||
| + | |||
| + | |||
| + | * USB2UART_GND ------> SmartNode_GPIO0 / Bulb_GPIO0 | ||
| + | * USB2UAR_GND -----> SmartNode_GND / Bulb_GND | ||
| + | * USB2UAR_RXD -----> SmartNode_TX / Bulb_TX | ||
| + | * USB2UAR_TXD -----> SmartNode_RX / Bulb_TX | ||
| + | |||
| + | |||
| + | Connect USB2UAR_VCC3.3 -----> SmartNode_VCC / Bulb_3V3 at last | ||
| + | |||
| + | ESP8285 will be enter upload mode, we can upload the compiled firmware through serial using following commands in Linux: | ||
| + | |||
| + | <source lang=bash> | ||
| + | $ cd /path/to/noduino-sdk/sketch/open-light | ||
| + | $ make produce ESPPORT=/dev/ttyUSB1 | ||
| + | </source> | ||
| + | |||
| + | |||
| + | In windows: | ||
| + | |||
| + | <source lang=bash> | ||
| + | $ make produce ESPPORT=COM7 | ||
| + | </source> | ||
| + | |||
| + | COM7 is your USB2UART device | ||
| + | |||
| + | |||
| + | In MAC OS, maybe it's: | ||
| + | |||
| + | <source lang=bash> | ||
| + | $ make produce ESPPORT=/dev/cu.SLAB_USBtoUART | ||
| + | </source> | ||
| + | |||
| + | /dev/cu.SLAB_USBtoUART is your USB2UART device | ||
<br><br> | <br><br> | ||
| + | |||
| + | ==== Online ==== | ||
| + | |||
| + | ;; Access: http://dev.noduino.org/openlight | ||
| + | |||
| + | |||
| + | ;; Login: | ||
| + | |||
| + | * Username: noduino | ||
| + | * password: noduino1234 | ||
| + | |||
| + | |||
| + | Click the "Add files", select the user1.bin and user2.bin located in /path/to/noduino-sdk/sketch/open-light/build/ | ||
| + | |||
| + | |||
| + | Then click "Start upload" to upload the user1.bin and user2.bin into the server temporaily | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | == 硬件原理 == | ||
| + | |||
| + | === LED 灯珠 === | ||
| + | |||
| + | OpenLight 铝基板上,LED 灯珠默认布局为: | ||
| + | |||
| + | * Red LED 6 颗串联,正极接 12V,负极接控制板 R (MY9291 之 OUTA) | ||
| + | * Green LED 4 颗串联,正极接 12V,负极接控制板 G (MY9291 之 OUTB) | ||
| + | * Blue LED 4 颗串联,正极接 12V,负极接控制板 B (MY9291 之 OUTC) | ||
| + | * White LED x8 (4 颗串联为一组, 2 组并联,正极接 12V,负极接控制板 W (MY9291 之 OUTC)) | ||
| + | |||
| + | |||
| + | LED 灯珠 (5730) 单颗特性为: | ||
| + | |||
| + | * 尺寸 5.7 x 3.0 mm | ||
| + | * 最大电流 150mA (0.5W) | ||
| + | * VF 为 3.0 - 3.4V (Red LED为 2.0 - 2.2V) | ||
| + | * 亮度 50 - 55 lm | ||
| + | |||
| + | |||
| + | LED 灯珠其实就是一个二极管,只要有一个正向导通电压 (VF) 就能发光,一般为 2 - 3.5V,低于此电压灯珠不能发光,高于此电压,灯珠会烧坏。 | ||
| + | |||
| + | 控制灯珠亮度的,是电流大小,因此调光灯实际调得是电流的大小。电流超过额定电流,会加速灯珠老化,缩短灯珠寿命 | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | === MY9291 === | ||
| + | |||
| + | OpenLight 采用台湾明阳 4 通道恒流 LED 驱动芯片,控制 R, G, B, W 四路 LED 灯珠 | ||
| + | |||
| + | |||
| + | ;;特性: | ||
| + | |||
| + | * 3.3 - 5V 电源电压范围(±10%) | ||
| + | * 每个通道 5 - 350 mA 恒流输出范围 | ||
| + | * 可承受最大输出电压 24V,支持多颗 LED 串联 | ||
| + | * 外接器件少,仅需四个外接电组来设定四組恆流电流 | ||
| + | |||
| + | |||
| + | ;;框图: | ||
| + | |||
| + | [[文件:MY9291.app.jpg | 600px]] | ||
| + | |||
| + | 电源为恒压源,可以多片级联,MCU 的控制线就两个:DI 和 DCK | ||
| + | |||
| + | |||
| + | ;; 电源电压与灯珠串并联确定: | ||
| + | |||
| + | * 12V 电源的情形,如选用 VF 为 3V 左右的 LED 灯珠,则需要 4 颗串联,这样每颗灯珠分到电压为 3V 左右;2V 左右的灯珠,则需要 6 颗串联 | ||
| + | * 24V 电源,则 3V 灯珠 8 颗串联,2V 灯珠 12 颗串联 | ||
| + | * 6V 电源,则 3V 灯珠 2 颗串联,2V 灯珠 3 颗串联 | ||
| + | |||
| + | |||
| + | ;; 输出限流 | ||
| + | |||
| + | MY9291 单路最大输出 350mA,为节约灯珠寿命,可限制通过灯珠的最大电流以节约灯珠寿命 | ||
| + | |||
| + | 最大输出电流限制: | ||
| + | |||
| + | R = 380mV / Iout | ||
| + | |||
| + | 满输出 350mA,则每路的限流电阻都得选为:1R,1/4 W 够用 | ||
| + | |||
| + | |||
| + | OpenLight 球泡灯,R/G/B 选用电阻 4R7,限流为 81mA 左右,W 用两个 4R7 并联 2.35R 左右,限流为 162mA 左右。这样基本限制经过每颗 5730 (0.5W) 灯珠的电流为 80mA 左右,以延迟灯珠老化。这样整体功率被限制在 5W,如要增加亮度,可将这 5 个 4R7 电阻替换为 3R0,可将输出功率增加到 7W | ||
| + | |||
| + | |||
| + | 其他可选择的: | ||
| + | |||
| + | * MY9231 3 通道恒流 LED 驱动芯片 | ||
| + | * MY9221 12 通道恒流 LED 驱动芯片 | ||
| + | |||
| + | |||
| + | <br><br> | ||
| + | |||
| + | == 电源 == | ||
| + | |||
| + | === 12V === | ||
| + | |||
| + | 220V 转 12V 恒压电源模块,额定 12W,1A 电流输出 | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | === 3.3V === | ||
| + | |||
| + | 控制板上的 ESP8266/ESP8285 芯片、MY9291/MY9231 芯片、SPI Flash 芯片皆为 3.3V 供电 | ||
| + | |||
| + | ==== MP1470 ==== | ||
| + | |||
| + | 宽电压供电的 | ||
| + | |||
| + | * Wide 4.7V to 16V Operating Input Range | ||
| + | * Fixed 500kHz Switching Frequency | ||
| + | * Over-Current Protection and Hiccup | ||
| + | * Thermal Shutdown | ||
| + | * Output Adjustable from 0.8V | ||
| + | * Available in a 6-pin TSOT-23 package | ||
| + | |||
| + | |||
| + | [[文件:Mp1470-typical.jpg]] | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | ==== MP2359 ==== | ||
| + | |||
| + | * Wide 4.5V to 24V Operating Input Range | ||
| + | * 1.2A Peak Output Current | ||
| + | * 0.35Ω Internal Power MOSFET Switch | ||
| + | * Stable with Low ESR Output Ceramic Capacitors | ||
| + | * Up to 92% Efficiency | ||
| + | * 0.1μA Shutdown Mode | ||
| + | * Fixed 1.4MHz Frequency | ||
| + | * Thermal Shutdown | ||
| + | * Cycle-by-Cycle Over Current Protection | ||
| + | * Output Adjustable from 0.81V to 15V | ||
| + | |||
| + | |||
| + | [[文件:Mp2359-sch.jpg]] | ||
| + | |||
| + | <br><br> | ||
| + | |||
| + | == 参考 == | ||
| + | |||
| + | ;;更多信息访问: | ||
| + | |||
| + | * [[Noduino]] | ||
| + | |||
<br><br> | <br><br> | ||
<br><br> | <br><br> | ||
2017年10月10日 (二) 14:46的最后版本
目录 |
[编辑] 1 概述
OpenLight 球泡灯:
OpenLight 独立控制器:
[编辑] 2 Quick Start
快速上手视频:http://v.youku.com/v_show/id_XMTY1MTMzMjA0NA==.html
- 灯通电,等待 8 s左右
- 灯在红色渐变,表示灯在等待配网
- 如果不在红色渐变,请开关三次(开 – 灯亮 – 关,重复三次),可进入红色渐变等待配网状态
- 手机连接 WiFi 路由,微信扫描右侧二维码,点击 ”配置设备上网“
- 按提示输入 WiFi 密码,点 “连接”,等待配网完成(注意,设备不支持 5G WiFi,只支持 2.4G;另外企业级安全认证也不支持)
- WiFi 配置完成后,微信自动进入局域网发现设备模式,其会列出设备列表
- 点击第一个设备,进入页面,在页面最下面会有 “绑定设备” 按钮 (如果已经绑定过改设备,最下面的按钮为“进入公众号”),点击按钮,完成设备绑定
- 完成后,点“进入公众号”,在公众号菜单的 “智能设备”,即可列出你绑定的所有设备,点一个设备,即可进入设备控制页
- 其他说明:
- 其他人需要控制设备,需要先连接到同样的路由器,在设备通电的情形下,扫描同样的二维码,点“设备已联网,跳过此步”,直接“发现”、“绑定设备” 即可在公众号菜单“智能设备里控制
- 灯泡要迁移到其他的路由,可开关三次,扫描二维码配一下网络即可,无需再绑定
- 灯泡从家移到公司,找不到原来的路由会自动进入等待配网状态(红色渐变),扫描二维码配一下网络即可
- 开关 6次(开 – 灯亮 – 关,重复 6次),可恢复出厂设置
[编辑] 3 Open API
Afer you guys 'Link Device' in WeChat, Enter Official Account:
- click "Devices" to list your binding devices
- select your OpenLight in the list, enter control page, click upright corner, then Copy URL
- paste the URL into web browser (Chrome or Safari) to access the control page in browser
- check the source code of the page to get the following variables:
var devid = YOUR_DEVICE_ID; var mqtt_uname = xxxxxxxx; var mqtt_pass = TTTTTTTTTTTTTTTT; < ---- 3600s life time var mqtt_server = xxx.xxx.xxx.xxx; var mqtt_port = xxx;
[编辑] 3.1 node.js
Prepare the node.js:
# download the node-v6.9.1-xxx.tgz from http://nodejs.org $ tar xf node-v6.9.1-*.tar.xz $ sudo cp -a node-v6.9.1*/* /usr/local/ $ sudo npm install -g MQTTClient $ sudo npm install -g request
[编辑] 3.1.1 Turn Off
Using the node.js to switch off the OpenLigh:
$ cat light-off.js
#! /usr/bin/env node
var opt = {
username: "YOUR_mqtt_uname",
password: ""
};
var http_req = require('/usr/local/lib/node_modules/request');
http_req.post(
'http://api.noduino.org/user/token',
{ json: {user_id: opt.username} },
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
opt.password = body.user_token;
var MQTTClient = require('MQTTClient').Client;
var client = new MQTTClient('mqtt.noduino.org', 1883, opt);
client.connect(function () {
console.log("connect ok!");
var pubopt = {
qos_level: 2
};
var state = {
on: 0 <---- off
};
var data = '{"m":"set", "d":{' + '"s":' + state.on + '}}';
client.publish('app2dev/YOUR_DEVICE_ID', data, pubopt, function (message_id) {
console.log("public ok! message_id = " + message_id);
process.exit(0);
});
});
} else {
console.log("Request the user token failed");
process.exit(1);
}
}
);
$ ./light-off.js
[编辑] 3.1.2 Turn On
Turn on the OpenLight:
$ cat light-on.js
#! /usr/bin/env node
var opt = {
username: "YOUR_mqtt_uname",
password: ""
};
var http_req = require('/usr/local/lib/node_modules/request');
http_req.post(
'http://api.noduino.org/user/token',
{ json: {user_id: opt.username, app_id:"mj2030064278", app_key:"0077d4829f52b1b2d668f8a82c5f5ded"} },
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
opt.password = body.user_token;
var MQTTClient = require('MQTTClient').Client;
var client = new MQTTClient('mqtt.noduino.org', 1883, opt);
client.connect(function () {
console.log("connect ok!");
var pubopt = {
qos_level: 2
};
var state = {
on: 1 <---- on
};
var data = '{"m":"set", "d":{' + '"s":' + state.on + '}}';
client.publish('app2dev/YOUR_DEVICE_ID', data, pubopt, function (message_id) {
console.log("public ok! message_id = " + message_id);
process.exit(0);
});
});
} else {
console.log("Request the user token failed");
process.exit(1);
}
}
);
$ ./light-on.js
[编辑] 3.1.3 Setup Color
Change the color of the OpenLight:
$ cat light-color.js
#! /usr/bin/env node
var opt = {
username: "YOUR_mqtt_uname",
password: ""
};
var http_req = require('/usr/local/lib/node_modules/request');
http_req.post(
'http://api.noduino.org/user/token',
{ json: {user_id: opt.username, app_id:"mj2030064278", app_key:"0077d4829f52b1b2d668f8a82c5f5ded"} },
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
opt.password = body.user_token;
var MQTTClient = require('MQTTClient').Client;
var client = new MQTTClient('mqtt.noduino.org', 1883, opt);
client.connect(function () {
console.log("connect ok!");
var pubopt = {
qos_level: 2
};
var state = {
red: 0,
green: 0,
blue: 255, <--------- outputting full power of the blue channel
white: 0,
on: 1
};
data = '{"m":"set", "d":{' + '"r":' + state.red + ',"g":' + state.green
+ ',"b":' + state.blue + ',"w":' + state.white
+ ',"s":' + state.on + '}}';
client.publish('app2dev/YOUR_DEVICE_ID', data, pubopt, function (message_id) {
console.log("public ok! message_id = " + message_id);
process.exit(0);
});
});
} else {
console.log("Request the user token failed");
process.exit(1);
}
}
);
$ ./light-color.js
[编辑] 3.1.4 FAQ
If you get the following error:
/usr/local/lib/node_modules/MQTTClient/client.js:56
throw Error('user names are kept to 12 characters or fewer');
^
Error: user names are kept to 12 characters or fewer
Please patch the /usr/local/lib/node_modules/MQTTClient/client.js to remove the line of checking the length of username and password:
--- a/client.js
+++ b/client.js
@@ -52,10 +52,10 @@ var Client = exports.Client = function (host, port, options) {
options.alive_timer = 30;
options.ping_timer = parseInt(options.alive_timer * 0.6 * 1000);
// 用户名和密码
- if (typeof options.username == 'string' && options.username.length > 12)
- throw Error('user names are kept to 12 characters or fewer');
- if (typeof options.password == 'string' && options.password.length > 12)
- throw Error('passwords are kept to 12 characters or fewer');
+ //if (typeof options.username == 'string' && options.username.length > 12)
+ // throw Error('user names are kept to 12 characters or fewer');
+ //if (typeof options.password == 'string' && options.password.length > 12)
+ // throw Error('passwords are kept to 12 characters or fewer');
// Will flag
if (options.will_flag && (typeof options.will_topic != 'string' || typeof options.will_message != 'string'))
throw Error('missing will_topic or will_message when will_flag is set');
[编辑] 3.2 HTML5
The device control page in WeChat is a H5 page. Using a MQTT client implement in javascript , using the mqttws31.js library:
var client_id = parseInt(Math.random() * 10000, 10) + '_' + mqtt_uname;
var client = new Paho.MQTT.Client(mqtt_server, mqtt_port, "/mqtt", client_id);
function failConnect(e) {
console.log("connect failed");
console.log(e);
console.log("reconnecting ...");
client.connect({userName: mqtt_uname, password: mqtt_pass, onSuccess:onConnect, onFailure: failConnect, mqttVersion:3});
}
function onConnect() {
console.log("onConnect OK!");
subscribe('dev2app/' + devid);
}
function subscribe(topic) {
client.subscribe(topic);
}
function onMessageArrived (message) {
console.log("Arrived Message: [", message.payloadString, "]");
try {
job = JSON.parse(message.payloadString);
set = job.d;
} catch(e) {
console.log("JSON object error!");
alert("JSON error, RX data is: " + message.payloadString);
return;
}
if(job.m == 'set' || job.m == 'status') {
//console.log("set ui state");
set_ui_state(set);
}
if(job.m == 'offline') {
blockUI();
}
}
function onDisConnect() {
console.log("reconnecting ...");
client.connect({userName: mqtt_uname, password: mqtt_pass, onSuccess:onConnect, onFailure: failConnect, mqttVersion:3});
}
function mqtt_publish(msg){
var topic = 'app2dev/' + devid;
message = new Paho.MQTT.Message(msg);
message.destinationName = topic;
client.send(message);
console.log("publish message: " + msg);
}
function mqtt_init() {
client.connect({userName: mqtt_uname, password: mqtt_pass, onSuccess:onConnect, onFailure: failConnect, mqttVersion:3});
client.onMessageArrived = onMessageArrived;
client.onConnectionLost = onDisConnect;
}
mqtt_init();
[编辑] 4 极客定制
[编辑] 4.1 编译固件
获取 noduino-sdk:
$ git clone --recursive git://github.com/icamgo/noduino-sdk.git noduino-sdk
生成 toolchain (you need Python 2.7):
$ cd noduino-sdk/toolchain $ ./gen.py
编译:
$ cd ../sketch/open-light $ make
[编辑] 4.2 烧写固件
[编辑] 4.2.1 Serial
Prepare a USB2UART board, something like FT232RL or CP2102/CP2104:
Upload firmware throught serial for OpenLight Bulb:
Upload firmware throught serial for OpenLight Controller:
- USB2UART_GND ------> SmartNode_GPIO0 / Bulb_GPIO0
- USB2UAR_GND -----> SmartNode_GND / Bulb_GND
- USB2UAR_RXD -----> SmartNode_TX / Bulb_TX
- USB2UAR_TXD -----> SmartNode_RX / Bulb_TX
Connect USB2UAR_VCC3.3 -----> SmartNode_VCC / Bulb_3V3 at last
ESP8285 will be enter upload mode, we can upload the compiled firmware through serial using following commands in Linux:
$ cd /path/to/noduino-sdk/sketch/open-light $ make produce ESPPORT=/dev/ttyUSB1
In windows:
$ make produce ESPPORT=COM7
COM7 is your USB2UART device
In MAC OS, maybe it's:
$ make produce ESPPORT=/dev/cu.SLAB_USBtoUART
/dev/cu.SLAB_USBtoUART is your USB2UART device
[编辑] 4.2.2 Online
- Login
- Username: noduino
- password: noduino1234
Click the "Add files", select the user1.bin and user2.bin located in /path/to/noduino-sdk/sketch/open-light/build/
Then click "Start upload" to upload the user1.bin and user2.bin into the server temporaily
[编辑] 5 硬件原理
[编辑] 5.1 LED 灯珠
OpenLight 铝基板上,LED 灯珠默认布局为:
- Red LED 6 颗串联,正极接 12V,负极接控制板 R (MY9291 之 OUTA)
- Green LED 4 颗串联,正极接 12V,负极接控制板 G (MY9291 之 OUTB)
- Blue LED 4 颗串联,正极接 12V,负极接控制板 B (MY9291 之 OUTC)
- White LED x8 (4 颗串联为一组, 2 组并联,正极接 12V,负极接控制板 W (MY9291 之 OUTC))
LED 灯珠 (5730) 单颗特性为:
- 尺寸 5.7 x 3.0 mm
- 最大电流 150mA (0.5W)
- VF 为 3.0 - 3.4V (Red LED为 2.0 - 2.2V)
- 亮度 50 - 55 lm
LED 灯珠其实就是一个二极管,只要有一个正向导通电压 (VF) 就能发光,一般为 2 - 3.5V,低于此电压灯珠不能发光,高于此电压,灯珠会烧坏。
控制灯珠亮度的,是电流大小,因此调光灯实际调得是电流的大小。电流超过额定电流,会加速灯珠老化,缩短灯珠寿命
[编辑] 5.2 MY9291
OpenLight 采用台湾明阳 4 通道恒流 LED 驱动芯片,控制 R, G, B, W 四路 LED 灯珠
- 特性:
- 3.3 - 5V 电源电压范围(±10%)
- 每个通道 5 - 350 mA 恒流输出范围
- 可承受最大输出电压 24V,支持多颗 LED 串联
- 外接器件少,仅需四个外接电组来设定四組恆流电流
- 框图:
电源为恒压源,可以多片级联,MCU 的控制线就两个:DI 和 DCK
- 电源电压与灯珠串并联确定:
- 12V 电源的情形,如选用 VF 为 3V 左右的 LED 灯珠,则需要 4 颗串联,这样每颗灯珠分到电压为 3V 左右;2V 左右的灯珠,则需要 6 颗串联
- 24V 电源,则 3V 灯珠 8 颗串联,2V 灯珠 12 颗串联
- 6V 电源,则 3V 灯珠 2 颗串联,2V 灯珠 3 颗串联
- 输出限流
MY9291 单路最大输出 350mA,为节约灯珠寿命,可限制通过灯珠的最大电流以节约灯珠寿命
最大输出电流限制:
R = 380mV / Iout
满输出 350mA,则每路的限流电阻都得选为:1R,1/4 W 够用
OpenLight 球泡灯,R/G/B 选用电阻 4R7,限流为 81mA 左右,W 用两个 4R7 并联 2.35R 左右,限流为 162mA 左右。这样基本限制经过每颗 5730 (0.5W) 灯珠的电流为 80mA 左右,以延迟灯珠老化。这样整体功率被限制在 5W,如要增加亮度,可将这 5 个 4R7 电阻替换为 3R0,可将输出功率增加到 7W
其他可选择的:
- MY9231 3 通道恒流 LED 驱动芯片
- MY9221 12 通道恒流 LED 驱动芯片
[编辑] 6 电源
[编辑] 6.1 12V
220V 转 12V 恒压电源模块,额定 12W,1A 电流输出
[编辑] 6.2 3.3V
控制板上的 ESP8266/ESP8285 芯片、MY9291/MY9231 芯片、SPI Flash 芯片皆为 3.3V 供电
[编辑] 6.2.1 MP1470
宽电压供电的
- Wide 4.7V to 16V Operating Input Range
- Fixed 500kHz Switching Frequency
- Over-Current Protection and Hiccup
- Thermal Shutdown
- Output Adjustable from 0.8V
- Available in a 6-pin TSOT-23 package
[编辑] 6.2.2 MP2359
- Wide 4.5V to 24V Operating Input Range
- 1.2A Peak Output Current
- 0.35Ω Internal Power MOSFET Switch
- Stable with Low ESR Output Ceramic Capacitors
- Up to 92% Efficiency
- 0.1μA Shutdown Mode
- Fixed 1.4MHz Frequency
- Thermal Shutdown
- Cycle-by-Cycle Over Current Protection
- Output Adjustable from 0.81V to 15V
[编辑] 7 参考
- 更多信息访问:



