/// <summary> /// Handler for the NewPacket event. The packet is sent to the client by means of a callback function. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void NewPacketHandler(object sender, EventArgs e) { ADS1298device targetDevice; ADS1298deviceVM targetDeviceVM; RawDataPacket packet; XDataPacket xPacket; if (!_ignorePackets) { //We retrieve a raw packet, convert it to a serializable iDataPacket //and send it to the client through a callback function. try { targetDevice = (ADS1298device)(EMGSingleton.Instance.EPdevices.ElementAt(deviceNum)); targetDeviceVM = (ADS1298deviceVM)(EMGSingleton.Instance.EPdevicesViewModel.ElementAt(deviceNum)); while (!targetDevice.packetQueue.TryDequeue(out packet)) ; xPacket = new XDataPacket(); xPacket.payloadSize = packet.payloadSize; xPacket.sampleFreq = packet.sampleFreq; //For our purpose, we assume that the gain has the same value for all channels. xPacket.gain = targetDeviceVM.GAIN_LIST[0]; xPacket.inputDifferentialVoltagePositive = targetDeviceVM.InputDifferantialVoltagePositive; xPacket.inputDifferentialVoltageNegative = targetDeviceVM.InputDifferantialVoltageNegative; xPacket.payload = System.Convert.ToBase64String(packet.payload); xPacket.resolutionBits = (Byte)targetDeviceVM.ResolutionBits; xPacket.frameSize = packet.frameSize; xPacket.nChannels = packet.nChannels; xPacket.nFrames = packet.nFrames; xPacket.lastPacket = packet.lastPacket; xPacket.timeStamp = packet.timeStamp; xPacket.timeDelta = packet.timeDelta; //DEBUG //Console.Out.WriteLine(xPacket); //DEBUG/ //And then we should use a callback that allows a IDataPacket as parameter serviceCallback.NewPacket(xPacket); //DEBUG dequeuedPackets++; //DEBUG/ //Console.Out.Write("> "); } catch (Exception ex) { //Something happened that prevented us from sending the packet! //In this case, we stop the acquisition process. Debug.WriteLine("An exception was caught while running the packet handler!"); Debug.WriteLine(ex.ToString()); Debug.WriteLine("Data acquisition will be stopped."); ProcessData(); } } }
public void NewPacket(XDataPacket packet) { Byte[] buffer; double[] sample = new double[packet.nChannels]; Byte[] frame = new Byte[packet.frameSize]; UInt32 countvalue; float inputDifferentialVoltage = ADS1298DataQueue.Instance.posVoltage - ADS1298DataQueue.Instance.negVoltage; UInt32 powerOfResBits = (UInt32)(1 << packet.resolutionBits); Frame currentFrame; BlockingCollection<Object> queue = ADS1298DataQueue.Instance.queue; //Length of the moving average buffer used when correcting signal offset UInt32 correctLength = packet.sampleFreq/8; bool correctOffset = ADS1298DataQueue.Instance.correctOffset; if (correctOffset) { //Using an average array with 0.125 seconds of samples (packet.sampleFreq/8) if (_avgArray == null) _avgArray = new double[correctLength, packet.nChannels]; if (_avgValues == null) _avgValues = new double[packet.nChannels]; } if (queue.IsAddingCompleted) return; if (ADS1298DataQueue.Instance.paused) return; //We transform back the frame data into a byte array buffer = System.Convert.FromBase64String(packet.payload); if (packet.lastPacket == true) { //We have received a dummy packet indicating that there will be no more frame packets coming. //The current capture session has finished, but we only mark the queue as complete for adding //if the data acquisition is not paused. if (!ADS1298DataQueue.Instance.paused) queue.CompleteAdding(); return; } int temp; for (Int32 i = 0; i < packet.nFrames; i++) { Buffer.BlockCopy(buffer, (Int32) packet.frameSize * i, frame, 0, (Int32) packet.frameSize); countvalue = (UInt32)(frame[00]<<16|frame[01]<<8|frame[02]); int channel = 0; double min = 0; double max = 0; for (int j = 3; j <= frame.Length-3; j=j+3 ) { temp = (frame[j] << 24 | frame[j+1] << 16 | frame[j+2] << 8) / 256; //Experimenting with a moving average to detect the channel amplitude offset if (correctOffset) { /* _avgArray[avgPos, channel] = (double)temp / (double)correctLength; _avgValues[channel] = _avgValues[channel] + _avgArray[avgPos, channel] - _avgArray[(int)((avgPos + 1) % correctLength), channel]; */ _avgValues[channel] = _avgValues[channel] - _avgArray[avgPos, channel]; _avgArray[avgPos, channel] = (double)temp / (double)correctLength; _avgValues[channel] += _avgArray[avgPos, channel]; temp -= (int)_avgValues[channel]; } //End of the experiment sample[channel] = ((double)temp / (double)powerOfResBits) * inputDifferentialVoltage; if (channel == 0) { min = sample[channel]; max = sample[channel]; } else { if (sample[channel] < min) min = sample[channel]; else if (sample[channel] > max) max = sample[channel]; } channel++; } //This is only used when performing offset correction avgPos = (int)((avgPos + 1) % correctLength); currentFrame = new Frame(sample, ADS1298DataQueue.Instance.frameIdx, ADS1298DataQueue.Instance.timeIdx, min, max); ADS1298DataQueue.Instance.frameIdx++; ADS1298DataQueue.Instance.timeIdx = ADS1298DataQueue.Instance.frameIdx / (double)packet.sampleFreq; queue.Add(currentFrame); } }
public void NewPacket(XDataPacket packet) { //Console.Out.Write("* "); Byte[] buffer; Int32 nFrames; double[] sample = new double[8]; Byte[] frame = new Byte[27]; UInt32 countvalue; Byte DATALENGTH = 27; float inputDifferentialVoltage = packet.inputDifferentialVoltagePositive - packet.inputDifferentialVoltageNegative; UInt32 powerOfResBits = (UInt32)(1 << packet.resolutionBits); Frame currentFrame; Console.Out.WriteLine("sampleFreq: {0}",packet.sampleFreq); Console.Out.WriteLine("payloadSize: {0}", packet.payloadSize); //We transform back the frame data into a byte array buffer = System.Convert.FromBase64String(packet.payload); nFrames = packet.payloadSize/DATALENGTH; //We should get DATALENGTH from the device model! for (Int32 i = 0; i < nFrames; i++) { Buffer.BlockCopy(buffer, DATALENGTH * i, frame, 0, DATALENGTH); //An unrolled loop to obtain the counter and float values for each frame countvalue = (UInt32)(frame[00]<<16|frame[01]<<8|frame[02]); sample[0]=frame[03]<<24|frame[04]<<16|frame[05]<<8; sample[0]=(sample[0]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); sample[1]=frame[06]<<24|frame[07]<<16|frame[08]<<8; sample[1]=(sample[1]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); sample[2]=frame[09]<<24|frame[10]<<16|frame[11]<<8; sample[2]=(sample[2]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); sample[3]=frame[12]<<24|frame[13]<<16|frame[14]<<8; sample[3]=(sample[3]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); sample[4]=frame[15]<<24|frame[16]<<16|frame[17]<<8; sample[4]=(sample[4]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); sample[5]=frame[18]<<24|frame[19]<<16|frame[20]<<8; sample[5]=(sample[5]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); sample[6]=frame[21]<<24|frame[22]<<16|frame[23]<<8; sample[6]=(sample[6]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); sample[7]=frame[24]<<24|frame[25]<<16|frame[26]<<8; sample[7]=(sample[7]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); currentFrame = new Frame(sample, countvalue, countvalue / (double) packet.sampleFreq,packet.inputDifferentialVoltageNegative,packet.inputDifferentialVoltagePositive); //DEBUG /* Console.Out.Write("{0} ", countvalue); Console.Out.Write("{0} ", sample[0]); Console.Out.Write("{0} ", sample[1]); Console.Out.Write("{0} ", sample[2]); Console.Out.Write("{0} ", sample[3]); Console.Out.Write("{0} ", sample[4]); Console.Out.Write("{0} ", sample[5]); Console.Out.Write("{0} ", sample[6]); Console.Out.Write("{0} ", sample[7]); */ //DEBUG/ } //DEBUG //And the, print out what we got formated by samples and fields /* Console.Out.WriteLine("Length of the recovered data: {0}", Buffer.ByteLength(buffer)); for (Int32 i = 0; i < frame.payloadSize; i++) { Console.Out.Write("{0} ", buffer[i]); } */ //DEBUG/ }