尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

USB3161A_激光编码器同步采样方案

USB3161A_激光编码器同步采样方案 USB3161A — 6路激光 编码器同步采样方案场景描述6路激光传感器输出模拟电压0~5V 或 0~10V接 USB3161A 的 AI 通道ai0~ai5电压→高度转换1路编码器A/B/Z 相脉冲接 USB3161A 的计数器ctr0测距离目标每次采样时6路高度值与编码器距离值一一对应整体架构┌─────────────────────────────────────────────────────────────┐ │ USB3161A (Dev1) │ │ │ │ AI 通道 (电压测量) CI 通道 (计数器) │ │ ┌───────────────────┐ ┌───────────────────┐ │ │ │ ai0 ← 激光1 │ │ ctr0 ← 编码器A/B/Z │ │ │ │ ai1 ← 激光2 │ └───────────────────┘ │ │ │ ai2 ← 激光3 │ │ │ │ │ ai3 ← 激光4 │ │ │ │ │ ai4 ← 激光5 │ │ │ │ │ ai5 ← 激光6 │ │ │ │ └───────────────────┘ │ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ 板载采样时钟 (1 kHz) ←── 共享时钟源 │ │ │ └──────────────────────────────────────────────────┘ │ │ │ │ │ │ ▼ ▼ │ │ AI 任务 CI 任务 │ │ (ConfigureSampleClock) (ConfigureSampleClock │ │ 引用AI时钟) │ │ │ │ │ │ └──────────┬─────────────────────┘ │ │ ▼ │ │ 同步读取 (同索引对齐) │ │ aiData[ch0..5, i] ←→ ciData[i] │ └─────────────────────────────────────────────────────────────┘关键设计两个任务共享采样时钟任务通道时钟源说明AI 任务ai0~ai5板载时钟“”作为主时钟CI 任务ctr0/Dev1/ai/SampleClock引用 AI 任务的采样时钟作为外部时钟启动顺序先启动 CI从再启动 AI主。这样 AI 任务的时钟一开始CI 任务也同时触发保证采样对齐。C# 代码示例usingArtDAQ;usingArtDAQ.CI;usingArtDAQ.AI;publicclassLaserEncoderSync{privateTask_aiTask;privateTask_ciTask;privateAnalogMultiChannelReader_aiReader;privateCounterReader_ciReader;privateconststringDeviceNameDev1;privateconstintNumLaserChannels6;privateconstdoubleSampleRate1000.0;// 采样率 1 kHzprivateconstintSamplesPerRead1000;// 每次读 1000 个样本publicvoidStart(){// 1. AI 任务6路激光电压测量 _aiTasknewTask(LaserAITask);// 创建 6 个 AI 电压通道// 函数原型CreateAIVoltageChan(physicalChannel, nameToAssign, terminalConfig, minVal, maxVal, units, customScale)// 注意ArtDAQ 中具体函数名请查 ArtDAQ.chm常见为 CreateAIVoltageChan 或 CreateAINaiveChanfor(inti0;iNumLaserChannels;i){_aiTask.AIChannels.CreateAIVoltageChan(${DeviceName}/ai{i},$Laser{i},AITerminalConfiguration.Differential,// 差分模式推荐0.0,// 最小值10.0,// 最大值按激光传感器实际输出改AIVoltageUnitsID.Volts,// 单位伏特// 无自定义标尺);}// AI 配置采样时钟板载时钟1 kHz连续采样_aiTask.Timing.ConfigureSampleClock(,// 空字符串 板载时钟SampleRate,// 1 kHzSampleClockActiveEdge.Rising,// 上升沿采样SampleQuantityMode.ContinuousSamples,// 连续模式SamplesPerRead// 缓冲区);// 2. CI 任务编码器距离测量 _ciTasknewTask(EncoderCITask);// 创建 CI 线性编码器通道// 函数原型来自 ArtDAQ.chm 图9// CreateCILinEncoderChan(counter, nameToAssign, decodingType,// ZidxEnable, ZidxVal, ZidxPhase, unit, distPerPulse,// initialPos, customScaleName)_ciTask.CIChannels.CreateCILinEncoderChan(${DeviceName}/ctr0,// 计数器 0Encoder,// 通道名ArtDAQ_Val_X4,// X4 解码四倍频精度最高false,// ZidxEnable不启用 Z 相归零调试阶段先关0.0,// ZidxValZ 相触发时的值ArtDAQ_Val_AHighBHigh,// ZidxPhaseZ 索引相位ArtDAQ_Val_Meters,// unit米距离测量0.0001,// distPerPulse每个脉冲对应的距离米// 例如编码器 1 米 10000 脉冲 → 0.00010.0,// initialPos初始位置// 无自定义标尺);// CI 配置采样时钟引用 AI 任务的采样时钟作为外部时钟源// ★★★ 关键这是同步采样的核心 ★★★_ciTask.Timing.ConfigureSampleClock($/{DeviceName}/ai/SampleClock,// AI 任务的采样时钟作为 CI 时钟源SampleRate,// 同样 1 kHzSampleClockActiveEdge.Rising,SampleQuantityMode.ContinuousSamples,SamplesPerRead);// 3. 创建读取器 _aiReadernewAnalogMultiChannelReader(_aiTask.Stream);_ciReadernewCounterReader(_ciTask.Stream);// 4. 启动顺序先 CI 后 AI // CI 任务先启动等待 AI 时钟AI 任务启动后开始产生时钟两者同步_ciTask.Control(TaskAction.Verify);_ciTask.Control(TaskAction.Commit);_ciTask.Start();_aiTask.Control(TaskAction.Verify);_aiTask.Control(TaskAction.Commit);_aiTask.Start();}publicvoidReadLoop(){while(running){// 同步读取同一时刻的 AI 和 CI 数据double[,]aiData_aiReader.ReadMultiSample(SamplesPerRead);// aiData 维度[NumLaserChannels, SamplesPerRead] [6, 1000]double[]ciData_ciReader.ReadMultiSampleDouble(SamplesPerRead);// ciData 维度[SamplesPerRead] [1000]// 数据对应处理 // aiData[ch, i] 和 ciData[i] 是同一时刻采样for(inti0;iSamplesPerRead;i){// 1. 提取 6 路电压double[]voltagesnewdouble[NumLaserChannels];for(intch0;chNumLaserChannels;ch){voltages[ch]aiData[ch,i];}// 2. 电压 → 高度转换按激光传感器标定double[]heightsConvertVoltagesToHeights(voltages);// 3. 获取对应的编码器距离doubledistanceciData[i];// 4. 此时 heights[0..5] 与 distance 是同一时刻的数据// 可以保存到文件、绘图、计算等SaveData(heights,distance);}}}/// summary/// 电压 → 高度转换/// 按激光传感器实际标定公式改/// 例如量程 0~10V 对应 0~1000mm则 height_mm voltage * 100/// /summaryprivatedouble[]ConvertVoltagesToHeights(double[]voltages){double[]heightsnewdouble[voltages.Length];for(inti0;ivoltages.Length;i){// ★ 按实际传感器标定改 ★// 示例0~10V → 0~1000mmheights[i]voltages[i]*100.0;}returnheights;}publicvoidStop(){_aiTask.Stop();_ciTask.Stop();_aiTask.Dispose();_ciTask.Dispose();}}函数对应关系总表功能ArtDAQ 函数参数说明AI 电压通道CreateAIVoltageChan物理通道、终端配置、量程、单位CI 线性编码器CreateCILinEncoderChan计数器、解码类型、Z相、单位、每脉冲距离时钟配置ConfigureSampleClock时钟源、采样率、采样模式、缓冲区任务控制Control(TaskAction.Verify/Commit)验证、提交、启动AI 读取AnalogMultiChannelReader.ReadMultiSample返回 [通道数, 样本数]CI 读取CounterReader.ReadMultiSampleDouble返回 [样本数]CI 编码器参数说明对应 ArtDAQ.chm 图8/9参数说明推荐值decodingType解码类型ArtDAQ_Val_X4四倍频精度最高ZidxEnable是否启用 Z 相归零调试阶段先false需要每圈归零时trueZidxValZ 相触发时的计数值0.0ZidxPhaseZ 相索引相位ArtDAQ_Val_AHighBHighunit测量单位ArtDAQ_Val_Meters米distPerPulse每脉冲对应距离按编码器实际值改见下方计算initialPos初始位置0.0distPerPulse 计算方法线性编码器光栅尺/磁栅尺distPerPulse 编码器分辨率 (米/脉冲)例如光栅尺分辨率 0.1μm/脉冲 0.0000001 m/脉冲旋转编码器 滚珠丝杠distPerPulse 丝杠导程 / (编码器每转脉冲数 × 解码倍数)例如丝杠导程 5mm编码器 1000 脉冲/转X4 解码distPerPulse 0.005 / (1000 × 4) 0.00000125 米/脉冲常见问题1. -200284 错误CI 任务读取超时检查 CI 任务的时钟源是否配置为/Dev1/ai/SampleClock确认 AI 任务已启动否则没有时钟信号确认编码器有信号输入2. CI 数据和 AI 数据不同步确保启动顺序先 CI 后 AI确保两个任务的采样率一致确保两个任务的 SamplesPerRead 一致3. 编码器数据为负检查initialPos 0.0如果方向反了交换 A/B 相接线检查distPerPulse是否为正值4. CHM 文件查看ArtDAQ.chm 中函数签名请直接打开查看CreateCILinEncoderChan- 线性编码器通道CreateCIAngEncoderChan- 角度编码器通道CreateAIVoltageChan- AI 电压通道ConfigureSampleClock- 采样时钟配置
返回列表