Communications

This section describes how to connect to a device (PalmSens or EmStat), read data from the device, manually controlling the potential, run measurements on the device and finally how to properly close a connection to a device.

Connecting to a device

The following example shows how to get a list of all available devices and available serial com ports, and how to connect to one of the discovered devices.

Using Simplified PalmSens.Core:

 using PalmSens.Devices;

Add this namespace at the top of the document.

Device[] devices = psCommSimpleWPF.ConnectedDevices;
psCommSimpleWPF.Connect(devices[0]);

The first line returns an array of all the connected devices, and the second connects to the first device in the array of connected devices. When Bluetooth devices should also be discovered set psCommSimpleWPF.EnableBluetooth = true first.

Using PalmSens.Core:

using PalmSens.Comm; 
using PalmSens.Devices; 
using PalmSens.Windows.Devices;

Add these namespaces at the top of the document.

//List of discover functions
List<DeviceList.DiscoverDevicesFunc> discFuncs = new List<DeviceList.DiscoverDevicesFunc>(); //Create an empty list of device discovery functions.

//Add the discovery functions for the types of devices you would like to discover.
discFuncs.Add(USBCDCDevice.DiscoverDevices); //Default for PS4
discFuncs.Add(FTDIDevice.DiscoverDevices); //Default for Emstat + PS3
discFuncs.Add(SerialPortDevice.DiscoverDevices); //Devices connected via serial port
discFuncs.Add(BluetoothDevice.DiscoverDevices); //Bluetooth devices (PS4, PS3, Emstat Blue)
string errors;

Device[] devices = new DeviceList(discFuncs).GetAvailableDevices(out errors);
//The GetAvailableDevices() method has an additional optional parameter which must be set to true when Bluetooth devices should be included in the search.

//Connecting to the first device in the connected devices array
CommManager comm;
Device device = devices[0];
try
{
   device.Open(); //Open the device to allow a connection
   comm = new CommManager(device); //Connect to the device
}
   catch (Exception ex)
{
   device.Close();
}

To prevent your program from crashing it is recommended to use a try catch sequence when connecting to a device, this way a device will be closed again when an exception occurs. This code will connect to the first device in the array of discovered devices.

Receive readings

The readings of PalmSens can be read continuously using the ReceiveStatus event. The following information can be found in the status object that is received using this event:

  • AuxInput (auxiliary input in V, GetExtraValueAsAuxVoltage())
  • Current (in uA, CurrentReading.Value or Status.CurrentReading.ValueInRange)
  • Current2 (in uA, in case a BiPot is used, GetExtraValueAsBiPotCurrent())
  • Noise (Noise)
  • CurrentRange (the current range in use at the moment, CurrentReading.CurrentRange)
  • CurrentStatus (as Comm.ReadingStatus is ok, underload or overload, Status.CurrentReading.ReadingStatus)
  • Potential (measured potential, PotentialReading.Value)
  • ReverseCurrent (the reverse current for SquareWave, ExtraValue)
  • PretreatmentPhaseStatus (None, Conditioning, Depositing or Equilibrating, PretreatmentPhase)
  • VoltageStatus (as Comm.ReadingStatus is ok, underload or overload, Status.PotentialReading.ReadingStatus)

Using Simplified PalmSens.Core:

Either subscribe to the ReceiveStatus event of the psCommSimpleWPF component via the designer or programmatically. It is not required to be connected to a device first.

Via the XAML designer via code or the interface:

<WPF:PSCommSimpleWPF x:Name="psCommSimpleWPF" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" 
                     ReceiveStatus="psCommSimpleWPF_ReceiveStatus"
                     StateChanged="psCommSimpleWPF_StateChanged"
                     MeasurementStarted="psCommSimpleWPF_MeasurementStarted"
                     MeasurementEnded="psCommSimpleWPF_MeasurementEnded"
                     SimpleCurveStartReceivingData="psCommSimpleWPF_SimpleCurveStartReceivingData"/>

 Or programmatically in the underlying c# code:

psCommSimpleWPF.ReceiveStatus += PsCommSimpleWPF_ReceiveStatus;

private void psCommSimpleWPF_ReceiveStatus(object sender, PalmSens.Comm.StatusEventArgs e)
{
    Status status = e.GetStatus();  //The status is obtained from the event’s StatusEventArgs.
}

Using PalmSens.Core:

//To get the device’s status updates subscribe to the CommManager’s ReceiveStatus event after connecting to a device. (comm is a reference to the instance of the CommManager created when connecting to a device).
comm.ReceiveStatus += Comm_ReceiveStatus;

private void Comm_ReceiveStatus(object sender, StatusEventArgs e)
{
   Status status = e.GetStatus();  //The status is obtained from the event’s StatusEventArgs.
}


Manually controlling the device

Depending on your device’s capabilities it can be used to set a potential/current and to switch current ranges. The potential can be set manually in potentiostatic mode and the current can be set in galvanostatic mode. The following examples show how to manually set a potential.

Using Simplfied PalmSens.Core:

//The psCommSimpleWPF component must be connected to a device before you can set its potential and control the cell. 

psCommSimpleWPF.SetCellPotential(1f);
psCommSimpleWPF.TurnCellOn();

//To turn the cell off:
psCommSimpleWPF.TurnCellOff();

Using PalmSens.Core:

comm.Potential = 1f;
comm.CellOn = true;

The device can be controlled using the CommManager that was created when connecting to the device. When the cell is turned off no potential will be set. (comm is a reference to the instance of the CommManager created when connecting to a device).

DeviceCapabilities

The capabilities of a connected device can either accessed via the CommManager.Capabilities or the psCommSimpleWPF.Capabilities property. The DeviceCapabilities contains properties such as its maximum potential, supported current ranges and support for specific features (galvanostat/impedance/bipot). The DeviceCapabilities can also be used to determine whether a certain method is compatible with a device using either method.Validate(DeviceCapabilities) or psCommSimpleWPF.ValidateMethod(method).

Measuring

Starting a measurement is done by sending method parameters to a PalmSens/EmStat device. Events are raised when a measurement has been started/ended, when a new curve/scan is started/finished, and when new data is received during a measurement.

Using Simplified PalmSens.Core:

using PalmSens.Core.Simplified.Data;

Add this namespace at the top of the document.

//Subscribing to these events informs you on the status of a measurement and gives you references to the active SimpleCurve instances. (psCommSimpleWinForms is a reference to the instance of the psCommSimpleWPF component in the Form).
psCommSimpleWPF.MeasurementStarted += PsCommSimpleWPF_MeasurementStarted; //Raised when a measurement begins
psCommSimpleWPF.MeasurementEnded += PsCommSimpleWPF_MeasurementEnded; //Raised when a measurement is ended
psCommSimpleWPF.SimpleCurveStartReceivingData += PsCommSimpleWPF_SimpleCurveStartReceivingData; //Raised when a new SimpleCurve instance starts receiving datapoints, returns a reference to the active SimpleCurve instance

SimpleMeasurement activeSimpleMeasurement = psCommSimpleWPF.Measure(method);

The last line in the example starts the measurement described in the instance of the method class. It returns a reference to the instance of the SimpleMeasurement, in the case of a connection error or invalid method parameters it returns null. Optionally, when using a multiplexer the channel can be specified as an integer, for example, psCommSimpleWPF.Measure (method,2). (method is a reference to an instance of the PalmSens.Method class, methods can be found in the namespace PalmSens.Techniques more information on methods and their parameters is available here).

The following code shows you how to obtain a reference to the instance of the active SimpleCurve currently receiving data from the SimpleCurveStartReceivingData event. It also shows how to subscribe this SimpleCurve’s NewDataAdded and CurveFinished events and how these events can be used to retrieve the values of new data points from the Simple Curve as soon as they are available.

SimpleCurve _activeSimpleCurve;

private void PsCommSimpleWPF_SimpleCurveStartReceivingData(object sender, SimpleCurve activeSimpleCurve)
{
   _activeSimpleCurve = activeSimpleCurve;
   _activeSimpleCurve.NewDataAdded += _activeSimpleCurve_NewDataAdded;
   _activeSimpleCurve.CurveFinished += _activeSimpleCurve_CurveFinished;
}

private void _activeSimpleCurve_NewDataAdded(object sender, PalmSens.Data.ArrayDataAddedEventArgs e)
{
   int startIndex = e.StartIndex;
   int count = e.Count;
   double[] newData = new double[count];
   (sender as SimpleCurve).YAxisValues.CopyTo(newData, startIndex);
}

private void _activeCurve_Finished(object sender, EventArgs e)
{
   _activeSimpleCurve.NewDataAdded -= _activeSimpleCurve_NewDataAdded;
   _activeSimpleCurve.Finished -= _activeSimpleCurve_Finished;
}

During a measurement the property psCommSimpleWPF.DeviceState property equals either CommManager.DeviceState.Pretreatment or CommManager.DeviceState.Measurement.

Using PalmSens.Core:

using PalmSens; 
using PalmSens.Comm; 
using PalmSens.Plottables;

Add these namespaces at the top of the document.

//Subscribing to these events informs you on the status of a measurement and gives you the references to the active measurement and curve instances. (comm is a reference to the instance of the CommManager created when connecting to a device).
comm.BeginMeasurement += Comm_BeginMeasurement; //Raised when a measurement begins, returns a reference to its measurement instance
comm.EndMeasurement += Comm_EndMeasurement; //Raised when a measurement is ended
comm.BeginReceiveCurve += Comm_BeginReceiveCurve; //Raised when a curve instance begins receiving datapoints, returns a reference to the active curve instance
comm.BeginReceiveEISData += Comm_BeginReceiveEISData; //Raised when a EISData instance begins receiving datapoints, returns a reference to the active EISData instance


comm.Measure(method);

The last line starts the measurement described in the instance of the method class. Optionally, when using a multiplexer the channel can be specified as an integer, for example, comm.Measure(method,2). (method is a reference to an instance of the PalmSens.Method class, methods can be found in the namespace PalmSens.Techniques more information on methods and their parameters is available here).

Measurement measurement; 

//When the BeginMeasurement event is raised it returns a reference to the instance of the current measurement. 
//Alternatively, this reference can be obtained from the CommManager.ActiveMeasurement property after the measurement has been started. 

private void Comm_BeginMeasurement(object sender, ActiveMeasurement newMeasurement) 
{ 
   measurement = newMeasurement; 
}
 
// The following code shows you how to obtain a reference to the instance of the active curve currently receiving data from the BeginReceiveCurve event. 
// It also shows how to use the active curve’s NewDataAdded and Finished events to retrieve the values of new data points from the curve as soon as they are available. 

Curve _activeCurve; 

private void Comm_BeginReceiveCurve(object sender, PalmSens.Plottables.CurveEventArgs e) 
{ 
   _activeCurve = e.GetCurve(); 
   _activeCurve.NewDataAdded += _activeCurve_NewDataAdded; 
   _activeCurve.Finished += _activeCurve_Finished; 
} 

private void _activeCurve_NewDataAdded(object sender, PalmSens.Data.ArrayDataAddedEventArgs e) 
{ 
   int startIndex = e.StartIndex; 
   int count = e.Count; 
   double[] newData = new double[count]; 
   (sender as Curve).GetYValues().CopyTo(newData, startIndex); 
} 

private void _activeCurve_Finished(object sender, EventArgs e) 
{ 
   _activeCurve.NewDataAdded -= _activeCurve_NewDataAdded; 
   _activeCurve.Finished -= _activeCurve_Finished; 
}

When performing Impedance Spectroscopy measurements data points are stored in an instance of the EISData class and these events should be used similarly to those used for other measurements.

EISData _activeEISData;

Add this namespace at the top of the document.

private void Comm_BeginReceiveEISData(object sender, PalmSens.Plottables.EISData eisdata)
{
   _activeEISData = eisdata;
   _activeEISData.NewDataAdded += _activeEISData_NewDataAdded; //Raised when new data is added
   _activeEISData.NewSubScanAdded += _activeEISData_NewSubScanAdded; //Raised when a new frequency scan is started
   _activeEISData.Finished += _activeEISData_Finished; //Raised when EISData is finished
}

During a measurement the property comm.Busy is TRUE.

Closing the Com port

The com port is automatically closed when the instance of the CommManager is disconnected or disposed.

Using Simplified PalmSens.Core:

psCommSimpleWPF.Disconnect(); or psCommSimpleWPF.Dispose();

Using PalmSens.Core:

comm.Disconnect(); or comm.Dispose();