Tags

,

Simpson DOHI came to the conclusion in a previous post that the unexpected behavior I was observing while testing the EC rectifying circuit was due to a slight voltage surge that occurs when the circuit for the multiplexer was chosen.

D’OH Wrong.  

The capacitor was not being discharged.  There was no surge.  I wasn’t using the FET correctly to discharge the capacitor prior to taking a Vin+ or ECVout measurement.  This seems like such a basic concept.  In fact, it alarms me that I didn’t reason this out…

Thanks To Those That Went Before

I constantly find myself mentally pounding my head on a table at how little I comprehend about electronics.  These on going investigations continue to shine a light on concepts I thought I understand but in reality were not grasping.  I have been blessed to get guidance and a boost of confidence from Chris Gammell – both through his Contextual Electronics courses and mentoring.

Open Source

  • Updated kicad files for the Ladybug Shield Alpha V2 that I sent to OshPark the other day are located at this GitHub repository.
  • Arduino sketch used to test the circuit available here.

The Circuit

Here is an image of the rectifying circuit:

IMG 3274

the negative feedback of the 1st op amp is not tied to VGND.  This is a visual representation to remind me the op amps, capacitor, and gate are relative to VGND.

And an image of the test circuit:

IMG 3294

Tests

Analog

I am evolving my skills at testing circuits.  The key – and perhaps obvious – thing I was not doing was evaluating the input and output at the same time.  This is common practice with software.  Is the input unexpected, why?  If the input is expected and the output is unexpected, why?  Can the input and output be further isolated to an interaction/result somewhere closer to the input?  

I was analyzing the input and next analyzing the output using one probe.  This works well when analyzing numbers, but not so well when analyzing analog circuits.  Much better is to overlay the input and the output.  As shown in the image above, two probes is and will be a necessity when debugging analog circuits.  Oh – right – two probes are on my scope for a reason :-).

The result?  Repeatable observance of a higher voltage and s l o w discharge at the node where the capacitor is located.

Digital

I wrote an Arduino sketch that calculates the digital value for Vin+ and ECVout.  Recall Vin+ Vpp ~= 500mV.  ECVout is the gain using a 200Ω resistor to simulate an EC probe value.

I use three i/o pins on the Arduino:

  • enable to multiplexer
  • tell the multiplexer to switch between sending in the Vin+ and ECVout waveforms
  • turn on the FET’s gate

The Arduino pin that I was using incorrectly was the sequence of turning on/off the FET so the capacitor is discharged.  What I now do is a discharge of the capacitor before the first reading and immediately after subsequent readings.  Discharging the capacitor means turning on the FET  (gate = HIGH), then immediately turn off (gate=LOW).

The Arduino Sketch

The sketch I used is located at this GitHub location.  Here is a sample result in a sea of runs I made:

| Count: 1000** Vin+ ** Average: 251.22| Std deviation: 2.12

| Count: 1000**  ECVout ** Average: 1576.48|  Std deviation: 2.04

Gain = ECVout/Vin+ = 1576.48/251.22 = 6.28 = 1 + 1K/R(EC)

Where 1K is the feedback resistor of the second op amp (R17 in the Ladybug Shield Alpha V2 schematic).

The simulated resistance (R(EC) ) = 1K/(G-1) = 1000/5.28 = 189Ω.

“close enough” to 200Ω.

Here is the sketch I used:

#include <Statistic.h>
#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1015 ads1015;
const byte FET_pin = 8;
const byte mux_out_pin = 7;
const byte mux_enable_pin = 6;
const byte LSB_multiplier = 1;// 2x gain +/- 2.048V 1 bit = 1mV
Statistic myStats_Vin; //from http://playground.arduino.cc/Main/Statistics
Statistic myStats_ECv;
void setup(void)
{
Serial.begin(9600);
pinMode(FET_pin,OUTPUT);
pinMode(mux_out_pin,OUTPUT);
pinMode(mux_enable_pin,OUTPUT);
digitalWrite(FET_pin,LOW); //start with FET as open circuit
digitalWrite(mux_enable_pin,HIGH); //disable multiplexer

ads1015.begin();
//Vpp a bit over 2V
// ads1015.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV
ads1015.setGain(GAIN_TWO); // 2x gain +/- 2.048V 1 bit = 1mV
// ads1015.setGain(GAIN_FOUR); // 4x gain +/- 1.024V 1 bit = 0.5mV
// ads1015.setGain(GAIN_EIGHT); // 8x gain +/- 0.512V 1 bit = 0.25mV
// ads1015.setGain(GAIN_SIXTEEN); // 16x gain +/- 0.256V 1 bit = 0.125mV
showHelp();
}
void loop()
{
// Handle serial commands
serialHandler();
}
void serialHandler() {
char inChar;
if((inChar = Serial.read())>0) {
switch (inChar) {
case ‘i’: // take ECVin+ reading
case ‘I’:
readECVin();
showHelp();
break;
case ‘o’: // take ECVout reading
case ‘O’:
readECVout();
showHelp();
break;
case ‘?’:
case ‘h’: // Display help
showHelp();
break;
default:
break;
}
}
}
#define VIN 1
#define ECV 2

void readECVin()
{
Serial.println(“readECVin”);
myStats_Vin.clear(); //explicitly start clean
Serial.println(F(“Enter number readings: “));
while (Serial.available () == 0) {
;
}
unsigned int num_readings = Serial.parseInt();
Serial.println(num_readings);
int vIn_value = readVIn(num_readings);
Serial.print(F(“| Count: “));
Serial.print(myStats_Vin.count());
Serial.print(F(“** Vin+ ** Average: “));
Serial.print(myStats_Vin.average());
Serial.print(F(“| Std deviation: “));
Serial.println(myStats_Vin.pop_stdev());
}
void readECVout()
{
Serial.println(“readECVout”);
myStats_ECv.clear(); //explicitly start clean
Serial.println(F(“Enter number readings: “));
while (Serial.available () == 0) {
;
}
unsigned int num_readings = Serial.parseInt();
Serial.println(num_readings);
int vIn_value = readECv(num_readings);
Serial.print(F(“| Count: “));
Serial.print(myStats_ECv.count());
Serial.print(F(“** ECVout ** Average: “));
Serial.print(myStats_ECv.average());
Serial.print(F(“| Std deviation: “));
Serial.println(myStats_ECv.pop_stdev());

}
int readVIn(unsigned int num_readings)
{
digitalWrite(FET_pin,LOW); //stop draining
digitalWrite(mux_enable_pin,LOW); //enable multiplexer
switchTo(VIN);
for (int i=0;i<num_readings;i++) {
int results = readADC();
myStats_Vin.add(results);
}
digitalWrite(mux_enable_pin,HIGH); //disable multiplexer
// digitalWrite(FET_pin,HIGH); //start draining
return myStats_Vin.average();
}
int readECv(unsigned int num_readings)
{
digitalWrite(FET_pin,LOW); //stop draining
digitalWrite(mux_enable_pin,LOW); //enable multiplexer
switchTo(ECV);
for (int i=0;i<num_readings;i++) {
int results = readADC();
myStats_ECv.add(results);
}
digitalWrite(mux_enable_pin,HIGH); //disable multiplexer
// digitalWrite(FET_pin,HIGH); //start draining
return myStats_ECv.average();
}
int adcReading(unsigned int num_readings)
{
discharge(); //discharge capacitor before taking readings
for (int i=0;i<num_readings;i++) {
int results = readADC();
discharge(); //discharge after a reading
myStats_Vin.add(results);
}
return myStats_Vin.average();
}

void switchTo(const byte waveform)
{
Serial.println(“Switch”);
if (waveform == VIN) {
Serial.println(“Reading Vin+”);
digitalWrite(mux_out_pin,LOW); //ECVin+ when pin is low.
}
else {
Serial.println(“Reading ECv”);
digitalWrite(mux_out_pin,HIGH); //ECVout when pin is high.
}
Serial.println(“Settle…”);
delay(1000);
}
void discharge()
{
digitalWrite(FET_pin,HIGH);
//delay(5000);
digitalWrite(FET_pin,LOW);
}
int16_t readADC()
{
int16_t results = ads1015.readADC_Differential_VGND(0)*LSB_multiplier;
Serial.println(results);
return results;
}
const char helpText[] PROGMEM =
“\n”
“Available commands:” “\n”
” ? – shows available comands” “\n”
” i – take ECVin+ reading” “\n”
” o – take ECVout reading” “\n”
;
/*———————————————————–
show command line menu
———————————————————–*/
static void showHelp () {
showString(helpText);
}
static void showString (PGM_P s) {
for (;;) {
char c = pgm_read_byte(s++);
if (c == 0)
break;
if (c == ‘\n’)
Serial.print(‘\r’);
Serial.print(c);
}
}

The End

Well, while I would have hoped I would have figured this out a while ago, the good news is persistence pays off. Hopefully in the future I will be able to better reason and debug analog issues. Although much continues to illude me.

Thanks for reading this far. Please find many things to smile about.

Advertisements