# CANopen主站快速开始 ## 5分钟快速上手 ### 步骤1: 准备硬件 1. 连接创芯科技CAN卡到电脑 2. 安装CAN卡驱动程序 3. 连接CAN总线(确保终端电阻正确) 4. 连接至少一个CANopen从站设备 ### 步骤2: 编译项目 ```bash # 在Visual Studio中打开CanTest项目 # 或者使用命令行编译 msbuild CanTest.csproj ``` ### 步骤3: 运行示例程序 ```csharp // 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. 按任意键退出 ## 最小化示例 如果只想测试基本功能,可以使用简化版本: ```csharp 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模块 ```csharp // 监控数字输入 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: 控制伺服驱动器 ```csharp // 读取位置 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: 多节点数据采集 ```csharp // 存储所有节点的数据 Dictionary> nodeData = new Dictionary>(); master.OnTpdoReceived += (nodeId, data) => { if (!nodeData.ContainsKey(nodeId)) nodeData[nodeId] = new List(); 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. 启用详细日志 ```csharp master.OnLogMessage += msg => Console.WriteLine(msg); ``` ### 2. 监控节点状态 ```csharp 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使用频率 ```csharp // ❌ 不好 - 频繁SDO读写 while (true) { master.SdoReadAndWait(1, 0x6000, 0x01); Thread.Sleep(10); } // ✅ 好 - 使用PDO master.EnableSync(10); // PDO自动传输 ``` ### 2. 批量处理事件 ```csharp master.OnTpdoReceived += (nodeId, data) => { // 将数据放入队列,后台线程处理 dataQueue.Enqueue(new { NodeId = nodeId, Data = data }); }; ``` ### 3. 合理设置SYNC周期 ```csharp // 根据应用需求选择 master.EnableSync(1); // 高速控制(1ms) master.EnableSync(10); // 一般应用(10ms) master.EnableSync(100); // 慢速监控(100ms) ``` ## 下一步 - 阅读 [CANopen主站使用指南.md](./CANopen主站使用指南.md) 了解详细API - 查看 [README_CANopen_Master.md](./README_CANopen_Master.md) 了解架构设计 - 参考 `Program.cs` 中的完整示例 - 尝试修改示例代码适应你的应用 --- **祝你使用愉快!** 🚀