This circuit reads a capacitive type probe and requires knowledge of the Arduino platform for programming microcontrollers. The software is free and the hardware can be obtained cheaply on EBay. Here
is an example. The microcontroller is an Atmega328 which is cheap and
easily obtained. To save some trouble, you can buy them with the
Arduino bootloader already installed. The bootloader is a subroutine
that lets the chip accept the arduino programming from your
developement board. You can also buy the chips at a cheaper cost and
load the bootloader yourself but it can sometimes be troublesome to get
it to work. I'm retired and have the time to fuss with it so I go ahead
and do that. There is definately a learning curve here but the Arduino
software has a lot of examples. There are a ton of projects on the net
as well. The nice part is it's open source so anybody can use it.
I take bits and pieces from various projects and combine them into
projects of my own. I'm not a programmer by any means but can cut ,
copy and paste just fine. Once you have played with the code long
enough it becomes easier finding your errors if your code is not
working the way you want. In this circuit the microcontroller does all
the thinking and the rest of the components are just for handling the
large amounts of current for the display. The microcontroller can only
source a total of 200ma and this circuit as drawn is drawing about
500ma. The regulator for the display requires a small heatsink. I use
old chassis from various electronic devices for a lot of free parts.
The 2sc945 transistors are found in old tv chassis and capable of
100ma. We are shooting for about 50ma per segment so they are
adequate. You could substitute whatever you want for those. Just make
sure they are good for 100ma or better. The transistors are merely
acting as switches turning the segments on and off as needed. Collector
resistors should be 1/2 watt. They are going to get warm. My DIY
probe is connected directly to the microcontroller. The capacitance
changes as fuel rises or falls within the probe. The microcontroller
reads the capacitance directly from the probe and does not need to
convert anything. It then decides how many segments to light.
Calibration for empty and full are determined by reading some pots.
These chips can be reprogrammed at any time. So if my table of values
is not working for your probe, it will be up to you to change them and
reprogram. The mapped values in the middle of the code is
the spot you are looking to change if necessary. You could do a serial
read of your probe on a computer before installing it and see if it
falls withing range. Look at my You Tube video for this. The Bargraph display can be found Here.
The Arduino code for this project follows. Just copy and paste into
your Arduino IDE software and upload into your chip and you should be
ready to go. const int OUT_PIN = A2; const int IN_PIN = A0; //Capacitance between IN_PIN and Ground //Stray capacitance is always present. Extra capacitance can be added to //allow higher capacitance to be measured. const float IN_STRAY_CAP_TO_GND = 24.48; //initially this was 30.00 const float IN_EXTRA_CAP_TO_GND = 0.0; const float IN_CAP_TO_GND = IN_STRAY_CAP_TO_GND + IN_EXTRA_CAP_TO_GND; const int MAX_ADC_VALUE = 1023; //averaging setup const int numReadings = 10; int readings[numReadings]; // the readings from the analog input int index = 0; // the index of the current reading int total = 0; // the running total int average = 0; // the average //Bargraph setup const int ledCount = 10; // the number of LEDs in the bar graph const int led1 = 2; const int led2 = 3; int ledPins[] = { led1, led2, 4, 6, 7,8,9,10,11, 12 }; // an array of pin numbers to which LEDs are attached void setup() { // initialize all the readings to 0: for (int thisReading = 0; thisReading < numReadings; thisReading++) readings[thisReading] = 0; pinMode(OUT_PIN, OUTPUT); //digitalWrite(OUT_PIN, LOW); //This is the default state for outputs pinMode(IN_PIN, OUTPUT); //digitalWrite(IN_PIN, LOW); // loop over the led pin array and set them all to output: for (int thisLed = 0; thisLed < ledCount; thisLed++) { pinMode(ledPins[thisLed], OUTPUT); } Serial.begin(9600); } void loop() { //Capacitor under test between OUT_PIN and IN_PIN //Rising high edge on OUT_PIN pinMode(IN_PIN, INPUT); digitalWrite(OUT_PIN, HIGH); int val = analogRead(IN_PIN); //Clear everything for next measurement digitalWrite(OUT_PIN, LOW); pinMode(IN_PIN, OUTPUT); //Calculate and print result float capacitance = (float)val * IN_CAP_TO_GND / (float)(MAX_ADC_VALUE - val); int sensorval = capacitance; // subtract the last reading: total= total - readings[index]; // read from the sensor: readings[index] = sensorval; // add the reading to the total: total= total + readings[index]; // advance to the next position in the array: index = index + 1; // if we're at the end of the array... if (index >= numReadings) // ...wrap around to the beginning: index = 0; // calculate the average: average = total / numReadings; // send it to the computer as ASCII digits delay(1); // delay in between reads for stability // read the sensor: int sensorReading = average; //full calibration pot hooks to A4 with rising voltage //empty calibration pot hooks to A5 with falling voltage int MapHi = analogRead(A4); MapHi = map(MapHi, 0, 1023, 160, 200); //map calibration ranges int MapLow = analogRead(A5); //to initial dry capacitive MapLow = map(MapLow, 0, 1023, 10, 40); //measurement of probe // map the result to a range from 0 to the number of LEDs: int ledLevel = map(sensorReading, MapLow, MapHi, 0, ledCount); // loop over the LED array: for (int thisLed = 0; thisLed < ledCount; thisLed++) { // if the array element's index is less than ledLevel, // turn the pin for this element on: if (thisLed < ledLevel) { digitalWrite(ledPins[thisLed], HIGH); } // turn off all pins higher than the ledLevel: else { digitalWrite(ledPins[thisLed], LOW); } if (digitalRead(led1) == 1 && digitalRead(led2) == 0) { digitalWrite (led1, HIGH); //Blink bottom led if it's delay (200); //the only one lit digitalWrite (led1, LOW); delay (200); } } Serial.print("Capacitance Value = "); Serial.print(average); Serial.print(" pF "); Serial.print(" Calibration low = "); Serial.print(MapLow); Serial.print(" pF "); Serial.print(" Calibration High = "); Serial.print(MapHi); Serial.println(" pF "); while (millis() % 500 != 0) ; } Home Page |