快速开始_主站.md 5.6 KB

CANopen主站快速开始

5分钟快速上手

步骤1: 准备硬件

  1. 连接创芯科技CAN卡到电脑
  2. 安装CAN卡驱动程序
  3. 连接CAN总线(确保终端电阻正确)
  4. 连接至少一个CANopen从站设备

步骤2: 编译项目

# 在Visual Studio中打开CanTest项目
# 或者使用命令行编译
msbuild CanTest.csproj

步骤3: 运行示例程序

// Program.cs中的Main方法已经配置为运行主站示例
// 直接运行即可
static void Main(string[] args)
{
    RunCanOpenMaster();  // 已启用
    // RunCanOpenSlave(); // 已注释
}

步骤4: 观察输出

程序会执行以下操作:

  1. 初始化CAN设备(500kbps)
  2. 添加4个节点(ID: 1, 2, 3, 5)
  3. 等待心跳报文
  4. 扫描节点设备信息
  5. 启动所有节点
  6. 启用SYNC同步(10ms周期)
  7. 进入主循环,持续接收PDO数据
  8. 按任意键退出

最小化示例

如果只想测试基本功能,可以使用简化版本:

static void SimpleTest()
{
    using (CanOpenMaster master = new CanOpenMaster(4, 0, 0))
    {
        // 注册事件
        master.OnHeartbeatReceived += (id, status) => 
            Console.WriteLine($"HB from {id}");
        
        // 初始化
        master.Initialize(CanBaudRate.BaudRate_500K);
        
        // 添加节点
        master.AddNode(1);
        
        // 等待
        Thread.Sleep(2000);
        
        // 读取设备类型
        uint type = master.ReadDeviceType(1);
        Console.WriteLine($"Device Type: 0x{type:X8}");
        
        // 启动节点
        master.NmtStartNode(1);
        
        Console.WriteLine("Done!");
    }
}

常见场景

场景1: 监控IO模块

// 监控数字输入
master.OnTpdoReceived += (nodeId, data) =>
{
    if (nodeId == 1 && data.Length >= 2)
    {
        byte di1 = data[0];
        byte di2 = data[1];
        Console.WriteLine($"DI1={di1}, DI2={di2}");
    }
};

// 控制数字输出
master.SdoWriteAndWait(1, 0x6200, 0x01, 0x000000FF);

场景2: 控制伺服驱动器

// 读取位置
var response = master.SdoReadAndWait(3, 0x6064, 0x00);
if (response != null)
{
    int position = BitConverter.ToInt32(response, 4);
    Console.WriteLine($"Position: {position}");
}

// 设置目标位置
master.SdoWriteAndWait(3, 0x607A, 0x00, 10000);

// 启动运动
master.SdoWriteAndWait(3, 0x6040, 0x00, 0x000F);

场景3: 多节点数据采集

// 存储所有节点的数据
Dictionary<byte, List<byte[]>> nodeData = new Dictionary<byte, List<byte[]>>();

master.OnTpdoReceived += (nodeId, data) =>
{
    if (!nodeData.ContainsKey(nodeId))
        nodeData[nodeId] = new List<byte[]>();
    
    nodeData[nodeId].Add(data);
    
    // 每100条数据保存一次
    if (nodeData[nodeId].Count % 100 == 0)
    {
        SaveData(nodeId, nodeData[nodeId]);
    }
};

故障排查

问题1: 初始化失败

症状: Initialize() 返回 false

解决:

  1. 检查CAN卡是否正确连接
  2. 确认驱动已安装
  3. 验证设备类型参数(默认4=USBCAN2)
  4. 检查设备索引和通道索引

问题2: 收不到心跳

症状: 没有心跳事件触发

解决:

  1. 确认从站设备已上电
  2. 检查波特率是否与从站一致
  3. 验证节点ID是否正确
  4. 使用CAN分析仪检查总线上是否有心跳报文
  5. 检查物理连接(线缆、终端电阻)

问题3: SDO读写超时

症状: SdoReadAndWait() 返回 null

解决:

  1. 确认节点处于PreOperational或Operational状态
  2. 检查索引和子索引是否正确
  3. 增加超时时间参数
  4. 查看日志输出了解详细错误
  5. 验证从站是否支持该对象

问题4: PDO无数据

症状: 没有TPDO事件触发

解决:

  1. 确认已发送SYNC帧(如果需要)
  2. 检查从站的PDO配置
  3. 验证COB-ID是否正确
  4. 确认传输类型配置正确
  5. 使用CAN分析仪验证PDO是否在总线上

调试技巧

1. 启用详细日志

master.OnLogMessage += msg => Console.WriteLine(msg);

2. 监控节点状态

while (running)
{
    foreach (var nodeId in master.NodeIds)
    {
        var node = master.GetNode(nodeId);
        Console.WriteLine($"{nodeId}: {node.GetStateString()}, " +
                         $"Online={node.IsOnline()}, " +
                         $"HB={node.HeartbeatCount}");
    }
    Thread.Sleep(1000);
}

3. 使用CAN分析仪

推荐使用CAN分析仪工具:

  • 验证总线上的实际通信
  • 检查帧格式和内容
  • 诊断通信问题
  • 对比预期和实际行为

4. 逐步测试

  1. 先测试单节点
  2. 再添加更多节点
  3. 先测试NMT
  4. 再测试SDO
  5. 最后测试PDO

性能优化

1. 减少SDO使用频率

// ❌ 不好 - 频繁SDO读写
while (true)
{
    master.SdoReadAndWait(1, 0x6000, 0x01);
    Thread.Sleep(10);
}

// ✅ 好 - 使用PDO
master.EnableSync(10); // PDO自动传输

2. 批量处理事件

master.OnTpdoReceived += (nodeId, data) =>
{
    // 将数据放入队列,后台线程处理
    dataQueue.Enqueue(new { NodeId = nodeId, Data = data });
};

3. 合理设置SYNC周期

// 根据应用需求选择
master.EnableSync(1);   // 高速控制(1ms)
master.EnableSync(10);  // 一般应用(10ms)
master.EnableSync(100); // 慢速监控(100ms)

下一步


祝你使用愉快! 🚀