Boost Converter Intro with Arduino

Driving some neon lights.

Let’s say that you’re trying to drive a few Nixie clock tubes, or you want to make a strobe light. A variable high voltage DC power supply from 50-200+ volts may be required. Transformers are terrific, but difficult to find the right one and a pain to wind. Why not use a boost converter? They’re easy and don’t necessarily require a guru for basic operation. This guide is meant for the individual who wants to build a simple boost converter, and may need refreshing on the theory. It will also help determine what parts will be required.

Is this guide right for you?

boost equations

Basic inductor and boost converter equations. D is the duty (0 fully off, 1 fully on)

Boost converters typically get less efficient as they increase voltage out/voltage in ratio. If 100+ volts are required from a 12v source, the load will need to be a fairly high impedance. Don’t expect to run a 60watt light bulb from this boost converter! If precision is required, you may want a dedicated boost converter IC which will do the job better. This guide is intended for educational purposes.

Microcontroller:

I’m going to be using, oh you guessed it — an Arduino for this example! As usual any micro controller will do (3.3v or 5v), but this project requires analog voltage reading. If your favorite micro controller doesn’t have an ADC (Analog to Digital Converter), buy one or you can make your own!

Theory:

Boost converters work by taking advantage of a fundamental property of inductors: inductors use stored energy to maintain current. The key is that the inductor will vary voltage to maintain whatever current was present before the system (circuit) changed. Once the power supply is removed from a charged inductor, it may be easier to think of the inductor as an electromotive force rather than a passive component. Refer to the images to see it a bit more illustrated. Some of the key inductor equations are also listed.

boostbasicschematic

Basic overview. Original image from Wikipedia.

On state – Current can flow through the closed switch. There is a potential difference across the inductor. The fundamental property of inductors tells us that the inductor resists change in current. Initially the inductor current is near zero when the switch closes, but current will ramp up quickly as the inductor charges till the circuit goes into the Off state.

Off state – Current no longer flows through the switch. The inductor tries to maintain current, and it acts as a current source which means that voltage can sway, in this case it flips polarity due to discharge. The inductor voltage will immediately jump up to the voltage of C3 and maintain original current till the potential energy of the inductor is transferred to the capacitor. As the capacitor charges, the inductor will continue to jump up the the capacitor’s voltage, even if it’s much greater than Vin.

The Circuit:

boost converter circuit

Schematic, C1, C2 are 12V. C3, FET1, and D1 must be rated for high voltage output. Arduino shares ground with this circuit. ~12v means around 12v, that’s not a negative.

The mosfet(FET1), diode (D1), and capacitor (C3) will need to be rated for voltages greater than the peak voltage. The mosfet and diode will need to have a current rating greater than the current peak — see equations. The more capacitance the better, and a ballpark number from the capacitor equation isn’t a bad idea. When it comes to duty, I would suggest not going over a .9 (230 duty for Arduino pwm) duty. If you already have a diode you want to use, then use the diode’s max current as the peak current and solve for the duty. This will be the maximum duty without damaging the diode.

Important: Mosfet Driver for the IRFP260N is required. This mosfet’s Gate-Source pins have a capacitor in parallel (downside on all mosfets). This capacitance is significant and will tend to resonate with the Arduino’s signal. This may damage the Arduino, and will dramatically reduce mosfet efficiency.

boost converter circuit

Boost converter circuit.

Frequency: My Arduino sample code will be using f = 31250 Hz pwm. It seems like any higher frequency results in a less efficient system, and 31250 hz is inaudible. This will also be using phase correct pwm – more on this in section 17.7.4 atmega328 datasheet.

Feedback: There are calculations to estimate the high voltage output, but in reality there are many factors which affect this output. I found that a feedback system works better. This feedback will output 5v when C3 is at 255 volts, and output 3.3v at 168V. If the feedback voltage is too high for the ADC, adjust the voltage divider! Look at the TI pdf at the bottom (pdf pg 9).

Selecting parts:

Here are the key components that may need to be purchased. I suggest buying from Jameco or Digikey if purchasing in the states.:

  1. Capacitor – There will need to be a high voltage capacitor – larger the better. I used a 330uF 200V capacitor that I found in an old computer Power Supply Unit. Laptop PSU (usually), computer PSU, and CRT monitors will have decent sized high voltage capacitors. Find an old CRT monitor to dig into! Check myEasy High Voltageguide to safely discharge a CRT monitor. Buy some capacitors here, or here!
  2. Diode – A regular 1N4007, but it’s not recommended and will probably fail! A Schottky diode or some other ultra fast recovery diode is much better. There are some nice diodes in CRT monitors. I’ve used the RL4Z, 5JUZ47, 5VUZ47, all scavenged from CRT monitors. Buy some here, these should work too.
  3.  N channel mosfet – IRFP260N available here or here, rated for 200v, 49A.
  4. Neon Light. With DC, the ground is what lights up!

    Mosfet Driver – I’ll be using the MIC4422YN. The MCP1407  or the UCC27424P should work too. If using more than 12 volts, watch the voltage requirements of these guys.

  5. Inductor – Buy or make your own inductor. I’ve used a 120uH, 871uH, 1000uH, and a 5000uH inductor with this circuit. All work fine. Larger inductors store more energy in its inductance which requires less current. The main drawback is that Equivalent Series Resistance (ESR) is higher with inductors that have many windings. When buying an inductor, watch the current rating!

Code for Arduino:

Simple code: boost code

PID code (Arduino pid library 1.0.1): boost code PID

Download .pde files from Rapidshare (down) – I’ll eventually put everything up on github. I know those pdfs are very inconvenient

Other Notes:

With boost converters, core saturation can be an issue with some designs. Remember that this design charges up a capacitor to 200V! This is dangerous and could be deadly if misused! The inductor is a current source when it’s discharging. Beginners are unfamiliar with current sources so I avoided explaining it like that.

Here’s an example of a dedicated buck/boost converter IC from sparkfun!

Handy References:

It’s always difficult knowing how in depth to go in the guides. My guide was written to get the nooblet up and on his feet. If this isn’t enough I’d suggest the links below. The TI boost guide really goes into detail.

Adafruit boost guide

Smps overview (pdf)

TI boost guide (slva061.pdf)

nixie clock from Jameco schematic
Daycounter Boost Converter guide

Advertisements

Wicked Laser

My initial response.

Green laser with shades to block green light.

Just received my, “Flashlight Sample” from Hong Kong. I guess it’s better than calling it a high power laser and losing it at customs. I’m certainly satisfied with seeing a clearly visible beam in just about any light condition! No smoke required! Using it to cut electrical tape like butter, and popping balloons never gets dull! Shining this thing on the ceiling literally lights up the whole room! The only downside is that there are warnings NOT to look at the dot without eye protection… how can I resist!?

Green laser DPSS.

The legality of high power handheld laser pointers is somewhat murky and will likely change in the near future. It may be a federal crime to shine a powerful laser at the sky (who could resist doing this) since it may hit an aircraft.

How they work:

This is a Diode Pumped Solid State laser (DPSS). The actual diode inside is an infrared laser, and the light gets changed to a green color by a rather interesting, yet inefficient process. Anyway I don’t want this post to be too long, so head here if you want to learn more! I’ve read that cheap DPSS lasers don’t have the IR filter in order to have a higher power output. This must dramatically increase danger since shades probably don’t block IR too!

similar laser

Picture of a similar laser.

Future use:

I plan on putting this bad boy on a robot that will drive around popping balloons, and target tank cut outs made out of black flash paper. Another possible use is to buy a simple line camera and make a laser distance sensor.

Where to buy:

Sellers include Laser Glow, Dragon Lasers, and Wicked Lasers. I would be curious to see how well some of the laser modules from deal extreme work. Maybe I’ll get this guy!

Update:

After a year and some change the laser diode failed. Disappointing since I never went through a set of batteries! That’s a pretty good indication that the laser diode was being driven far beyond its ratings. Be warned when buying from Wicked Lasers!

Easily measuring inductance with Arduino

bidirectional analog to digital - using LM741 as comparator.

So you need to make or measure an inductor, but you don’t have an oscilloscope or signal generator? Measuring inductance with a handful of cheap common parts is certainly possible. I’ve verified this method is accurate with a scope from 80uH to 30,000uH, but it should work for inductors a bit smaller or much larger. There are some contingencies to keep in mind when it comes to measuring inductors — more on this in “Other Notes:

There are three components that you’ll probably have to buy, but they can be picked up at your local Radio$hack: LM399 and two 1uF non polar capacitors – look at the schematic. If you don’t want to shop at radio$hack, there is a list of products at the end that should work.

No Arduino?

There is 1 digital output and 1 digital input, so this will work with most micro controllers. The output works better with a high current and uses ~33mA at 5V. The only thing left is to measure the rising edge to falling edge time on a square wave. You may want to look at the code if you’re unsure about how to enter the equations, you too can measure inductance with a microcontroller!

LM741, LM339 comparison and a picture showing bell like behavior.

A short lesson on the theory:

An inductor in parallel with a capacitor is called an LC circuit, and it will electronically ring like a bell. Well regardless of the frequency or how hard a bell is struck, it will ring at it’s resonating frequency. We will electronically strike the LC bell, wait a bit to let things resonate, then take a measurement. There is some internal resistance so this is really an RLC circuit, and I’ll talk about this more in the math.

Now micro controllers are terrible at analyzing analog signals. The ATMEGA328 ADC is capable of sampling analog signals at 9600hz or .1ms, which is fast but no where near what this project requires. Let’s go ahead and use a chip specially designed for turning real world signals into basic digital signals: The LM339 comparator which switches faster than a normal LM741 op amp, but there will be a schematic for the LM741 too.

As soon as the voltage on the LC circuit becomes positive, the LM339 will be floating, which can be pulled high with a pull up resistor. When the voltage on the LC circuit becomes negative, the LM339 will pull its output to ground. I’ve noticed that the LM339 has a high capacitance on it’s output, which is why I used a low resistance pull up.

Math:

LC equations

Since our wave is a true sinusoidal wave, it spends equal time above zero volts and below zero volts. This means that the comparator will turn it into a square wave with a duty of 50%, and pulseIn(pin, HIGH, 5000); will measure the time in microseconds elapsed from rising edge to falling edge. This measurement can then be doubled to get the period and the inverse of the period is the frequency. Since the circuit is resonating, this frequency is the resonating frequency.

To the left are the equations where f is the resonating frequency, c is capacitance, and L is inductance. Solving for inductance will result in the last equation

Since this is an RLC circuit due to internal resistance, it won’t change any characteristics of the resonating frequency. The RLC will still resonate, but the amplitude will die out. With a low resistance the RLC will tend to latch onto the exact resonating frequency quicker. For you EE’s think of the frequency response of an RLC with low resistance versus high resistance.

Parts that should work:

review the circuit before buying anything. All resistors are 1/4 watt, but anything will work.

LM339

Using LM339 (works better at high frequency)

The Circuit:

Pick whichever circuit is better for you, but the one using the LM339 is better. Both the capacitors are 1uf metalized film, but anything that is non polar will work. It will need to be very close to 2 uF though. You can not use a capacitor that marks which connection is ground. One thing you may notice is that the LM741 is geared for analog computing. This means that it requires a negative voltage on it’s V- pin. If you don’t have a power supply that offers this, use two AA batteries to go 3v below ground as shown. The LM339 doesn’t need this and there is no problem inputting a negative voltage. Remember that the LC circuit will vary above and below ground. Here’s a picture of the breadboard.

Using the common LM741 op amp. D2 is a 1N4001 too.

Code:

Code for Arduino – With large inductors, you may need to increase the timeout on pulseIn() from 5000 to 10000. If you’re having issues with very small inductors – under 200uH – increase the delayMicroseconds() right before pulseIn() to a larger value ~500uS.

Other Notes:

Not accurate enough? If you look at the equation and you’ll see that the capacitor’s tolerance is key. Expect your results to be accurate within ~10% with a 10% tolerance capacitor. What does this mean? Let’s say you’re using a 10% tolerance capacitor, and the Arduino spits out that the inductor is 1000uH. Well this means that the inductor is in between 900uH and 1100uH. Think of a bell curve if you’ve taken a statistics class – most capacitors with 10% tolerance will be under 10%. (pdf)

If you require a very accurate measurement for a system running at a very high frequency, then this method is definitely not for you due to parasitic capacitance, which isn’t taken into account. This method uses low current to measure inductance, so saturation characteristics will be unavailable (measurements will be taken in an unsaturated state.) This won’t be an issue for most people.

There is this wonderful thing called permeability. Filling an inductor with certain materials changes the inductance without changing the coils. This is similar to mutual inductance in transformers. Ever notice how high frequency transformers are made with nearly non conductive ferrite, and 60hz transformers are made with an iron/steel?

Another method that doesn't work well with Arduino.

You could make a metal detector. Inductors that don’t have closed fields — not magnetically isolated — will change their inductance when something with a different permeability than air is near.

If you have access to fast sampling rates, you can use the method on the right too, but it will require a p type mosfet to really pump some current into the inductor and R1 less than an ohm or so, but greater than the equivalent series resistance of the inductor. This method will probably run into saturation issues if the sample isn’t taken quickly, but if you’re smart about it you should be able to get information about the saturation characteristics.

And there you have it! This is the most difficult part to build on a diy LCR meter.

Using the TCS3200 with Arduino or Parallax Propeller.

Image of the TCS3200 chip - from emartee

Working on a project which requires color detection, but you don’t want to bother with making your own color sensor? The TCS3200 is a great sensor offering sampling rates much higher than one made with a photoresistor. The main downfall to it is that the TCS3200-DB package from Parallax is very expensive ~ 80$ and more complicated to calculate spectral response compensation. If you’re up for some fun, make your own color sensor!

How it works:

As you can see there is an array of photodiodes with color filters on top. There are four types of filters – red, blue, green, and a clear filter. You may have noticed that there are multiple photodiodes of each color, and this helps reduce bad readings due to non-uniformity of incoming light.

TCS3200-DB package from parallax

Excluding power, TCS3200 only has 1 output and the rest of the wires are all inputs. The output is a 50% duty cycle square wave with a frequency proportional to the light intensity (irradiance) on the selected filter. There are two pins to divide the frequency of the square wave S0 and S1, and two pins to select the color filter S2 and S3. The chip works from 2.7V to 5.5V, so it’ll work fine with 3.3V or 5V micro controllers.

Wiring:

When using the TCS3200-DB with Arduino: Connect Vdd, V, and +5v to the Arduino’s 5V line, Gnd connects to the Arduino’s Ground. All other wires are on the example program.

TCS3200 Wiring

Program functionality for Arduino:

The program will need to determine if there an object in front of the sensor. If there is an object present, then figure out what color it is. I will be looking at the TCS3200 output’s rising edge to the falling edge, so the less time elapsed means that there is more light. There will be some redundant readings, but this is to help ensure correct detection if anything is moving.

Take a measurement with the LED off, then compare that to a measurement with the LED on (line 53), both using the clear filter. If there was a significant difference then that means that there is an object in front of the sensor. If there wasn’t a significant difference then just return a zero (line 61-64).

Image from TCS3200 datasheet

Take a clear filter reading and compare it with readings of each color filter, both with the LED on (line 67-72). Then do somewhat of a reverse ratio, since smaller means more light, and pick the largest reading (lines 70 – 96).

Now there will be a serial output of all the ratios and this program simply selects the largest. If you need more accurate readings instead of just the primaries, then I suggest divide the ratio with the spectral response found in the datasheet.

Spectral and pinout from datasheet. Note: if you're using the product from Parallax, use the spectral response from their TCS3200_doc.pdf.

There are plenty of comments in the programs below to help the user get started. there is a detectColor(TCS3200’s output square wave pin) that will return a 0 if nothing is in front of the sensor, 1 for red, 2 for blue, and 3 for green. After each reading it will power off the TCS3200 chip and LED.

I don’t fully support the Parallax Propeller, but I did write a simple program to do basic readings.

TCS3200 for Arduino with line numbers

TCS32000 for Arduino without line numbers

TCS3200 with Parallax Propeller (main.spin)

TCS3200 with Parallax Propeller (taosCountLib.spin)

Or download everything from RapidShare

ASEE 2011 Competition

Original CAD.

The goal of this project is to have a robot start on the east wall, navigate the track, collect all red doll rods, and finish touching the original east wall. The key robot rules are: robot must be fully autonomous, total budget is under 450$, the robot must fit inside an 8 x 12 x 10 inch box, and it must complete the task within two minutes. We designed the robot to be similar to an assembly line, so the robot never stops moving. Our robot ended up using a PI controller based on the Arduino PID library.

Front view, doors closed.

The batteries were only changed twice which shows how the project focused on building small modules, and shows how smoothly the final design came together. We ended up not competing due to funding issues with the school, which is why nothing was fully completed or perfected.

Member roles:

  • Moser EE- electronics, programming, control theory
  • Imig EE – electronics, control theory
  • Doxsie ME- CAD design, organization, mechatronics
  • Dulce BioE- general management, organization, paperwork

Design Stages:

The total time for this project was about seven months!

Front view, doors open.

  • Rather than rushing into any decisions, we decided to brainstorm for about two months. This brainstorming allowed team members who weren’t interested to drop out and allowed everyone else ample time to research, think of designs, test sensors, and test algorithms.
  • Next stage was to build a robot that could follow a wall, we had two robots at this time — Arduino and a Propeller based robot. Many complications arose with the propeller robot, so we ended up going with Arduino since it’s simple to use. This stage took about two months.
  • Once the team’s robot could follow a wall, it was time to navigate the course perfectly every time. This stage took about a month. A video oh another!

    Rear, doors closed.

  • The final stage was giving the robot it’s second chassis, and test one door. We then added the color detection modules. This stage took about a month, giving us plenty of time for perfection.

Programming style:

I ended up doing the majority of the programming and I’ll give a bird’s eye view on the concepts of the program.

  • Break the overall program into three stages.
  • Keep everything very modular and break up core robot functions into methods which are reused in all applicable stages.
  • Write the program in a style which contains no time based delays. If a large time based delay is needed, then store the current up time and don’t take action until the stored up time and the current up time differ by whatever the delay needs. There are some exceptions to this, but they’re under ten milliseconds.

The Arduino may do a few hundred loops a second where the actual processor just runs calculations and makes adjustments to registers, it’s not generating signals for the servos. There are large delays when the robot is turning at the corners, or at a time where it doesn’t need to be accurately following a wall and color detecting. We were originally using a compass, but a simple estimated turn is better and saves 30$.

Final ASEE robot source code (pdf) – Since we didn’t go to Canada, the code isn’t pretty.

All connections and currents.

Electronics used:

Picture of wiring. What a mess!

We did use a standard Arduino with an Atmega328. This proved to have enough pins for everything. Our Arduino was the DC BoArduino from Adafruit!

The wheels used continuous rotation servos. Doors were cheap analog servos, color sensors are the same ones that I wrote about earlier…etc. A full list of the final parts is in the pdf below.

Final robot parts (pdf)

Mechatronics:

The doll rods are much easier to work with if they’re knocked over since they can roll. I’ll admit that we used some design ideas from the other team. They didn’t knock over the doll rods and had major difficulties with actually getting the rods into their storage compartment. Their robot was based on dead reckoning, which meant there was no feedback when it came to navigating the track. Although dead reckoning is an easy path to take, it’s not ideal when tolerance is less than an inch. The video below is an older one back before we completed the color sensors. The servo in the next video is a digital all metal gear servo and it’s MUCH nicer than our final servos.

front view from robot showing pid response:

inside the cargo bay (collecting both colors):

Original robot with compass and Sharp IR distance sensor

Why are we not competing?: The tech department is funding the project, and our team is composed of engineering majors. Since we’re not from their department, they weren’t able to drop a few thousand to send us to Canada. It was frustrating since this was not explained until a few weeks before the competition!

Why didn’t we use all the doll rods?: Yes… as you can see we weren’t using all 12 doll rods. This was because the other team that dropped out still had most of the doll rods, and we didn’t have enough extras to fill up the course. We didn’t get around to making more.

One more video!

Color detection with Arduino for under 5$

Let’s say that you’re working on a project and it needs color detection. This guide will help you make a basic red, blue, green color detector that will decide if an object is present – and the color of the object. A range of up to 6cm is possible with proper guidance tubes! Let’s look at some of the options of completed sensors on the market:

The TCS3200 is a great sensor that I’ve used on Propeller and Arduino based projects, but its 80$ per sensor once shipping is paid! For the ASEE robot we needed two of these and our total budget was 450$! Since we purchased a TCS3200,  I decided to reverse engineer it and create my own! It’s a great sensor, but do we really need an adjustable lens with anti reflective coatings? It’s a bit large too…

There are two white LEDs and an array of photodiodes inside. Some of those photodiodes have color filters on them. Pulling certain pins high/low will determine which diode groups are selected — no filter, red, blue, green. The color sensor outputs a square wave and it’s frequency is proportional to the light intensity. There are also frequency multiplication pins which change the proportional constant.

Design:

There are a few different ways to do this, but I’ll cut to the chase and give you what I found to be the best. Let’s use a sensor to measure ambient light, and compare that measurement to measurements with only a powered red LED, blue LED, and finally a green LED. I say ‘sensor’ because there are many different light sensors that will fit the job.

Some of the major pros of this method is that it only needs 3 digital pins and 1 analog pin on the micro controller when using a photoresistor. If you want to use a photoresistor but don’t have analog pins, then use my “Measuring resistance or voltage with 1 I/O” post! This sensor can be built into a very small form factor with decent sampling rates less than 20ms!

Choosing a light sensor – this guide is for a photoresistor:

Choosing the LED:

  • ‘Piranha’ RGB LED – what I used because we had some sitting around looking for a nibble.
  • RGB LED – another LED that would be great.
  • Just use 3 separate bright LEDs

    Schematic: Click to enlarge

The build:

The Piranha RGB LED is a bit different than we might expect. In order to turn on the red LED we’ll need to pull the blue and green pins HIGH, then pull red LOW. Only one LED at a time may be lit, otherwise the LED with the lowest threshold voltage will probably be the only one to light.

This design will use 19mA per sensor. Two sensors may have their LED lines tied together since the Arduino is capable of sourcing/sinking 40mA. Each color sensor’s photoresistor (output) will need a dedicated ADC pin on the micro controller.

Important:

Photoresistor tube is shorter.

Isolate the LED and photoresistor by using white paper tubes wrapped in a layer of electrical tape. Cut the tubes so that they’re

Black tape behind photoresistor

about 2-3cm long and fit one on the LED and put the other on the photoresistor with a black piece of tape stuck to the back of the resistor. You want to block as much light as possible on the back end of the photoresistor.

Improving results:

Here’s a way to get a rough calibration: The wavelength for the Piranha is Red: 630nm, Green: 525nm, Blue: 470nm. Now look at the spectral response for your sensor. We can make software corrections to the measurements at the LED’s wavelength. I would suggest doing a constant multiplication to the reading to get all readings to 100%. The color detection ran well enough that I didn’t need to do this for my project.

In the schematic above a 10k Ohm resistor was picked mostly because that size worked well for me. The resistor value depends on the light levels and the tube length you’re going to be working with on your robot. A longer tube increase range, but decrease overall light values. This will require a resistor around 20k.  Mainly you’ll want to put one of the photodiodes in the tube prior to the build and put it in the environment you’ll be using it in. Here’s a graph that will explain why.

My photoresistors to up to 200k in pitch dark! Graph made with WolframAlpha

Let’s say that we want the sensor to be very directional and view a far ways away. Since the photoresistor is deep inside a tube, it won’t be exposed to much light. Since it’s probably operating past 100k ohms, if the resistance changes to 150k ohms, then the voltage will hardly change at all when using a 10k grounding resistor. Don’t forget that there are only 1024 segments with the on board 10bit ADC! You’ll want to use a part of the graph which has a large negative slope (left side). The right side of the graph will be difficult for the microcontroller to interpret when using small resistor values. A 100k resistor will have a small negative slope, but it’s distributed all over the graph. If you want to adjust the resistance after the project is already done: just add resistance to the ground pin of the sensor. The ground pin connects directly to the 10k resistor, and nothing else uses it. Remember that resistors in series is just the sum of the individual values.

You could also think of this in terms of curvyness, so curvature will be small, then large, then small. Don’t go past the large value for curvyness. Methods exist to calculate curvyness but not necessary. If you’re interested it’s on page 833 of James Steward – fundamentals of calculus 6th ed.

Alternative designs:

You could use four possibly three photoresistors and have colored filters in front of them. Then a white LED to look for reflectivity. This method is more difficult to calibrate, and would require three to four analog pins with one digital pin for the LED.

Code for Arduino:

Color Detection code (pdf)

Measuring resistance or voltage with 1 digital I/O

Let’s say that you’re trying to measure some resistance, but running low on analog pins. Maybe you’re using a microcontroller (aka micro) that’s purely digital, such as the parallax propeller. Well my friends this post is for you! Let’s consider the fact that nearly all micro’s digital pins trigger at 1/2 of the voltage they micro is being driven at. If we slowly increase the voltage of a micro’s digital input, the micro will consider it HIGH at 2.5+ volts for a 5v micro.

If we use a simple charging RC circuit, we can think of the final voltage as 2.5 volts. What if we have the micro discharge the circuit, so we start at about 0v. After the circuit is discharged the micro will turn the pin to input and time how long the circuit takes to charge to 2.5v. Resistance is easily calculated knowing initial and final voltage, capacitance, and time elapsed.

Math:

At the top is the classical, time domain, voltage of a charging capacitor. Vcap is the capacitor voltage, Eemf is the electromotive force (charging voltage), C is the capacitor’s capacitance, t is the time in seconds, and R is the resistance being solved for.

Vcap will be 2.5v when micro triggers, C is .1uF, t is in micro seconds, Eemf is 5v. For arduino, which runs at 5v and digital I/O triggers at about 2.5v. Notice that the 10E-6 cancels out. This is good since Arduino doesn’t have alot of sigfigs to work with during calculations.

Make sure that the time that this circuit takes is reasonable. The time below is in Seconds. Everything else is same as before, R is approximately what resistance is being measured.

variables are same values as above.

Vcap was switched to Vc

Schematic:

As you can see the circuit is fairly simple. The 270Ohm resistor is to limit current the current as the micro discharges the capacitor. The R is the resistance we’re trying to measure.

This circuit is not meant for extremely high sampling rates. If you absolutely need a high sample, then I suggest that you get an ADC chip to do it all for you. Note that if the resistance is high, then you might want to decrease capacitance. If Resistance is very low, then increase capacitance. Only do this if you’re having problems though.

Sometimes the ADC chip is worth it, but if you don’t happen to have one lying around, or if you don’t want to mess around with spi or I2C, then this is a quick work around.

So in this screenshot I had channel 1 (yellow) connected to the capacitor. Channel 2 (blue) connected to a signal pin on the micro. The capacitor’s voltage suddenly drops down when the micro discharges it. When the blue line’s rising edge occurs, that signals the I/O measurement has begun and the pin is set to input. We can then see the blue line’s falling edge occurs when the capacitor’s voltage is at 2.5 volts. As soon as the 2.5 mark is it, the circuit is ready for another sampling. I just had the sampling set to some arbitrary length of time.

Here’s a video of it in action!

Original forum posts

http://arduino.cc/forum/index.php/topic,50642.msg361179.html#msg361179

http://adafruit.com/forums/viewtopic.php?f=25&t=19476

Code for the Arduino:

Any analog references are solely for debugging. Remove them when you are confident everything’s working.

Click to download resistor measurement program (pdf)

Measuring Voltage using this method: I do like the thought of using 1 i/o to measure nearly any range of voltage, but basically if you’re measuring up to 100 volts, then this method will only be able to measure 50-100 volts. This is because the voltage divider will make the 0-100v into 0-5v, and the pin won’t trigger below about 2.5v. This equation was calculated using Thevenin’s theory. It could also easily be solved using nodal analysis, but then we’d have some calculus to do! I feel as though this is impressive to do very accurate voltage calculations, but it’s a bit complicated and doesn’t work over the full range. An op amp could be added to give a wider voltage measurement range, but this is would require additional pins… and the op amp output won’t like charging capacitors!

Well the voltage calculation was off, but fitting the calculated versus real output results in a linear function with slope almost 1. Interestingly it’s off by a constant.

I decided not to investigate why, but it is probably a result of component 10% manufacturing tolerance.

If you decide to give this a shot, then use the top middle schematic with the equation on the very bottom “a” is 2.5 (on the mid left). I suggest you do a function fit of calculated versus real voltage output like I did. Code is extremely similar to the example above. Of course you could just do a function fit for the entire thing since the picture shows the form of the equation.

code for voltage measurement: voltage_measuring_rc