19 极物科技 | DALI协议栈 - 标准命令集解析

极物科技 | DALI协议栈 - 标准命令集解析

前言

在智能控制领域,"协议壁垒"与"系统稳定性"始终是绕不开的难题。极物科技(Zeewo)以 "重构空间交互体验" 为使命,通过自研的 极物 OS,实现了 KNX、DALI、CAN、RS485 等多种总线协议在单一主机上的深度融合。

我们认为,一个真正优秀的智能系统,不仅要实现灯光、遮阳、温控、音乐、安防等全生态设备的无界融合 ,更要确保本地运行、断网可用 ,并具备WEB 远程调试OTA 固件升级的能力。基于此底层架构,我们推出了诸如带双路 DALI 的 KNX 主机、HomeKit 网桥等核心硬件,并将极物 OS 成功接入了 Apple HomeKit、小度、纯血鸿蒙及 HomeAssistant 等主流生态系统。

一句话概述:本文深入解析极物 DALI 协议栈 0-31 标准命令集的完整实现逻辑。

本文聚焦于 DALI 基础控制命令与场景调用命令,涵盖 OFF/UP/DOWN/STEP、RECALL MAX/MIN、GO TO SCENE 等核心命令的处理流程、渐变引擎触发、状态机更新等关键机制。


1. 命令分类总览

1.1 基础控制命令 (0-10)

命令值 命令名称 功能说明
0 OFF 关灯(无渐变)
1 UP 向上调光 200ms
2 DOWN 向下调光 200ms
3 STEP_UP 亮度 +1(无渐变)
4 STEP_DOWN 亮度 -1(无渐变)
5 RECALL_MAX_LEVEL 调至最大亮度
6 RECALL_MIN_LEVEL 调至最小亮度
7 STEP_DOWN_AND_OFF 亮度 -1,到最小则关
8 ON_AND_STEP_UP 开灯并 +1
9 ENABLE_DAPC_SEQUENCE 启用 DAPC 序列
10 GO_TO_LAST_ACTIVE_LEVEL 恢复上次亮度

1.2 场景调用命令 (16-31)

命令值 命令名称 功能说明
16~31 GO_TO_SCENE 0~15 调用场景 0~15

2. 命令处理入口

c 复制代码
uint16_t dali_cmd_process_normal(dali_slave_service_info_t *slave_info, uint8_t repeat_flag) {
    if (slave_info->rec_data >= REFERENCE_SYSTEM_POWER) {
        // 扩展应用命令 (224-255)
        return dali_cmd_process_extended_application(slave_info, repeat_flag);
    } else {
        // 标准命令 (0-223)
        return dali_cmd_process_common(slave_info, repeat_flag);
    }
}

3. 基础控制命令详解

3.1 OFF 命令 (0)

功能:立即关灯,无渐变过程。

c 复制代码
case OFF:
    dali_cmd_direct_arc_power_control(0);
    break;

执行流程

c 复制代码
void dali_cmd_direct_arc_power_control(uint8_t level) {
    device_enabled = false;
    write_memory_enabled = false;
    
    if (level == 0) {
        if (dali.s.level == dali_ram.variable.minimum_level) {
            // 从最小亮度关到 OFF
            fade_direction = FADE_BETWEEN_MINLEVEL_AND_OFF;
        } else {
            // 渐变到最小亮度后关闭
            fade_direction = FADE_TIME_DOWN_OFF;
            level_change = (dali.s.level - dali_ram.variable.minimum_level);
        }
    }
    
    dali_ram.variable.target_level = 0;
    
    // 计算渐变步进
    fade_step = flash_inv_fadetime_val[fade_time] * level_change;
    fade_step = fade_step >> 1;
    
    status_information &= ~LAMP_ON;  // 清除开灯标志
}

3.2 UP 命令 (1)

功能:以设定的渐变速度向上调光 200ms。

c 复制代码
case UP:
    status_information |= LAMP_ON;
    status_information &= ~LAMP_FAILURE;
    
    if (status_information & LAMP_ON) {
        if (dali.s.level < dali_ram.variable.maximum_level) {
            fade_direction = FADE_RATE_UP;
            current_fade_time = W200MS;
            current_fade = dali_ram.variable.fade_rate;
            fade_step = flash_fade_rate_val[current_fade];
            fade_step = fade_step << 7;  // 左移 7 bit
            need_fade = true;
            status_information |= FADE_RUNNING;
        } else {
            status_information |= LIMIT_ERROR;
            fade_direction = FADE_STOP;
        }
    } else {
        fade_direction = FADE_STOP;  // 灯灭时不执行
    }
    light_flag = true;
    break;

关键点

  • 使用 fade_rate 而非 fade_time
  • 固定 200ms 调光时长
  • 灯灭状态下无效

3.3 DOWN 命令 (2)

功能:以设定的渐变速度向下调光 200ms。

c 复制代码
case DOWN:
    if (status_information & LAMP_ON) {
        if (dali.s.level > dali_ram.variable.minimum_level) {
            fade_direction = FADE_RATE_DOWN;
            current_fade_time = W200MS;
            current_fade = dali_ram.variable.fade_rate;
            fade_step = flash_fade_rate_val[current_fade];
            fade_step = fade_step << 7;
            need_fade = true;
            status_information |= FADE_RUNNING;
        } else {
            status_information |= LIMIT_ERROR;
            fade_direction = FADE_STOP;
        }
    } else {
        fade_direction = FADE_STOP;
    }
    light_flag = true;
    break;

3.4 STEP_UP 命令 (3)

功能:亮度立即 +1,无渐变。

c 复制代码
case STEP_UP:
    if (status_information & LAMP_ON) {
        if (dali.s.level < dali_ram.variable.maximum_level) {
            dali.s.level = dali.s.level + 1;
            dali_ram.variable.target_level = dali.s.level;
            status_information &= ~LIMIT_ERROR;
        } else {
            status_information |= LIMIT_ERROR;
        }
        fade_direction = FADE_DIRECT;
    }
    light_flag = true;
    break;

3.5 STEP_DOWN 命令 (4)

功能:亮度立即 -1,无渐变。

c 复制代码
case STEP_DOWN:
    if (status_information & LAMP_ON) {
        if (dali.s.level > dali_ram.variable.minimum_level) {
            dali.s.level = dali.s.level - 1;
            dali_ram.variable.target_level = dali.s.level;
            status_information &= ~LIMIT_ERROR;
        } else {
            status_information |= LIMIT_ERROR;
        }
        fade_direction = FADE_DIRECT;
    }
    light_flag = true;
    break;

3.6 RECALL_MAX_LEVEL 命令 (5)

功能:调至最大亮度(可触发识别模式)。

c 复制代码
case RECALL_MAX_LEVEL:
    dali_cmd_direct_arc_power_control(dali_ram.variable.maximum_level);
    light_flag = true;
    break;

识别模式处理(代码中被注释):

c 复制代码
// 原始逻辑:
if (w15min_waiting_time > 0) {
    // 处于初始化窗口,进入识别模式
    fade_direction = FADE_DIRECT_IDENTIFICATION;
    recall_level_flag = MAX_LEVEL_FLAG;
} else {
    fade_direction = FADE_DIRECT;
}

3.7 RECALL_MIN_LEVEL 命令 (6)

功能:调至最小亮度。

c 复制代码
case RECALL_MIN_LEVEL:
    dali_cmd_direct_arc_power_control(dali_ram.variable.minimum_level);
    light_flag = true;
    break;

3.8 STEP_DOWN_AND_OFF 命令 (7)

功能:亮度 -1,如果已在最小亮度则关灯。

c 复制代码
case STEP_DOWN_AND_OFF:
    if (dali.s.level <= dali_ram.variable.minimum_level) {
        dali_ram.variable.target_level = 0;
        dali.long_level = 0;
    } else {
        dali.s.level = dali.s.level - 1;
        dali_ram.variable.target_level = dali.s.level;
    }
    status_information &= ~LIMIT_ERROR;
    fade_direction = FADE_DIRECT;
    light_flag = true;
    break;

3.9 ON_AND_STEP_UP 命令 (8)

功能:如果灯灭则开至最小亮度,否则亮度 +1。

c 复制代码
case ON_AND_STEP_UP:
    if (dali.s.level == 0) {
        dali.s.level = dali_ram.variable.minimum_level;
        dali_ram.variable.target_level = dali.s.level;
        status_information &= ~LIMIT_ERROR;
    } else if (dali.s.level < dali_ram.variable.maximum_level) {
        dali.s.level = dali.s.level + 1;
        dali_ram.variable.target_level = dali.s.level;
        status_information &= ~LIMIT_ERROR;
    } else {
        status_information |= LIMIT_ERROR;
    }
    fade_direction = FADE_DIRECT;
    light_flag = true;
    break;

3.10 ENABLE_DAPC_SEQUENCE 命令 (9)

功能:标记 DAPC 序列开始,后续调光使用快速渐变。

c 复制代码
case ENABLE_DAPC_SEQUENCE:
    dapc_sequence = true;
    dapc_sequence_time = W200MS;
    break;

DAPC 序列中的调光

c 复制代码
if (dapc_sequence == true) {
    if (dali.s.level == 0) {
        // 当前为 0,直接设置目标值
        dali.s.level = level;
        fade_direction = FADE_DIRECT;
    } else {
        // 使用 fade_rate = 1(最快速度)
        current_fade = 1;
        dapc_sequence_time = W200MS;
    }
}

3.11 GO_TO_LAST_ACTIVE_LEVEL 命令 (10)

功能:恢复到上次非 OFF 状态的亮度。

c 复制代码
case GO_TO_LAST_ACTIVE_LEVEL:
    if (dali.s.level != last_active_level) {
        dali_cmd_direct_arc_power_control(last_active_level);
    }
    light_flag = true;
    break;

last_active_level 更新时机

c 复制代码
// 在 dali_cmd_direct_arc_power_control 中
if (level != 0) {
    last_active_level = level;  // 记录非零亮度值
}

4. 场景调用命令 (16-31)

4.1 场景调用逻辑

c 复制代码
case GO_TO_SCENE0:
case GO_TO_SCENE1:
// ... 到 GO_TO_SCENE15
    temp = dali_ram.variable.scene[slave_info->rec_data & 0x0F];
    
    // 场景值不为 MASK 才执行
    if (temp != POWER_MASK) {
        power_on_flag = false;
        dali_cmd_direct_arc_power_control(temp);
        
        // 同时设置色温
        temp = dali_ram.variable.tc_scene[slave_info->rec_data & 0x0F];
        if (temp != POWER_MASK) {
            dali_cmd_direct_arc_tc_control(temp);
        }
    }
    
    status_information &= ~POWER_CYCLE_SEEN;
    break;

4.2 场景值说明

场景值 含义
0~254 有效亮度/色温值
255 (MASK) 该场景未配置,不改变当前状态

4.3 场景调用示例

复制代码
场景 3 配置:
  scene[3] = 180        // 亮度 180
  tc_scene[3] = 200     // 色温 200

调用场景 3:
  → dali_cmd_direct_arc_power_control(180)
  → dali_cmd_direct_arc_tc_control(200)
  → 亮度渐变到 180,色温渐变到 200

5. 渐变方向枚举

c 复制代码
enum {
    FADE_IDLE,                    // 空闲
    FADE_STOP,                    // 停止渐变
    FADE_TIME_UP,                 // 按时间向上渐变
    FADE_TIME_DOWN,               // 按时间向下渐变
    FADE_TIME_DOWN_OFF,           // 渐变到最小后关闭
    FADE_RATE_UP,                 // 按速度向上渐变
    FADE_RATE_DOWN,               // 按速度向下渐变
    FADE_DIRECT,                  // 直接设置(无渐变)
    FADE_DIRECT_IDENTIFICATION,   // 直接设置 + 识别模式
    FADE_PENDING,                 // 等待执行
    FADE_BETWEEN_MINLEVEL_AND_OFF // 最小亮度与 OFF 之间渐变
};

6. 渐变参数表

6.1 渐变时间表 (fade_time)

c 复制代码
// fade_time 对应实际时间
uint16_t tc_fade_time[] = {
    0, 700, 1000, 1400, 2000, 2800, 4000, 5700, 
    8000, 11300, 16000, 22600, 32000, 45300, 64000, 90500
};
fade_time 实际时间
0 0s (直接)
1 0.7s
2 1.0s
3 1.4s
4 2.0s
5 2.8s
6 4.0s
7 5.7s
8 8.0s
9 11.3s
10 16.0s
11 22.6s
12 32.0s
13 45.3s
14 64.0s
15 90.5s

6.2 渐变速度表 (fade_rate)

c 复制代码
uint16_t const flash_fade_rate_val[] = {
    0x0000, 0xB731, 0x8189, 0x5B99, 0x40C5, 
    0x2DCC, 0x2062, 0x16E6, 0x1031, 0x0B73,
    0x0819, 0x05BA, 0x040C, 0x02DD, 0x0206, 0x016E
};

fade_rate 值越大,渐变速度越慢。

6.3 渐变时间倒数表

c 复制代码
uint32_t const flash_inv_fadetime_val[] = {
    0x0000, 0xB964, 0x8312, 0x5CB2, 0x4189, 
    0x2E59, 0x20C5, 0x172B, 0x1062, 0x0B96,
    0x0831, 0x05CB, 0x0419, 0x02E5, 0x020C, 0x0173
};

用于计算 fade_step

c 复制代码
fade_step = flash_inv_fadetime_val[fade_time];
fade_step = fade_step * level_change;
fade_step = fade_step >> 1;

7. 状态标志更新

7.1 light_flag 作用

以下命令执行后会设置 light_flag = true

  • UP, DOWN, STEP_UP, STEP_DOWN
  • RECALL_MAX_LEVEL, RECALL_MIN_LEVEL
  • STEP_DOWN_AND_OFF, ON_AND_STEP_UP
  • GO_TO_LAST_ACTIVE_LEVEL
  • GO_TO_SCENE 0~15

light_flag 触发清理

c 复制代码
if (light_flag == true) {
    status_information &= ~POWER_CYCLE_SEEN;  // 清除上电标志
    dapc_sequence = false;                     // 清除 DAPC 序列
    power_on_flag = false;                     // 清除上电标志
}

7.2 LIMIT_ERROR 标志

当亮度超出范围时设置:

c 复制代码
if (level < dali_ram.variable.minimum_level) {
    level = dali_ram.variable.minimum_level;
    status_information |= LIMIT_ERROR;
} else if (level > dali_ram.variable.maximum_level) {
    level = dali_ram.variable.maximum_level;
    status_information |= LIMIT_ERROR;
}

7.3 FADE_RUNNING 标志

渐变进行中设置:

c 复制代码
if (need_fade) {
    status_information |= FADE_RUNNING;
}

8. 注意事项

  1. DAPC 命令 :S=0 时直接调用 dali_cmd_direct_arc_power_control(),无需重复帧
  2. 场景 MASK:场景值为 255 时不执行任何操作
  3. UP/DOWN 限制:灯灭状态下 UP/DOWN 无效
  4. 渐变速度:fade_rate=0 保留不用,有效范围 1~15
  5. last_active_level:仅在亮度非 0 时更新
  6. LIMIT_ERROR:亮度被限制在 min~max 范围内时设置

9. 相关文档

  • 《极物科技 | DALI协议栈 - 架构总览与模块设计》
  • 《极物科技 | DALI协议栈 - 物理层位编解码详解》
  • 《极物科技 | DALI协议栈 - 帧传输状态机与地址解析》
  • 《极物科技 | DALI协议栈 - 配置命令详解》
  • 《极物科技 | DALI协议栈 - 查询命令全解》
  • 《极物科技 | DALI调光灯 - 快速接入指南》

关于极物科技(ZEEWO)

极物科技(Zeewo)致力于为用户提供智能控制系统及硬件产品。我们以总线系统为技术底座,以**"稳定、可靠、快速响应"**为产品底线,是国内少有的拥有 KNX、DALI 全套软硬件自主研发能力的厂商之一。

我们的核心能力:

  • 系统架构:自研极物 OS,支持多协议无界融合(KNX/DALI/CAN/RS485/IP)。
  • 核心硬件:带双路 DALI 的 KNX 主机、超薄全金属定制面板、各类智选传感器及网关。
  • 生态互联:深度融入 Apple HomeKit、Matter、小度、HomeAssistant 及纯血鸿蒙生态。
  • 调试交付:独家支持 ETS 导出 XML 直接导入进行 APP 免编程调试,支持远程 WEB 运维。

我们的市场覆盖:

服务网点已覆盖全国核心城市(含长三角、珠三角、成渝等),并以高品质的方案深耕家居生活、酒店民宿、企业办公、疗愈康养、餐馆会所等多个细分领域。

(如果您在开发或落地中遇到技术问题,欢迎通过官网或后台私信与我交流探讨)

相关推荐
阿钱真强道2 小时前
17 极物科技 | DALI协议栈 - 物理层位编解码详解
曼彻斯特编码·极物·极物智能·极物科技·iec 62386·dali协议栈
阿钱真强道1 天前
16 极物科技 | DALI协议栈 - 架构总览与模块设计
智能家居·照明·极物·极物智能·极物科技·iec 62386·dali协议栈
阿钱真强道3 天前
11 极物科技 | DALI调光灯 - 功能接口与调试指南
智能照明·极物·极物智能·极物科技·dali调光灯·调光控制·调试指南
阿钱真强道3 天前
12 极物科技 | DALI调光灯 - 设备发现与地址分配机制
智能照明·极物·极物智能·极物科技·dali调光灯·设备发现·地址分配
阿钱真强道4 天前
09 极物科技 | DALI调光灯 - IEC 62386 底层协议解析
智能照明·总线协议·极物·极物智能·极物科技·dali调光灯·iec 62386
阿钱真强道5 天前
07 极物科技 | DALI调光灯 - 快速接入指南
智能照明·极物·极物智能·极物科技·dali调光灯·iec 62386·调光控制
阿钱真强道5 天前
08 极物科技 | DALI调光灯 - UDP 通讯协议规范
通讯协议·智能照明·极物·极物智能·极物科技·dali调光灯·iec 62386
阿钱真强道8 天前
06 极物科技 | 创明RS485窗帘 - UDP 通讯协议规范
udp·智能家居·通讯协议·极物·极物智能·极物科技·创明窗帘
阿钱真强道9 天前
04 极物科技 | 创明RS485窗帘 - 快速接入指南
智能家居·rs485·极物·极物智能·极物科技·创明窗帘·窗帘控制