Public Lab Research note


Potentiostat Notes 2: Software

by JSummers | December 20, 2013 20:12 | 484 views | 18 comments | #9911 | 484 views | 18 comments | #9911 20 Dec 20:12

Read more: i.publiclab.org/n/9911


What I want to do

We are working to develop laboratory instrumentation for education and environmental monitoring. This note follows up on an earlier research note found at http://publiclab.org/notes/JSummers/11-02-2013/potentiostat-notes-1-wheestat-history. In that note, I describe our reasons for transitioning from the Texas Instruments MSP430g2553 LaunchPad microcontroller to the Stellaris microcontroller. At the time, we did not have the microcontroller software developed and had not begun working on the GUI. We now have that software written and pushed to our GitHub page. In this note, we report on some of the characteristics of the software and the Stellaris based system. This work was done by Ben Hickman and me.

My attempt and results

The software described in this note can be found at https://github.com/SmokyMountainScientific/WheeStat5_0. It consists of Energia code used to program the microcontroller board and Processing code for the GUI. All the test data in this note were acquired with the WheeStat5.1 hardware from the earlier note. The tests were conducted with the reference and counter electrodes attached to one side of a resistor and the working electrode attached to the other side. Thus, all behaviors should follow Ohm's Law.
The instrument as described will support the following experiments; voltage ramp, cyclic voltammetry, differential pulse voltammetry, anodic- and cathodic-stripping voltammetry, and a data logging version of the stripping voltammetry experiments. The top of the GUI (shown below) has dropdowns that allow the user to select the com port and experiment. In the figure, Com 21 has been selected and the ramp experiment executed. The overlay button allows you to overlay successive voltammagrams (plots of current versus voltage) to allow comparison. GUI-top.png On the left side of the GUI are a set of text boxes that allow input of run parameters. As you can see, values can be input for the initial and final voltages, current gain and offset, an initial delay, and the scan rate. Below the delay and scan rate is an empty box that will become active if the log_ASV experiment is selected from the mode dropdown list. In this case, you can enter the number of runs you wish to measure and the delay between runs. controlls.png The main image for this note shows a voltammagram where the voltage is ramped from -400 mV to +400 mV at a rate of 100 mV/s. You will notice that the early and late sections of the voltammagrams are flat-lined at the maximum and minimum values that the potentiostat can read. The maximum is at VCC (3287 mV above GND). The minimum is at about 600 mV and I think that reflects the limitations on the amps we chose to use (stay tuned, I have purchased different amps). You will also notice a little bump in the data at ~100 mV. I don't know what the heck that is. I think it is hardware related because it is certainly reproducible. So anyway, to keep the current reading on scale, you adjust the gain and offset values (these are the digital inputs that replaced my beloved analog knobs, as described in the earlier note). The figures below show the effects of systematically varying one then the other. These voltammagrams were collected in overlay mode to allow comparison. effects_of_current_gain.png The figure above shows that adjusting the current gain affects the slope of the line. Note that there is not a linear or logarithmic correlation between the gain value and the current amplification (if you are interested in the correlation then ask). The figure below shows that changing the offset does what you would expect, it shifts the data either up or down. effects_of_offset.png If you look closely, you will see that there is one data point in each of the two figures above that does not seem to go with anything else. This was due to a software bug that we have since fixed. The reproducibility of the ADC can be appreciated by considering the differential pulse voltammagram below. In this experiment, a square wave voltage pulse is superimposed on the voltage ramp and the current is sampled at the bottom and the top of the pulse. The current reported is the difference between the current at the low and high points of the pulse. This type of experiment filters out Ohm's Law type of effects and (in this case) should give a constant current output equal to i = (V hi - V low)/R. The data below show the current scale expanded to the point where the digitization is apparent (1 mV resolution on the y scale). To me this looks like the ADC reproducibility is not too shabby since each point reflects the difference between two measured values considering we are using a 12 bit ADC. asv_screenshot.png Ok, so that is differential pulse analysis of a resistor when Ohm's Law is followed. The figure below shows what you get when you try to measure current outside of the limits of detection: asv-truncated.png You will notice that the scan parameters for the differential pulse voltammagram above are the same as for the ramp experiment in the main image. That means that at voltages where the ramp voltammagram flat lined, the high and low current for the differential pulse experiment are the same, giving a zero value for the difference. While it is really apparent in this voltammagram that something has gone wrong, that will not always be the case. Luckily, there is an orange error message just above the graph pointing out the problem, and suggesting what to do about it.

Questions and next steps

The next steps for me are: (1) Make up some solutions and drop in the electrodes to evaluate performance in real-life lab environment. (2) Evaluate the lower detection limit for this configuration. I have a feeling that I would be happier with a 50 k ohm potentiostat (rather than the 10 k one in the instrument currently), but lets get the parameters on this one measured before calling up the digikey folks. (3) I need to make a new board using one of the rail-to-rail op amps we purchased and see if that does not allow us to measure a wider current range than we currently have access to. (4) I need to write up a note describing fabrication of the WheeStat shield. (5) Once we decide on a final hardware design, I need to order a bunch of pcb's from a fab house. I told a colleague I would have 8 copies for her to use by March (if you are not afraid of surface mount soldering and would like a kit, let me know and I will put one together for cost+shipping). In the mean time, you can check out the GUI. You should be able to download just the windows executable file, source and library files from (https://github.com/SmokyMountainScientific/WheeStat5_0/tree/master/WheeStat5GUI/WheeStatWinExe) That should allow you to run the GUI without having to download the Processing code. Guess that is about it. Jack


18 Comments

One thought on the microcontroller - we are using a Teensy 3.0, which has a 16 bit ADC built in (13 bit usable), and we've found it to be pretty darn effective. Also, the newest version (Teensy 3.1) actually has 2 ADCs, so you can sample 2 channels simultaneously or, double the number of samples from a single source (increasing your resolution). It also has a 12 bit analog output pin which may be useful for testing. Kind of a nice integrated solution.

Awesome project!

Greg

Reply to this comment...


Merry Christmas! - I've been following the original msp430 launchpad based potentiostat you presented a while back,and now the stellaris based one here.I'm interested in building this and have downloaded the Wheestat_5 Energia files and GUI you provided on github.I also downloaded the SPI.h library from the Stellaisiti forum as you instructed.When trying to compile the Energia Wheestat_5 sketch, I got the following errors:

digi_Pot.ino:18:6:error:"class SPIClass"has no member named 'setModule' digi_Pot.ino:28:7:error:"class SPIClass"has no member named 'trans2ByteA'

there are 3 more errors that then alternate with 'trans2ByteA' and 'trans2ByteB'

My question is ...what am I missing and/or forgot to do? You'll have to forgive me,(I'm a Hardware guy),and my programming skills are quite rudimentary.Any help and/or insight you could provide would be greatly appreciated! Thanks in advance.....Regards Mark

Is this a question? Click here to post it to the Questions page.

Reply to this comment...


Hi Mark, Sorry, but I forgot to mention the issues with the SPI library. It turns out that the SPI library that came with Energia did not initialize SPI module 0 correctly, and once that was fixed it still required some modification to communicate with the digital potentiometer I used.
You can get SPI0 to initialize by replacing the SPI library with one found here; http://forum.stellarisiti.com/topic/675-solved%C2%A0launchpad-stellaris-on-energia-miso-erratic-behaviour-on-spi0-and-spi3/. Look for the zip file in a July 8, 2013 posting by Rei Villo (This issue may be fixed in more recent versions of Energia, so you may not need the new library, I don't know). I unzipped the file to the libraries file for the Stellaris (for me that is at C:/program files/ energia 0101E0010/ hardware / lm4f / libraries). I then changed the name on the original SPI library and re-named the new library "SPI". That got the SPI0 module functioning, but I still had problems getting the digital potentiometer to work. I believe the problem was related to the pot requiring a 16 bit command and the commands in the SPI library only transferring 8 bits. This means that the CS signal needs to stay low for the 16 bit transfer. It turns out that I also had a hardware problem that complicated diagnostics. Anyway, once you are able to get SPI0 working, you still need to add the following definitions for trans2ByteA and trans2ByteB to your SPI library.

        uint8_t SPIClass::trans2ByteA(uint8_t data) {
              return transfer(slaveSelect, data, SPI_CONTINUE); }
        uint8_t SPIClass::trans2ByteB(uint8_t data) {
              return transfer(slaveSelect, data, SPI_LAST); }

trans2ByteA pulls the chip select pin low, transmits the first 8 bits and leaves chip select low. trans2ByteB assumes that chip select is low to start with, transmits the second 8 bits and pulls chip select high, finishing the 16 bit transfer. There is kind of an odd delay between the two 8 bit bytes, but the potentiometer seems to work fine. My struggles with this are described in a little greater detail at http://forum.stellarisiti.com/topic/1719-spi-with-16-bit-data/.
Try that and let me know if it works. If that does not work, let me know what you see and I will try to help. Best, Jack

Reply to this comment...


Greg; Thanks for bringing the Teensy to my attention. I was unaware of it. It looks like a neat system. While I am (currently) bought into the TI platform, I think it is great that the big hardware names are competing with each other for the diy market. Jack

Reply to this comment...


Agreed - competition is a great thing! I wouldn't call Teensy a big hardware name though - the processor is big (Atmel ARM), but the board itself is just a husband and wife team at PJRC. Awesome support and great product if you ever want to try something different -

Reply to this comment...


Hello Again! I'd like to thank you for getting back to me on my compiling problems with the Wheestat5_0 energia sketch;I've followed the instructions that you provided;I now have the following errors; In file included from Wheestat5_0.ino:11:0: C:\energia-0101E0011\hardware\lm4f\libraries\SPI/SPI.h:58:11:error:extra qualification 'SPIClass::'on member 'trans2ByteA'[-fpermissive] C:\energia-0101E0011\hardware\lm4f\libraries\SPI/SPI.h:60:11:error:extra qualification 'SPIClass::'on member 'trans2ByteB'[-fpermissive]

note: I added the definitions to the new renamed SPI.h file; I'm wondering if perhaps I've put them in the wrong place? Yeah,I know ...pretty pathetic for me not being very versed in the coding end of things.....I'm at least willing to learn.My strong suite happens to be hardware design...30 years worth and counting.Anyway,if you have time for some more suggestions,I'd be very grateful! If I don't hear from you before this year ends, Have a safe and very Happy New Year!!! Regards, Mark

Is this a question? Click here to post it to the Questions page.

Reply to this comment...


Hi Mark, Once again an oversight on my part. I am very new to coding myself. If I had more experience with it I would probably have less difficulty remembering all the steps to making it work. I think I need to do some editing to the research note once we have all this figured out so that the process works a little better. A friend recommended that I put the SPI library on GitHub for people to download. I think that may make some sense.
Anyway, the SPI folder in the lm4f libraries folder should have two files that need to be modified, these are named SPI.h and SPI.cpp,

In my SPI.h file, I added the following lines at about line 60:

uint8_t trans2ByteA(uint8_t);         //  new function
uint8_t trans2ByteB(uint8_t);         //  new function
                                     // transfers 2 bytes

A colleague of mine recommended the following instead. If my version doesn't work, I would try his:

uint8_t trans2ByteA(uint8_t data);
uint8_t trans2ByteB(uint8_t data);

In the SPI.cpp file, at line 210, I have the following (note, the next three lines define the command "transfer()", are already be in the file. I included these to make it easier to see where the new code should go) :

uint8_t SPIClass::transfer(uint8_t data) {
return transfer(slaveSelect, data, SPI_LAST);
}

below the transfer definition is where I added the trans2Byte defs

uint8_t SPIClass::trans2ByteA(uint8_t data) {

return transfer(slaveSelect, data, SPI_CONTINUE);

}
uint8_t SPIClass::trans2ByteB(uint8_t data) {

return transfer(slaveSelect, data, SPI_LAST);

}

Here's to a happy new year. Let me know what that does.

Reply to this comment...


Hello Dr. Summers, Thanks for getting back to me so soon.I followed your last instructions and tried compiling the Wheestat5_0 sketch.I got an error that referred to the fastdigitalwite.h and fastdigitalwrite.cpp files located within the new SPI library from the stellarisiti forum.I went back through the complete Wheestat5_0 sketch you've written,and could not find any instance where this library (fastdigitalwrite) is called.(the error simply states;board not supported).So I moved the two files to the original SPI file(I re-named it OLDSPI),and then tried to complile the sketch; It compiled successfully!Upon compiling,it shows a sketch size of 8,896 bytes; does that sound about right? If so...it would appear that we're good to go.Please advise if I've commited some "digital sin" by performing the actions above,otherwise,I'll assume for the time being,that I can move on to building the hardware(I have 2 Stellaris Launchpad boards on the way;as well as 14-pin PDIP versions of the digital pots.I already have a number of rail to rail opamps that can fill this projects requirements nicely). Well, that's about it for now,again......thank's so very much for both your help and patience!

Regards, Mark Rairie

Is this a question? Click here to post it to the Questions page.

Reply to this comment...


Hi Mark, I am glad to hear that you were able to get the program compiled. I have no idea what the error message you refer to means. Sometimes I get a similar message when I have not got the Stellaris LauchPad selected from the "tools" dropdown, but that has nothing to do with the fastdigitalwrite. Since you are going for the PDIP pot, I assume that you age going to build this up on a breadboard. Let me know if you are interested in a surface mount pcb. I got the VCC powered board with the rail to rail amp running today and the test data look good. I think I am ready to finalize the design and have some pcb's fabricated professionally. I hope to get to writing up the hardware build tomorrow. Let me know how this goes.
Best, Jack

Reply to this comment...


can I do this on the Arduino?

Is this a question? Click here to post it to the Questions page.

Reply to this comment...


I am pretty sure that it could be done.
My only concern would be converting the microcontroller code from Energia code to Arduino. The two are very similar but I dont believe that they would translate exactly. I suspect that someone with a good knowledge of Arduino would be able to convert it with a little patience and work. I have no doubt that the GUI would work without any modification. It just communicates through a serial port and there is no reason for it to care whether it is talking with a TI product or an Arduino. While the physical layout of the board would require adjusting, I have already drawn up an Eagle file for an Uno shield that I think should work. Let me know if you want to give it a try. I can easily post the Eagle file on GitHub (or send it directly to OSH Park if you want) and you could get a board made. If you are interested in this, let me know how I can help. Jack

Reply to this comment...


@JSummers

Hi, I'm currently trying to create a potentiostat that will be able to do similar electrochemical experiments. Mainly, I would like to do corrosion analysis on gold electrodes in a saline solution. Normally, I use a large, commercial potentiostat to run electrochemical impedance spectroscopy (EIS) and polarization resistance tests to see how the electrode impedance changes over time. Do you think the latest iteration of the WheeStat would be able to run these tests after some modifications with the microcontroller code and GUI? Thanks.

Is this a question? Click here to post it to the Questions page.

Reply to this comment...


@bjl1629 Hi, I have never done any EIS and have not gotten into its theoretical or practical aspects. That said, where would we all be if we let total ignorance of a subject prevent us from poking at it? As I understand it, EIS employs a two electrode system (working and counter) and applies an AC voltage signal on the counter electrode. The AC current on the working electrode is monitored to determine phase shift and intensity as a function of frequency (please correct me if I am wrong). The main problem that I foresee has to do with the hardware that would generate the AC voltage at the counter electrode. The WheeStat hardware was designed for DC experiments where voltage changes are relatively slow and we put absolutely no effort into optimizing it for high frequency AC output. That said, there may be a way to do high frequency work if it would be ok to have the signal be square wave instead of sinusoidal.
The WheeStat has two inputs from the microcontroller that determine the applied voltage: they are called the input pin and the pulse pin. The input pin is attached to a microcontroller pwm pin that outputs the main signal. This signal is converted from a digital (pwm) signal to an analog (DC) signal using a two stage passive low-pass filter (see note* below for specs to calculate a time constant). I dont think we can go very fast on this pin because of the low pass filter. The pulse pin, however, is not on a filter. Its function is to provide a square wave with a defined voltage that is overlayed on the input voltage (Used in differential pulse experiments). It may be possible to achieve what you are trying to do by running square wave experiments on the pulse pin. I should note, however, that there are also a couple of R/C pieces in the read circuit that might pose difficulties. Let me know what you think. Jack

note* for determining time constant on input pin: R1 and R2 are 1K and 220 ohm, both caps are 4.7 uF. This is isolated from the pulse input and the amplifier by another 1 K resistor

Is this a question? Click here to post it to the Questions page.

Reply to this comment...


@JSummers Jack, Thanks for explaining the details of the design. Sorry for the delayed response, the notification email from your response got stuck in my spam folder. You're correct about the details of EIS. From what I have seen, implementations of AC experiments like EIS on microcontroller-based platforms are few and far between because of the added complexity. I think DC experiments would provide a great starting point for what I'm trying to measure and I will certainly take a look at what can be done in regards to signal generation from the PULSE pin. Do you have a recent version of the Eagle files for the WheeStat 5.4 or is the WheeStat 5.1 board files in GitHub the most recent iteration (other than r8 and r9 being 10k and the 4.7uF capacitor in the RC filter)? I appreciate the help.

Is this a question? Click here to post it to the Questions page.

Reply to this comment...


@bjl1629 Hi, The 5.1 board files are the most recent hardware designs released to the wild. This summer I have been working on new hardware (and software) and I expect to have them finished and rolled out before long. The new hardware (WheeStat 6.0) will be able to push the counter electrode to +/- 12 volts instead of +/- 1.65 volts. The working and reference electrodes will still be limited to +/- 1.65. The reasons for the extended range for the counter electrode are described in this Research Note: http://publiclab.org/notes/JSummers/06-19-2015/booster-hardware-improves-the-usable-wheestat-voltage-range. I have a working 6.0 prototype on a pcb that I etched in the lab and I have three boards on order from OSH Park. Assuming the boards from OSH Park work alright, I will make them available on the OSH Park shared projects site (by the way, you know that you can get the 5.1 pcb from the shared projects, right?). I am also working on a design that will allow the working electrode to run to more extreme voltages. I don't think that many people have applications for a potentiostat that runs past +/-2 volts, but I will probably make one anyway. Let me know if there is anything I can do to help you out. Jack

Is this a question? Click here to post it to the Questions page.

Reply to this comment...


@JSummers Hi Jack, I have been doing some CV experiments with the device. I examined the .csv file and seem to be getting about ~280 data points for a run of about 28 seconds, which means the ADC is sampling the voltage and current read pins at about 10 Hz if I'm not mistaken. Do you know what parameters within the code would have to be altered to increase this rate if it is possible? Also, I would like to try getting the CV experiment to run multiple times from the initial to the final and back and maybe one or two more rounds before the experiment stops. I see the code has a variable for number of runs for data logging parameters and it is set to 1 run, but I'm not sure if increasing this value will make the experiment repeat. Thanks

Is this a question? Click here to post it to the Questions page.

Reply to this comment...


@bjl1629 Hi, This comment addresses the question of sampling frequency and I will discuss the cycling issue in the next comment. The WheeStat is set up to sample on 10 mV steps. If you are using 100 mV / s scan rate, that is where the 10 Hz frequency you observe comes from.
If you want to increase the scan frequency and keep the 10 mV steps, then it is a simple matter of increasing the scan rate (mV/sec) in the GUI. If you want to keep the scan rate at 100 mV/s and increase your sampling frequency, that will require changing the microcontroller code. Somewhere around line 57 in the main tab of the Energia program (it should be called something like WheeStat5_4a.pde) is a line that says "int pwmRes = 330;". That is the voltage resolution. It means that you are breaking up your 3.3 volt working range into 330 steps, each being 10 mV. If you want to increase the resolution by a factor of five, multiply this value by that same factor: "int pwmRes = 1650;". That will give you two mV steps. You will also have to change some code in the setupRun tab. You will need to change the digital values of the initial and final voltages (called dInit and dFnl) to reflect the change in voltage resolution. These are found in the setupRun tab starting around line 58. Find the line that says "dInit = mVinit/10 + halfRes;" and change it to read "dInit = mVinit/2 + halfRes;". Make a similar change to the line a few down that calculates dFnl. You will also need to decrease the stepTime by a factor of five. The stepTime is defined around line 88. Around line 126 in the setupRun tab will be a line that says: "dOff = dOff1 + offAdj;". After that line, add this one: "dOff = 5*dOff;" This line is necessary to adjust the current offset to accommodate the change in pwmRes. Hope this helps-Jack

Reply to this comment...


@bjl1629 Hi, I made a mistake in the above comment, referring to the Energia code as being a pde file. It is actually an ino file. The GUI programs are written in Processing, which are pde files. Sorry for the confusion. Driving the WheeStat to cycle through a saw tooth pattern should be fairly easy, but would be best if done with some modification of the GUI as well as the microcontroller code. I would do this by adding another option to the "mode" dropdown list. Open the WheeStat.pde file using "Processing". In the "Dropdown_lists" tab, on about line 44 add: "mode.addItem("CV_REP",8);" In the main tab, on about line 252 it will say "if(runMode=="logASV"){". Change that to "if(runMode=="logASV" || runMode=="CV_REP"){". These changes will allow you to program the gui to tell the microcontroller to run repetitive CVs (I think). You might also want to make the dropdown list longer so you can see the last option (there is a scroll bar, but that is not as convenient). There is a parameter in the Energia code called "runs" that is transferred from the GUI whether it is used or not. In the Energia code, main tab, at line 72, add "int CV_REP = 8;" In the ramp tab, add the following beginning at line 23 (before "if (mode == CV){"): "If (mode == CV_REP){ if(dInit <dFnl){ for (int j = 1; j<runs; j++){ nRamp(dFnl); pRamp(dInit); } nRamp(dFnl); }

else { for (int j = 1; j<runs; j++){ pRamp(dFnl); nRamp(dInit); } pRamp(dFnl); } }"

I think that should work but I havent tried it yet.--let me know what happens. Jack

Reply to this comment...


Login to comment.

Public Lab is open for anyone and will always be free. By signing up you'll join a diverse group of community researchers and tap into a lot of grassroots expertise.

Sign up