This project shows how to build a capacitance meter based on an Arduino board where the value of capacitor capacitance is displayed on a 16×2 LCD screen and on the laptop through serial monitor software (for example Arduino IDE serial monitor).
#include <LiquidCrystal.h> // include Arduino LCD library
// LCD module connections (RS, E, D4, D5, D6, D7)
LiquidCrystal lcd(2, 3, 4, 5, 8, 9);
#define discharge_pin A1
#define channel0_pin A2
#define channel1_pin A3
#define channel2_pin A4
// variables
bool ok;
byte ch_number;
const uint32_t res_table[3] = {1000, 10000, 100000};
uint32_t res, t_mul;
char _buffer[9];
void setup(void) {
Serial.begin(9600);
lcd.begin(16, 2); // set up LCD's number of columns and rows
lcd.setCursor(0, 0); // move cursor to column 0, row 0 [position (0, 0)]
lcd.print("Capacitance =");
pinMode(discharge_pin, OUTPUT);
digitalWrite(discharge_pin, LOW);
// Timer1 module configuration
TCCR1A = 0;
TCCR1B = 0;
TIMSK1 = 1; // enable Timer1 overflow interrupt
ADCSRA = 0x04; // disable ADC module
ADMUX = 0x45; // select channel 5
ADCSRB = (1 << ACME); // comparator negative input comes from ADC multiplexer
ACSR = 0x12; // configure analog comparator & its interrupt (interrupt on falling edge)
ch_number = 2;
}
// analog comparator ISR
ISR (ANALOG_COMP_vect) {
TCCR1B = 0; // disable Timer1
// disconnect all charging pins
pinMode(channel0_pin, INPUT);
pinMode(channel1_pin, INPUT);
pinMode(channel2_pin, INPUT);
// start discharging the capacitor
pinMode(discharge_pin, OUTPUT);
digitalWrite(discharge_pin, LOW);
ok = 1; // process completed
ACSR &= ~0x08; // disable analog comparator interrupt
}
// Timer1 overflow ISR
ISR(TIMER1_OVF_vect) {
t_mul++;
if(ch_number != 0) {
ch_number = 0;
ch_select(ch_number);
}
}
// main loop
void loop() {
// reset everything
TCNT1 = 0;
t_mul = 0;
ok = 0;
// wait for capacitor discharge
ADCSRA |= 0x80; // enable ADC
uint16_t volt;
do {
ADCSRA |= 1 << ADSC; // start conversion
while(ADCSRA & 0x40) delay(1); // wait for conversion complete
volt = ADCL | ADCH << 8; // read analog data
} while (volt > 0);
ADCSRA &= ~0x80; // disable ADC
delay(100);
// disconnect discharging pin
pinMode(discharge_pin, INPUT);
ACSR |= 0x08; // enable analog comparator interrupt
TCCR1B = 1; // start Timer1 with prescaler = 1 (1 tick every 62.5 ns)
ch_select(ch_number);
while(ok == 0) delay(1); // wait for process complete (charging the capacitor)
int32_t _time = 65536 * t_mul + TCNT1;
uint32_t cap;
if(ch_number == 0)
cap = -62.5 * _time/(res * log(0.5)); // cap is in nF
else {
_time -= 385; // apply some correction
if(_time < 0) _time = 0;
cap = -62500.0 * _time/(res * log(0.5)); // cap is in pF
}
if( (ch_number == 1 && cap < 10000) || (ch_number == 0 && cap < 10) )
ch_number = 2;
if( (ch_number == 2 && cap > 12000) || (ch_number == 0 && cap < 500) )
ch_number = 1;
if(ch_number != 0) {
if(cap < 1000) // if cap < 1000 pF = 1 nF
sprintf(_buffer, "%03u pF ", (uint16_t)cap);
else
sprintf(_buffer, "%03u nF ", (uint16_t)(cap/1000) % 1000);
}
else {
if(cap < 1000000) // if cap < 1000000 nF = 1000 uF
sprintf(_buffer, "%03u.%1u uF", (uint16_t)(cap/1000), (uint16_t)(cap/100)%10);
else
sprintf(_buffer, "%u uF ", (uint16_t)(cap/1000));
}
lcd.setCursor(0, 1); // move cursor to position (0, 1)
lcd.print(_buffer);
Serial.print("Capacitance = ");
Serial.println(_buffer); Serial.println();
delay(1000); // wait a second
}
void ch_select(byte n) {
switch(n) {
case 0:
pinMode(channel1_pin, INPUT);
pinMode(channel2_pin, INPUT);
pinMode(channel0_pin, OUTPUT);
digitalWrite(channel0_pin, HIGH);
break;
case 1:
pinMode(channel0_pin, INPUT);
pinMode(channel2_pin, INPUT);
pinMode(channel1_pin, OUTPUT);
digitalWrite(channel1_pin, HIGH);
break;
case 2:
pinMode(channel0_pin, INPUT);
pinMode(channel1_pin, INPUT);
pinMode(channel2_pin, OUTPUT);
digitalWrite(channel2_pin, HIGH);
}
res = res_table[n];
}
// end of code.
I found this article helpful. Best Of Luck. Santonu Dhar, CEO Technosmith
ReplyDeleteNice post. It is helpfull for me.Visit for all technology news!
ReplyDelete