Chat with us, powered by LiveChat

SDK for Android – 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 that.

Using Simplified PalmSens.Core:

 using PalmSens.Devices;

Add this namespace at the top of the document.

Device[] devices = await psCommSimpleAndroid.GetConnectedDevices();
psCommSimpleAndroid.Connectdevices[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.

Using PalmSens.Core:

using PalmSens.Comm; 
using PalmSens.Devices; 
using PalmSens.PSAndroid.Comm;

Add these namespaces at the top of the document.

//Discover devices with DeviceDiscoverer over BlueTooth and USB
Device[] devices = new Device[0];
DeviceDiscoverer deviceDiscoverer = new DeviceDiscoverer(Context);
devices = (await _deviceDiscoverer.Discover(true, true)).ToArray();
deviceDiscoverer.Dispose();

//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, 5000); //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:

Subscribe to the ReceiveStatus event of the psCommSimpleAndroid control in the OnCreate event of your app. It is not required to be connected to a device first.

PSCommSimpleAndroid psCommSimpleAndroid;

protected override void OnCreate(Bundle bundle)
{
   base.OnCreate(bundle);
   
   // Set our view from the "main" layout resource
   SetContentView (Resource.Layout.Main);

   //Get reference to psCommSimpleAndroid control
   psCommSimpleAndroid = FindViewById<PSCommSimpleAndroid>(Resource.Id.pSCommSimpleAndroid);
   psCommSimpleAndroid.ReceiveStatus += _psCommSimpleAndroid_ReceiveStatus;
}

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 Simplified PalmSens.Core:

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

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

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

Using PalmSens.Core:

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

//To turn the cell off:
comm.CellOn = false;

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 psCommSimpleAndroid.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
psCommSimpleAndroid.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. (psCommSimpleAndroid is a reference to the instance of the psCommSimpleAndroid control in the Form).
psCommSimpleAndroid.MeasurementStarted += PsCommSimpleAndroid_MeasurementStarted; //Raised when a measurement begins
psCommSimpleAndroid.MeasurementEnded += PsCommSimpleAndroid_MeasurementEnded; //Raised when a measurement is ended
psCommSimpleAndroid.SimpleCurveStartReceivingData += PsCommSimpleAndroid_SimpleCurveStartReceivingData; //Raised when a new SimpleCurve instance starts receiving datapoints, returns a reference to the active SimpleCurve instance

SimpleMeasurement activeSimpleMeasurement = psCommSimpleAndroid.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, psCommSimpleAndroid.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 PsCommSimpleAndroid_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 psCommSimpleAndroid.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:

psCommSimpleAndroid.Disconnect();

Using PalmSens.Core:

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