Skip to content

Instantly share code, notes, and snippets.

@john212
Created July 19, 2016 04:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save john212/ad88f780e4071ffd966b5f3fc11f0422 to your computer and use it in GitHub Desktop.
Save john212/ad88f780e4071ffd966b5f3fc11f0422 to your computer and use it in GitHub Desktop.
Using An Arduino and a LM339 Comparator To Measure an Unknown Inductance
/*
Inductance Meter Using Arduino - by J. Cantlin July 2, 2014
A coil of unknown inductance is connected in an LC crcuit. The
Arduino "rings" the circuit with a PWM pulse from a digital output.
The decaying sine wave from the LC circuit, i.e., tank circuit is
sent to an LM339 comparator where it is converted to a square
wave. The square wave is sent to the Arduino where the "pulseIN"
fuction reades its with in microseconds and converts it to the
resonant frequency of the LC circuit. With a known value of
capacitance, C and frequency f, the unknown inductance L is
calculated using L=1/4(pi^2)(f^2)C.
LiquidCrystal Library - Modified Hello World from Reference Library
The LiquidCrystal library works with all LCD displays that are
compatible with the Hitachi HD44780 driver. There are many of them
out there, and you can usually tell them by the 16-pin interface.
This sketch is used with an Adafruit P-tec P-1602-17 16x2 LCD and
using 4 pins of this character LCD for data.
The circuit:
* LCD RS pin to digital pin 7
* LCD Enable pin to digital pin 8
* LCD D4 pin to digital pin 9
* LCD D5 pin to digital pin 10
* LCD D6 pin to digital pin 11
* LCD D7 pin to digital pin 12
* LCD R/W pin to ground
* 10K potentiometer:
ends of pot to +5V and ground
wiper of pot to LCD Contrast pin (pin 3)
From the Arduino Language Reference:
----------------------------------------
The pulseIn() command is used.
Reads a pulse (either HIGH or LOW) on a pin. For example, if value is HIGH,
pulseIn() waits for the pin to go HIGH, starts timing, then waits for the pin
to go LOW and stops timing. Returns the length of the pulse in microseconds.
Gives up and returns 0 if no pulse starts within a specified time out.
The timing of this function has been determined empirically and will probably
show errors in longer pulses. Works on pulses from 10 microseconds to 3 minutes
in length.
Syntax
pulseIn(pin, value, timeout)
pin: the number of the pin on which you want to read the pulse. (int)
value: type of pulse to read: either HIGH or LOW. (int)
timeout (optional): the number of microseconds to wait for the pulse to start; default is one second (unsigned long)
Returns the length of the pulse (in microseconds) or 0 if no pulse started before the timeout (unsigned long)
----------------------------------------
Open Source Library LCD originally added 18 Apr 2008
by David A. Mellis
library modified 5 Jul 2009
by Limor Fried (http://www.ladyada.net)
example added 9 Jul 2009
by Tom Igoe
modified 22 Nov 2010
by Tom Igoe
This example code is in the public domain.
www.arduino.cc/en/Tutorial/LiquidCrystal
The Inductance Meter circuit and code is based on project and code at:
reibot.org/2011/07/19/measuring-inductance
Originally modified 24 June 2014 by
John G. Cantlin
*/
// include the LCD library code.
// USING HARDWARE INTERRUPTS:
// The attachInterrupt(param1, param2, param3) requires 3 parameters, these are;
// param1 = Which interrupt to listen for. This is the Interrupt Number not the Digital In number
// param2 = Which code function to call, this must be a method that takes no parameters and returns no value.
// For this program, the function is called stateChange.
// param3 = Which condition to watch for, LOW,RISING,FALLING,CHANGE
// Inside the attached function, delay() won't work and the value
// returned by millis() will not increment. Serial data received while
// in the function may be lost. You should declare as volatile any variables
// that you modify within the attached function.
// Interrupts are already assigned to specific pin.
// Do not mix up interrupt number with pin number.
// Uno has two: int0(Pin2), int1(Pin3).
// Mega 2560 has six: int0(Pin2), int1(Pin3),int2(Pin21), int3(Pin20),int4(Pin19),int5(Pin18).
// USING A TFT LCD 128x160 LCD
// The TFT LCD is a ST7735 from SainSmart.com 1.8in TFT LCD 128x160 Pixels
// The connection will be SPI. Hardware pin support for SPI is as follows:
// Uno: MOSI Pin 11/ICSP 4, MISO Pin12/ICSP1,SCK Pin 13/ICSP3, SS Pin 10
// Mega: MOSI Pin 51/ICSP 4, MISO Pin50/ICSP1,SCK Pin 52/ICSP3, SS Pin 53
// Note: MISO not needed for read only LCD, Only one SPI so SS not used.
#include <LiquidCrystal.h> //LCD library for 16x2 text LCD.
#include <SPI.h> //Serial Peripheral Interconn lib for high speed drive of TFT LCD.
#include <TFT.h> //TFT library to drive ST7735 128x160 display.
#include <stdlib.h> //Library for float to integer conversions, e.g. sprintf.
#include <SD.h> //Library for accessing SD card.
// initialize the library with the numbers of the interface pins.
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
// Define pins used with SPI and TFT LCD
// Note pin 51=MOSI pin 52 = SCK assigned in hardware.
// initialize the library with the TFT LCD pins.
#define cs 35
#define dc 36
#define rst 37
#define sd_cs 53
TFT screen = TFT(cs, dc, rst);
// initialize variables used in inductance measurement
// note: the Arduino Uno uses double the same as float i.e.,
// it is still a 4 byte floating point decimal and adds no precision.
double pulse, frequency, capacitance, inductance, microfarads;
// initialize strings char array to print float variables to the TFT screen
char indPrintout[20];
char freqPrintout[20];
char capPrintout[20];
// initialize an interrupt change of state toggle variable.
volatile int state = LOW;
void setup() {
// set up Arduino pin mode assignments
pinMode(5,INPUT);
digitalWrite(5,LOW); //set input to known state.
pinMode(6,OUTPUT);
// Note that even if it's not used as the CS pin, the hardware SS pin
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
// or the SD library functions will not work. Tribal knowledge.
pinMode(53, OUTPUT);
//Assign interrupt 0,1,2 to stateChange function and monitor for ANY Change
attachInterrupt(0, stateChangeK2, CHANGE); //int 0 = pin2 on Mega 2560 Keypad2
attachInterrupt(1, stateChangeK3, CHANGE); //int 1 = pin3 on Mega 2560 Keypad3
attachInterrupt(2, stateChangeK4, CHANGE); //int 2 = pin21 on Mega 2560 Keypad4
// set up the text LCD's number of columns and rows:
lcd.begin(16, 2);
//set up the SD CS assignment and begin the SD function.
SD.begin(sd_cs);
// Print heading message to the text LCD.
lcd.print("L Meter");
delay(100); //initial delay in millisec to read display, lrt circuit settle.
// initialize the screen
screen.begin();
screen.background(0,0,0); // black background.
screen.stroke(255,255,255); // stroke color to white.
// screen.setTextSize(2); // test size. Note: 2 is large.
screen.text("L Meter", 0, 20); //Header msg to TFT screen.
// delay(3000);
// screen.loadImage("parrot.bmp");
}
void loop() {
digitalWrite(6, HIGH);
delay(5); //give some time to charge inductor, delay(in millisec).
digitalWrite(6,LOW);
delayMicroseconds(80); //make sure resonation is measured, delay(in microisec).
pulse = pulseIn(5,HIGH,5000); //returns 0 if timeout in 5000 microsec.
if(pulse > 0.1){ //if a timeout did not occur and it took a reading:
capacitance = 1.032E-6; //insert actual capacitance (ex C1 = 1.032 + C2 = .920) here.
microfarads = capacitance*1E6; //microfarads = dummy variable for printing
frequency = 1.E6/(2*pulse);
inductance = 1./(capacitance*frequency*frequency*4.*3.141592654*3.141592654); //1/4(pi^2)(f^2)C
inductance = inductance*1E6; //convert inductance to uH = microHenrys.
// Call the *dtostrf function to convert the float numbers to char arrays
// for printing to TFT screen.
// *dtostrf (float var, total digits, digits to right of decimal, char array for string)
/*
Ref.: BradsDuinoBlogspot.com.
A call to dtostrf takes four arguments:
1. A floating point value to be converted
2. An integer indicating the minimum width (number of characters) for the output - including the decimal point and any leading minus sign. The output will be padded on the left side with spaces if the overall output is shorter than this value.
3. An integer to specify the number of digits to the right of the decimal place. The output will be padded with zeros on the right, if necessary.
4. An array of chars to hold the converted value. Be sure the array has enough room for all characters in output.
*/
// dtostrf(inductance,20,10,indPrintout);
// dtostrf(frequency,20,10,freqPrintout);
// dtostrf(microfarads,20,10,capPrintout);
}
}
// Interrupt action for Keypad 2 Press
void stateChangeK2()
{
state = !state; //return state to pre-change status.
// Print inductance to 16x2 text LCD.
lcd.clear(); //clear LCD.
lcd.setCursor(0, 0); //move cursor to start of first row.
lcd.print("Inductance uH");
lcd.setCursor(0, 1); //move cursor to start of second row.
lcd.print(inductance,DEC); //DEC means base ten decimal
// Print inductance to 128x160 TFT LCD.
// To send text to TFT: screen.text(text,xstart,ystart).
dtostrf(inductance,16,8,indPrintout);
dtostrf(frequency,16,8,freqPrintout);
dtostrf(microfarads,16,8,capPrintout);
screen.background(0,0,0); // black background, i.e. clear screen.
screen.text("Mr. C.'s L Meter", 45, 0); //Header msg to TFT screen.
screen.text("Inductance (uH)", 0, 25);
screen.text(indPrintout, 0, 35);
screen.text("Frequency (Hz)", 0, 55);
screen.text(freqPrintout, 0, 65);
screen.text("Capacitance (uF)", 0, 85);
screen.text(capPrintout, 0, 95);
}
// Interrupt action for Keypad 3 Press
void stateChangeK3()
{
state = !state; //return state to pre-change status.
// Print frequency.
lcd.clear(); //clear LCD.
lcd.setCursor(0, 0); //move cursor to start of first row.
lcd.print("Frequency Hz");
lcd.setCursor(0, 1); //move cursor to start of second row.
lcd.print(frequency,DEC); //DEC means base ten decimal
// Print inductance to 128x160 TFT LCD.
// To send text to TFT: screen.text(text,xstart,ystart).
dtostrf(frequency,16,8,freqPrintout);
screen.background(0,0,0); // black background, i.e. clear screen.
screen.text("Frequency (Hz)", 0, 40);
screen.text(freqPrintout, 0, 80);
}
// Interrupt action for Keypad 4 Press
void stateChangeK4()
{
state = !state; //return state to pre-change status.
// Print capacitance.
lcd.clear(); //clear LCD.
lcd.setCursor(0, 0); //move cursor to start of first row.
lcd.print("Capacitance uF");
lcd.setCursor(0, 1); //move cursor to start of second row.
lcd.print(microfarads,DEC); //DEC means base ten decimal
// Print inductance to 128x160 TFT LCD.
// To send text to TFT: screen.text(text,xstart,ystart).
dtostrf(microfarads,16,8,capPrintout);
screen.background(0,0,0); // black background, i.e. clear screen.
screen.text("Capacitance (uF)", 0, 40);
screen.text(capPrintout, 0, 80);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment