Created
July 19, 2016 04:15
-
-
Save john212/ad88f780e4071ffd966b5f3fc11f0422 to your computer and use it in GitHub Desktop.
Using An Arduino and a LM339 Comparator To Measure an Unknown Inductance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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