- 第一版玩偶不带电池,需外接5V/4A适配器供电。
- 玩偶控制板要能控制主板的开和关,目前画的控制板从串口取电是错的。关于控制板如何取电,等散热问题有结果后,再确定。
一、概述

{控制板电源来自主板,电压5V,电源和地在4根串口线中。}
控制板和主板的通信串口。4线次序:5V、GND、RXD、TXD(此处RXD、TXD是控制板视角)。用4pin的1.25mm母口。
- 初始上电后(待机状态)。1)LED灯,只控制板的电源LED灯亮,显示红色。2)除电源按钮外,其它按钮按下不会有反应。
- 用户按下“电源”按钮(不论长按还是短按)(工作状态)。1)给主板上电,2)电源LED灯显示绿色。4)开始发串口“读状态信息报”,间隔1秒。对此时的“读状态信息报”,目的是要让主板知道正用的是哪厂家哪型号产品,场景(参数5)、隐私(参数6)按钮都填0。
- 长按按下“电源”按钮。断开主板,电源LED灯显示红色,其它LED灯来掉。即让和初始上电时一样进入待机状态。

主板上电初始化完成后,会发串口协议中“控制LED指示灯”命令,控制“场景”、“隐私”这两个LED是亮还是暗。
对“电源”、亮或灭全由控制板控制。对“场景”、“隐私”,除了关机(长按按下“电源”按钮)时控制板要主动灭掉(此时主板已断电,没法发“控制LED指示灯”),其它时间取决于主板发来的“控制LED指示灯”命令。
1.3 台灯上按钮(3)
- 电源开/关(控制板控制,只长按)。按下它时,发现正在待机,给主板供电等,设备进入工作状态。否则断掉主板等,设备进入待机状态。断电时,要同时熄灭除电源外的其它LED灯。
- 场景(“读状态信息报”告知主板此按钮按下)。按下按钮,切换到下一个场景。详细见“三、场景、隐私按钮”。
- 隐私(“读状态信息报”告知主板此按钮按下)。按下它时,正处于隐私保护,就解除保护。否则进入保护。详细见“三、场景、隐私按钮”。
1.3 LED指示灯(5)
- 3个按钮各一个LED灯。另外两个用于眼睛啥 的。
- “电源”按钮下的LED灯状态由控制板完全控制。
- “控制LED指示灯”控制除电源外的其它LED灯。
- 对LED灯颜色,“电源”有红(待机状态)、绿(工作状态)两色,其它蓝色。
长按的生效时刻是在按着时,短按生效时刻是在松开时。以“场景”为例,按着“场景”按钮,到长按时长了,生效,发场景按钮值是2的”读状态信息报“。松开时刻,如果此次已满足长按,啥也不做,否则认为是短按,发场景按钮值是1的”读状态信息报“。

用户按下场景、隐私按钮时,不管之前是什么状态,控制板点亮对应LED指示灯(让用户看到按钮按下了)。等可以满足短按或长按了,发出“读状态信息报”。主板收到这个“读状态信息报”后,处理此按下事件,结束时会根据当前状态,灭掉或点亮对应LED灯
二、串口协议(Leagor LAMP Control Protocol)
2.1 基本格式
通信参数:8,N,1
波特率: 9600、115200、230400。控制板决定选哪个波特率。
命令帧基本格式
帧头 长度 命令类型 参1 参2 。。。 参n 校验 0x07
长度字节包括命令类型及后面的各参数(参1~参n),但不含长度本身和校验和。
校验字节为包含长度字节、命令类型、各参数(参1~参n)的字节和(模256)。注意,不包含帧字头节(0x07)。对应下面代码,变量i是从1开始。
uint8_t calculate_sum(const uint8_t* data, int len) { uint32_t sum = 0; for (int i = 1; i < len; i ++) { sum += data[i]; } return sum & 0xff; }
以下是一个“控制LED指示灯”命令示例:0x03 0x23 0xff 0x01 --> (校验和)0x26

2.2 读状态信息报(控制板 –>主板)
[0]帧头 | [1]长度 | [2]命令 | [3]参数1 | [4]参数2 | [5]参数3 | [6]参数4 | [7]参数5 | [8]参数6 | [9]参数7 |
0x07 | 0x07 | 0x10 | 产家编码 | 产品编码 | 色温 | 灯亮度 | 场景按钮 | 隐私按钮 | 校验和 |
1 | 1 | 0..4 | 0..100 | 0或1或2 | 0或1或2 | ||||
0x07 | 0x07 | 0x10 | 0x1 | 0x1 | 0x2 | 60 | 0x0 | 0x2 |
示例:设备是纽兰斯顿的A型台灯,当前色温是索引2,查色温数组是4400K。当前亮度是60%。此刻隐私按钮发生了长按,场景按钮则没按下事件。
- 产家编码、产品编码。这套协议可能会用于多种型号产品。产家编码1表示纽兰斯顿,产品编码1表示纽兰斯顿的A型台灯。
- “色温”指示当前灯泡正用的色温。值见下面的“改色温”命令。当正处于渐变时,填写要变到的色温。
- “亮度”指示灯亮着的百分比,值范围0到100。当正处于渐变时,填写要变到的亮度。处于“0亮度状态”时,值填0。
- “xx按钮”指示此刻xx按钮的按下情况。0表示没按下事件,1表示发生短按,2表示发生长按。
上电后,没收到主板的“全局设置”命令前,按1Hz(间隔一秒)发这条状态报告,此时“xx按钮”两参数填0。为什么一开始间隔一秒?那段时间主板还在初始化中,这须要数秒。主板初始化完成,成功收到一条读状态信息报后,便会发“全局设置”命令。
控制板收到的第一条命令,可能不是“全局设置”,但在没收到“全局设置”前,以1Hz发读状态信息报,以及忽略任何按键事件,即这些“读状态信息报”的“xx按钮”两参数填0。
收到第一条“全局设置”命令后,接下不必一秒发送一次“读状态信息报”了,而是在按下场景或隐私按钮时。
场景或隐私按钮发生按下(包括短按和长按)事件后。这时,要满足发生一次长按或短按时,确保只发一个读状态信息报。要做到这个,可遵循长按的生效时刻是在按着时,短按生效时刻是在松开时。以下是一种实现逻辑,假设长按时间阈值是2秒。
- 按下按钮时刻。一次新的按下开始了,但不要发任何的“读状态信息报”。
- 按下时间超过2秒时刻。发一个长按的“读状态信息报”。
- 松开按钮时刻。如果此次按下时,没出现过(2),也就是按下时间没超过2秒,发一个短按的"读状态信息报"。否则,如果出现过(2),不再发“读状态信息报”。
此型号玩偶是外接电源,不传实时电压。
(电池电压的原始数据是浮点型的数据,因为浮点型数据使用串口传输不方便,所以在发送之前先将浮点数放大一千倍(保留小数点后三位),再将放大后的浮点数强制转换成short型数据,最后在发送前将short型数据拆分成两个8位的数据。电压示例。高8位0X58(16进制)=0101 1000(2进制)、低8位0X38(16 进制)=0011 1000(2进制),最高位为0,正数,大小为88*256+56=22584,电压大小为22584mv(毫伏))。
2.3 全局设置(主板 –>控制板)
[0]帧头 | [1]长度 | [2]命令 | [3]长按时长 | [4]校验 |
0x07 | 0x02 | 0x20 | n | 校验和 |
n/10=多少秒 | ||||
0x07 | 0x02 | 0x20 | 25 |
示例:命令控制把长按时长阈值设为2.5秒。
“长按时长”,如果控制板不支持用户可以修改长按时长,忽略这字段。
运行过程中,控制板可能会收到多次“全局设置”。正如上面“读状态信息报”说的,第一个“全局设置”有个附加作用是修改后绪“读状态信息报”的发送时机。第二个起,纯粹是改长按时长了。
2.4 控制LED指示灯(主板 –>控制板)
[0]帧头 | [1]长度 | [2]命令 | [3]参数1 | [4]参数2 | [5]参数3 | [6]参数4 | [7]校验 |
0x07 | 0x05 | 0x23 | 场景灯 | 隐私灯 | 左眼灯 | 右眼灯 | 校验和 |
0/1/0xff | 0/1/0xff | 0/1/0xff | 0/1/0xff | ||||
0x07 | 0x05 | 0x23 | 0xff | 0x1 | 0x0 | 0x0 | 0x26 |
示例:命令控制板点亮隐私灯,但场景灯保持不变。
“xx灯”,0表示灭掉LED。1表示点亮。0xff表示保持当前状态。
此命令不会涉及“电源”指示灯,那灯完全由控制板控制。
三、场景、隐私按钮
场景
台灯工作时,除照明,还会默认执行一个任务。像学生写作业场景,这种任务可能是坐姿检测。做健身操场景,可能是陪伴做操。场景按钮就用于在这些场景中进行切换。
长按场景按钮会让挂起任务。举个例子,学生写作业时,想趴桌上睡觉,坐姿检测会认为这姿势不规范,于是会出声音提示。长按让挂起坐姿检测,等要继续写做业了,再按场景按钮,恢复坐姿检测任务。
当场景被挂起时,会熄灭场景LED。
隐私
一旦进入“隐私保护”状态,会阻止远程桌面,蓝牙IP发现,第三方小程序上传摄像头拍到图像。隐私按钮就用于提供“隐私保护”开关。
不排除将来会让隐私按钮有长按功能,发送“读状态信息报”时,也须要区分短按还是长按。
对隐私LED指示灯,设想是当隐私保护打开时,熄灭。否则亮灯,这时远程桌面这些可自由访问。