/// <summary> /// Write to a node via SDO /// </summary> /// <param name="node">Node ID</param> /// <param name="index">Object Dictionary Index</param> /// <param name="subindex">Object Dictionary sub index</param> /// <param name="udata">byte[] of data (1-8 bytes) to send</param> /// <param name="completedcallback">Call back on finished/error event</param> /// <returns>SDO class that is used to perform the packet handshake, contains error/status codes</returns> public SDO SDOwrite(byte node, UInt16 index, byte subindex, byte[] data, Action <SDO> completedcallback) { SDO sdo = new SDO(this, node, index, subindex, SDO.direction.SDO_WRITE, completedcallback, data); sdo_queue.Enqueue(sdo); return(sdo); }
/// <summary> /// Read from a remote node via SDO /// </summary> /// <param name="node">Node ID to read from</param> /// <param name="index">Object Dictionary Index</param> /// <param name="subindex">Object Dictionary sub index</param> /// <param name="completedcallback">Call back on finished/error event</param> /// <returns>SDO class that is used to perform the packet handshake, contains returned data and error/status codes</returns> public SDO SDOread(byte node, UInt16 index, byte subindex, Action <SDO> completedcallback) { SDO sdo = new SDO(this, node, index, subindex, SDO.direction.SDO_READ, completedcallback, null); sdo_queue.Enqueue(sdo); return(sdo); }
/// <summary> /// Main process loop, used to get latest packets from buffer and also keep the SDO events pumped /// When packets are recieved they will be matched to any approprate callback handlers for this specific COB type /// and that handler invoked. /// </summary> void asyncprocess() { while (threadrun) { canpacket cp; List <canpacket> pdos = new List <canpacket>(); while (threadrun && packetqueue.IsEmpty && pdos.Count == 0 && sdo_queue.Count == 0 && SDO.isEmpty()) { System.Threading.Thread.Sleep(1); } while (packetqueue.TryDequeue(out cp)) { //PDO 0x180 -- 0x57F if (cp.cob >= 0x180 && cp.cob <= 0x57F) { if (PDOcallbacks.ContainsKey(cp.cob)) { PDOcallbacks[cp.cob](cp.data); } pdos.Add(cp); } //SDO replies 0x601-0x67F if (cp.cob >= 0x580 && cp.cob < 0x600) { if (cp.len != 8) { return; } if (SDOcallbacks.ContainsKey(cp.cob)) { if (SDOcallbacks[cp.cob].SDOProcess(cp)) { SDOcallbacks.Remove(cp.cob); } } if (sdoevent != null) { sdoevent(cp); } } if (cp.cob >= 0x600 && cp.cob < 0x680) { if (sdoevent != null) { sdoevent(cp); } } //NMT if (cp.cob > 0x700 && cp.cob <= 0x77f) { byte node = (byte)(cp.cob & 0x07F); nmtstate[node].changestate((NMTState.e_NMTState)cp.data[0]); nmtstate[node].lastping = DateTime.Now; if (nmtecevent != null) { nmtecevent(cp); } } if (cp.cob == 000) { if (nmtevent != null) { nmtevent(cp); } } if (cp.cob == 0x80) { if (syncevent != null) { syncevent(cp); } } if (cp.cob > 0x080 && cp.cob <= 0xFF) { if (emcyevent != null) { emcyevent(cp); } } if (cp.cob == 0x100) { if (timeevent != null) { timeevent(cp); } } if (cp.cob > 0x7E4 && cp.cob <= 0x7E5) { if (lssevent != null) { lssevent(cp); } } } if (pdos.Count > 0) { if (pdoevent != null) { pdoevent(pdos.ToArray()); } } SDO.kick_SDO(); if (sdo_queue.Count > 0) { SDO front = sdo_queue.Peek(); if (front != null) { if (!SDOcallbacks.ContainsKey((UInt16)(front.node + 0x580))) { if (sdo_queue.Count > 0) { front = sdo_queue.Dequeue(); //Listen for the reply on 0x580+node id SDOcallbacks.Add((UInt16)(front.node + 0x580), front); front.sendSDO(); } } } } //System.Threading.Thread.Sleep(1); } }