/****************************************************************************** * * RECORDING THREAD! * * ****************************************************************************/ private void RecordingThread() { uint received; bool a = true; bool b = true; bool lasta, lastb; AcqChan = TotChan(); //How many channels are we going to acquire VoltageSpacing =(int)(Ymax / (AcqChan)); Thread BuffDraw = new Thread(new ThreadStart(drawbuffer)); //Set up thread for buffering BuffDraw.Start(); //and then start it BuffSize = ((uint)(SampleRate/UpdateSpeed))*(uint)AcqChan; //Need to determine the right buffer size. rec_buffer = new double[BuffSize]; //Place to copy the buffer of recieved data draw_buffer = new double[BuffSize]; //Place to copy the buffer to, for drawing //Need that so we can do thread-safe operations. Int32 transbuffer = new Int32(); //Translational buffer to write bytes instead of doubles. MPReturn = MPCLASS.startAcquisition(); //Start actual acquisition if (MPReturn != MPCODE.MPSUCCESS) //If acquisition fails, error out. { } while (isstreaming) //Thread stopping variable - set to false to end the recording thread. { MPReturn = MPCLASS.receiveMPData(rec_buffer, BuffSize, out received); //Get the latest buffer //This function pauses until the buffer is full - making the 'recieved' variable somewhat useless. //If this fails, the recieved will be smaller than the buffsize, but you have bigger issues. if (MPReturn != MPCODE.MPSUCCESS) //Make sure we were successful in getting the buffer. { MessageBox.Show(MPReturn.ToString() + " " + MPCLASS.getMPDaemonLastError().ToString()); MPReturn = MPCLASS.stopAcquisition(); //Have to restart the aquisition. return; } if (received % AcqChan > 0) { Console.WriteLine("Buffersize Mismatch @ " + DateTime.Now.TimeOfDay.ToString()); } last_received = received; //For the draw buffer samplesize = (int)last_received / AcqChan; samplecount += samplesize; VideoWrapper.SetSampleCount(samplecount); if (IsFileWriting) //If we are writing to the file, we want to handle it immediately. { BinaryFile.Seek(CurrentWriteLoc, SeekOrigin.Begin); //Make sure the File writting is in the right place if (string.Compare(RecordingDevice, "Telemetry") == 0) { for (int j = 0; j < BuffSize; j++) //Cycle through the buffer. { rec_buffer[j] = Math.Min(rec_buffer[j], 4); //Make sure we don't exceed the maxes rec_buffer[j] = Math.Max(rec_buffer[j], 0);//Make sure we don't exceed the minmum transbuffer = Convert.ToInt32((rec_buffer[j] - Offset) * (double)Int32.MaxValue / 2); //Convert the value BinaryFileID.Write((Int32)transbuffer); //Write the bytes to the file. The int16 probably isn't necessary to cast, //better safe than sorry. } } else { for (int j = 0; j < BuffSize; j++) //Cycle through the buffer. { rec_buffer[j] = Math.Min(rec_buffer[j], Int32.MaxValue / Gain); //Make sure we don't exceed the maxes rec_buffer[j] = Math.Max(rec_buffer[j], Int32.MinValue / Gain);//Make sure we don't exceed the minmum transbuffer = Convert.ToInt32((rec_buffer[j]) * Gain); //Convert the value BinaryFileID.Write((Int32)transbuffer); //Write the bytes to the file. The int16 probably isn't necessary to cast, //better safe than sorry. } } CurrentWriteLoc = BinaryFile.Position; //Update the current location. if (FileStop) //Need to have thread safe file closing! Oops! { updateheader(); //Write sample total BinaryFile.Close(); //Close FileCount = 0; IsFileWriting = false; FileStop = false; } else if (BinaryFile.Position > (1980 * MBYTE)) //Need to stop file, and restart it { updateheader(); //Write the final Stuff BinaryFile.Close(); //Close the file FileCount++; //Apparently, I don't need this, because the code won't overwrite a file. But, whatever StartWriting(); //Start a new file! } } lasta = a; //These serve as a debounce function. lastb = b; //Without debounce, you get multiple states in a single transistion if (Feeder.gap == 0) { MPCLASS.getDigitalIO(9, out a, MPCLASS.DIGITALOPT.READ_HIGH_BITS); //read the high bit for state MPCLASS.getDigitalIO(8, out b, MPCLASS.DIGITALOPT.READ_HIGH_BITS); //read the low bit for state if ((lastb == b) && (lasta == a)) { if (a && b) //11, feeder ready { Feeder.State = 3; Feeder.StateText = "READY"; } if (!a && b) { Feeder.State = 1; Feeder.StateText = "EXECUTING"; } if (a && !b) { if (Feeder.State != 2) { string Result = "SUCCESS - " + Feeder.GetLastCommandText() + " - "; FEB.Invoke(new MethodInvoker(delegate { FEB.Add_Status(Result); })); Feeder.ExecuteAck(); } Feeder.State = 2; Feeder.StateText = "SUCCESS"; } if (!a && !b) { if (Feeder.State == 3) //If the feeder goes from ready to Error, something happened with the infrared sensors { FEB.Invoke(new MethodInvoker(delegate { FEB.Add_Error("Infrared Sensors offline - "); })); } else if (Feeder.State == 1) //if something went wrong during execution, then the feeder failed to deliver pellets. { string Result = "FAIL - " + Feeder.GetLastCommandText() + " - "; FEB.Invoke(new MethodInvoker(delegate { FEB.Add_Error(Result); })); Feeder.ExecuteAck(); } Feeder.State = 0; Feeder.StateText = "ERROR"; } } if ((Feeder.CommandSize > 0) && Feeder.CommandReady) { byte v; v = Feeder.GetTopCommand(); Feeder.gap++; for (byte k = 0; k < 5; k++) //Step through the bits of the command { bool x =!((v&(1 << k)) > 0); //mathematical way to make x the kth bit MPCLASS.setDigitalIO((uint)k, x, true, MPCLASS.DIGITALOPT.SET_LOW_BITS); //set it on the MP150 } MPCLASS.setDigitalIO(7, true, true, MPCLASS.DIGITALOPT.SET_LOW_BITS); //pulse the data ready bit Thread.Sleep(1); MPCLASS.setDigitalIO(7, false, true, MPCLASS.DIGITALOPT.SET_LOW_BITS); //finish pulse } } else if (Feeder.gap > 0) //only want to send the feeding commands once every 4 cycles { Feeder.gap++; if (Feeder.gap == 6) { Feeder.gap = 0; } } Buffer.BlockCopy(rec_buffer, 0, draw_buffer, 0, (int)received * 8); //copy the Buffer to the drawing area _DrawHandle.Set(); //let the drawing thread know that data is available. } BuffDraw.Abort(); MPReturn = MPCLASS.stopAcquisition(); //We won't get here unless the thread stops. return; }
public bool Disconnect() { this.MPReturn = MPCLASS.disconnectMPDev(); if (this.MPReturn != MPCODE.MPSUCCESS) return true; else return false; }
public bool StartRecording() { AcqThread = new Thread(new ThreadStart(RecordingThread)); //Initialize recording thread AcqThread.Priority = ThreadPriority.Highest; isstreaming = true; g = Graphics.FromImage(offscreen); ClearDisplay = true; Ymax = Convert.ToSingle(g.VisibleClipBounds.Height); Xmax = Convert.ToSingle(g.VisibleClipBounds.Width); PointSpacing = Convert.ToSingle(Xmax / MaxDrawSize); MPReturn = MPCLASS.setDigitalAcqChannels(DigitalChannel); if (this.MPReturn != MPCODE.MPSUCCESS) return false; MPReturn = MPCLASS.setSampleRate(1000 / SampleRate); if (this.MPReturn != MPCODE.MPSUCCESS) return false; this.MPReturn = MPCLASS.setAcqChannels(this.RecordAC); if (this.MPReturn != MPCODE.MPSUCCESS) return false; this.MPReturn = MPCLASS.startMPAcqDaemon(); if (MPReturn != MPCODE.MPSUCCESS) return false; AcqThread.Start(); return true; }
/********************************************************************** * * Connection/Recording functions * ***********************************************************************/ public bool Connect() { //connect to the MP Device this.MPReturn = MPCLASS.connectMPDev(MPCLASS.MPTYPE.MP150, MPCLASS.MPCOMTYPE.MPUDP, "auto"); if (this.MPReturn != MPCODE.MPSUCCESS) { return false; } return true; }