Sourcing and sinking, a bad idea?

I want to sanity check an idea I had before I go and cook pins on my Arduino. Lame ASCII art ahead.

Supposing I had the following:

pin2->LED->resistor->GND

When pin2 is HIGH, the LED lights up. The LED is off when the pin is LOW.

If I do this:

+5V->LED->resistor->pin2

Then when pin 2 is HIGH, the LED is off, and when pin 2 is LOW, the LED is on. This much I have seen elsewhere and tested myself.

Now I get a little crazy. What if I do something like this:

pin2---+LED1--resistor-----pin4
|------resistor--LED2+------|

"+" to indicate the anode of the LED. Bottom circuit connected to the top at the "|".

If I set pin2 HIGH and pin4 LOW, then theoretically, I get a lit LED1 and LED2 is off. If pin2 is LOW and pin4 is HIGH, LED2 should light and LED1 is off. Which means I have reversed polarity.

Time for the first sanity check: Is this a bad idea? Am I going to cook something doing this? How much amperage can I drive this way? Probably not more that the 50mA that the specs say right?

Not to stop with that level of craziness, what if I do something like this:

pin9---+LED1--resistor-----pin4
|------resistor--LED2+------|

Same arrangement, but with pin9 instead of pin2.

Now I can theoretically raise and lower the brightness of LED1 while pin4 is LOW by varying the voltage on pin9 via analogWrite. LED2 will be off of course. And I can do the same with LED2 while pin4 is HIGH (and LED1 would be off).

Does it really work this way? Would this get rid of the need for an H-bridge if I were drawing low enough amperage? How long before I cooked my Arduino?

All those situations you have postulated will work fine. As long as you keep the current draw at of less then 40ma max (not the 50ma you stated) and better yet keep it at 20ma for best long term reliability) you can do all those situations.

If you really want to see some crazy I/O pin manipulation, study Charlie multiplexing. This uses three different 'modes' for a I/O pin, set high, set low, and set as floating input, to allow driving more LEDs with fewer pins then normal methods.

Lefty

OK, that is very cool. Thank you!

I have done some quick googling and based on your hint about the floating input, that is looking like high impedance.

Which I think means I should be able to use that to keep the actual voltage at 0 while I change analogWrite around to accommodate the change in polarity.

I have built the circuit I described and written the following code to test it. What I am seeing is a quick flash as each LED starts from 0, which means maybe I didn't fully understand the input idea.

Can I set the HIGH/LOW value of a digital pin while it is in INPUT mode, so when it is set to OUTPUT it immediately takes on that value?

void setup() {
  pinMode(11, OUTPUT);
}

void loop() {
  pinMode(2, INPUT);
  analogWrite(11,0); 
  digitalWrite(2, LOW);
  pinMode(2, OUTPUT);
  for (int i = 0; i<255; i++) {
    analogWrite(11, i);
    delay(10);
  }
  for (int i = 255; i>0; i--) {
    analogWrite(11, i);
    delay(10);
  }
  pinMode(2, INPUT);
  analogWrite(11,255); 
  digitalWrite(2, HIGH);
  pinMode(2, OUTPUT);
  for (int i = 255; i>0; i--) {
    analogWrite(11, i);
    delay(10);
  }
  for (int i = 0; i<255; i++) {
    analogWrite(11, i);
    delay(10);
  }
}

@Richard: Excellent question.

The scenario with the LEDs is just to test the idea.

I am trying to solve a problem driving an air-core meter. You can read about my problem here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1271537811 .

It is easier for me at least and perhaps others to grasp the concepts with LEDs. Coils seem mysterious. LEDs are warm and friendly.

The hesitation due to the polarity reversal seems to be tied to the L293D. As far as I can tell, it just can't reverse polarity fast enough.

If I can get the Arduino to do the switching directly, quickly and safely, I think I can get rid of that hesitation.

The coils for the meter appear to draw about 13.8mA when fully energized. When testing the resistance with my meter I get about 189.2 ohms. The math with ohms law doesn't quite work out for 5 volts so I am missing something. I hope that if I put a small resistor in there I can use it pretty safely.

The idea is to get as smooth a transition from +5V to -5V and back again as possible.

Sanity check, why would you want to do that?: WELLLLL
Unless you are "Charlie-plexing" or something, there doesn't appear to be any apparent advantage in connecting LEDs (or any other loads) BETWEEN output pins. You have two loads and two pins. So much more straightforward to simply connect each load to its own pin.

This is the normal way to connect a dual (R/G) led so that you have software control over the color. You can also get it to display yellow with this connection.

Don

Certainly. It is called an "air-core meter" (or gauge, movement, or "differential meter", etc). It is what is found in most automotive dashboards, at least ones from the `90s. It is just the meter itself, no additional electronics.

The principle of operation is explained very well in the "Application Notes" in this datasheet: http://eshop.engineering.uiowa.edu/NI/pdfs/00/52/DS005263.pdf , and this one: http://www.nxp.com/documents/application_note/AN1761.pdf and here: http://www.mikesflightdeck.com/diy_aircore_instruments.htm. My meters are the second type, with four leads (SIN+, SIN-, COS+, and COS-) and no common.

The problem with most driver chips (the ones that are still available anyway like the CS8190) is that their zeroing ability is too limited, at least with the meters I have (or at least, I haven't figured out how to make them zero all the way). Most also don't do a full 360 degrees, which is less important, but would be nice, especially to compensate for very off-zero meters.

Lastly, resolution is very important, and most don't have the resolution that the Arduino is capable of (at least with the Timer1 library). 1023 steps over one quadrant would be very nice, and the Arduino should be capable of that, I think.

Anyway, I am thinking that the Arduino should be capable of driving one of these meters without resorting to a specialized chip, since it is just a smooth voltage over a range of +5V to -5V. The tricky part seems to be at the zero crossing when polarity gets reversed. The needle seems to almost stick at those points.

I started off using relays and had the same problem. I upgraded to the L293D as described in the other post, but with similar results.

I figure I must be doing something wrong, but I just can't seem to see what it is. My hope with this post was to remove the L293D and just use the Arduino directly, simplifying things so I could narrow down or hopefully remove the problem.

Richard, I'm not sure I understand the comment

Sanity check, why would you want to do that?: WELLLLL
Unless you are "Charlie-plexing" or something, there doesn't appear to be any apparent advantage in connecting LEDs (or any other loads) BETWEEN output pins. You have two loads and two pins. So much more straightforward to simply connect each load to its own pin.

If each load has a pin, an ordinary Arduino can drive 18 loads (using digital and analogue pins as digital outputs).

With multiplexing using 18 pins, an Arduino can drive 99 = 81 loads.
Using 'Charlieplexing', you get 2x more, i.e. 9
9*2 = 162 loads

Is that not enough justification in itself for using the technique?

As I wrote, I don't understand the comment, so maybe I am missing your point.

GB

I think this is the sort of two colour LED being described.
http://www.rapidonline.com/Electronic-Components/Optoelectronics/5mm-LEDs/Bi-colour-5mm-LED/64855
Some of the kids love them because they are the 'same' LED.
The way I have always driven them is between two pins.
This doesn't gain any loads, unless they are multiplexed, which is then Charlieplexing.

HTH
GB

Ah, yes! As Einstein said

Everything should be made as simple as possible, but no simpler.

In my testing the problem appears to be the delay in switching the polarity of the coil.

I have the coils being driven directly from the PWM pins 9 and 10 now and being sourced or sunk by pins 2 and 4 respectively. My multimeter tells me they are drawing about 20.15mA at their peaks.

In the brief moment when pin 2 or 4 changes from LOW to HIGH or vice-versa the air-core meter jumps instead of hesitating.

Now I suspect the problem is software. During the time when the pin flips from LOW to HIGH or back, I still need the voltage to be as close to 0V as possible. The problem is that at that same time I need the corresponding PWM pin to go immediately from 0 to 255.

I tried setting the digital pin to INPUT, while I change it from LOW to HIGH and change the PWM pin from 0 to 255, but I still see that brief spike in voltage.

A friend told me that what I really needed a differential op-amp, so I am off to learn about those.

My multimeter tells me they are drawing about 20.15mA at their peaks.

Unless that is a very good multimeter, I would assume that it is not calibrated to read a square-wave AC current.

I'd suggest you measure the resistance of the coil, and estimate from ohms law what it's current maximum consumption is. If you are seeing 20mA, that is probably an average, and it may be much bigger.

An inductor should give an effect that looks like a spike as voltage is reversed. It has stored energy in the magnetic field of the coil, and when the voltage is reversed, that energy has to go somewhere. It's a bit like a motor acting as a generator when you try to reverse the voltage across it.

HTH
GB

You might want to consider some protection circuitry if the coil has appreciable inductance. It might be hitting the Arduino with voltage spikes. A parallel diode won't work for a bidirection drive like this, so protection diodes at each pin to the rails might be an idea to supplement the ATmega's on-chip protection.

@gbulmer
How would I tell if the multimeter is of high enough quality to properly read square wave current? Is it still considered AC if there are no zero crossings (at least until the polarity transitions)? The multimeter is an Extech EX330 if that helps any.

The coils individually measure 187 ohms. At 5V that should be about 5V/187ohms = ~27mA. That is above the recommended 20mA, but still pretty well below the 50mA max rating. I think I am OK, since it is only briefly at those points. Am I doing the math right?

@MarkT
I don't think I understand how I can protect the pins with any sort of diode. Wouldn't that limit the directionality of the current?

@Both
In theory the coil should be very close to 0V when the polarity switch happens, so there shouldn't be much current and therefore kickback when the polarity reverses. Theoretically anyway.

I suspect it is because when analogWrite is at 0 and the sinking pin is LOW, no current is flowing. The state I need to get to is analogWrite at 255 and the now sourcing pin to HIGH. Flipping one before the other will briefly set the voltage to 5V until the other flips also.

I thought that setting the source/sinking pin to INPUT would hide that delay between the pins switching, and that I could change the LOW/HIGH state while it is set to INPUT without creating any voltage. But I don't think I can. Or at very least I don't think I am doing it in the right sequence.

Thanks for your help everyone. I really appreciate it.

I don't think I understand how I can protect the pins with any sort of diode.

see:-
http://www.thebox.myzen.co.uk/Tutorial/Protection.html

How would I tell if the multimeter is of high enough quality to properly read square wave current

How much did you pay for it. less that $200 then it is not good enough.

well below the 50mA max

No that's 40mA absolute maximum.

How would I tell if the multimeter is of high enough quality to properly read square wave current? Is it still considered AC if there are no zero crossings (at least until the polarity transitions)?

If a meter doesn't say explicitly that it is set up for square waves, it almost definitely isn't. I had a quick look at the manufacturers spec sheet, and it just says AC. So I'd happily bet a $1 to 1¢ that is is measuring a sine-wave, the sort of thing you'd get from mains, or a transformer connected to the mains. The energy of a square wave of the same frequency is significantly different.
I strongly agree with Grumpy_Mike's algorithm, and I'd read the spec sheet too.

I don't understand how that air-core meter is supposed to work, but for anything containing an inductor, fed with a square wave, I'd expect stored energy to cause it to behave in a complex way*.

I don't think I understand how I can protect the pins with any sort of diode. Wouldn't that limit the directionality of the current?

The diodes go from a pin to ground and 5V (+V) so that the pin can't be driven far above +V or below ground. If you are very careful, choose Schottky diodes as they have a smaller voltage drop.

GB

_* Did you see what I did there? Inductor + square wave = complex behaviour! _
I'm slaying 'em in the EE department ;D

I'm slaying 'em in the EE department Grin

yes only 29 more posts before your a god!

Grumpy_Mike, compared with your productivity, maybe 500 is only a mini-me god :slight_smile:

Hmmm, that gives a thought for a new icon ... :wink: