arduino, PWM to variable resistance to earth

694 views
Skip to first unread message

gazz

unread,
Nov 11, 2013, 12:53:52 AM11/11/13
to notti...@googlegroups.com
Sorry, it's that damn bus dashboard again, 
got the tachograph working lovely, a play with the internal dip switches that set up how many pulses it reads to move the needle so far, and i got it working from 35Hz to 888Hz, for 0 to 125 KMH, 

Now i'm playing with the other gauges, i thought i had this sorted once, but apparently not, 

They are normal air core gauges as found in most pre-2000 vehicles (and some modern ones too as they are so simple) the sine and co-sine coils are connected internally with a resistor so as to only need 3 connections to work it, power in (24V) earth and sender, 

It dosent help that 1 of the gauges works slightly different to the others, with the fuel and water temp gauges, applying power and earth, the gauge does nothing, put the sender connection to earth and the needle goes FSD, 
The oil pressure gauge is the opposite, power and earth and the needle pegs at full, sender connection to earth brings the needle to zero, but that is normal, i just need to invert the signal to the oil pressure gauge in the arduino program.

These gauges work by varying the resistance to earth of the sender connection, if i put a potentiometer with the centre wiper contact to earth, and one of the track contacts to the sender terminal, turning the pot moves the needle (the real senders would be 180 ohms).... basically i need the arduino to simulate the pot/variable resistor.

I've heard of digital potentiometers, but not sure they are what i want, the gauge pulls 70Ma at 24V for fsd, 40Ma at zero, 
The other is to use an opto isolator, but again not sure that will do what i want at the current i need, 

I've tried just using the straight PWM signals via a transistor, but the needle is very notchy showing the pwm steps, and also i can't get the needle to move linearly, so i really need to simulate variable resistance, short of turning a physical potentiometer with a servo. 

jfowkes

unread,
Nov 11, 2013, 4:38:07 AM11/11/13
to notti...@googlegroups.com
Look up "arduino PWM filtering". When you understand it, hopefully you'll see how it applies to you.

Gazz

unread,
Nov 11, 2013, 8:17:16 AM11/11/13
to notti...@googlegroups.com
Gotchya,

i imagine i'll still have the problem on non linearity tho, it's strange,
using a pot, i can get the needle to move perfectly linear, but using the
PWM output, even tho it is 0 - 255 in a ramp, it gets to a certain point
then the needle goes to full, i guess i'm going over the 180 ohm resistance
range or something,

ATM i have the sender connection on the gauge going to the collector of a
2N2222 transistor, emitter to earth, base via a 500 ohm resistor to the
arduino pin,

--------------------------------------------------
From: "jfowkes" <james...@gmail.com>
Sent: Monday, November 11, 2013 9:38 AM
To: <notti...@googlegroups.com>
Subject: [Nottinghack] Re: arduino, PWM to variable resistance to earth
> --
> You received this message because you are subscribed to the Google Groups
> "Nottingham Hackspace - Nottinghack" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to nottinghack...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>


Andy Harsley

unread,
Nov 11, 2013, 8:25:50 AM11/11/13
to notti...@googlegroups.com
Hi Gazz,

Sounds like you're making a lot of progress - good stuff! (Hope to come over and see it sometime!)

Your current issue might be solved by digital to analogue conversion. The new Arduino Due has DACs onboard, but they're expensive (and 3.3V I think). As James says, you can convert the standard PWM from the Arduino into an analogue voltage with a simple low pass filter. Quite a bit of info on the web about it. This article has some scope pictures:

http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/

This is a simpler method:

http://www.avdweb.nl/arduino/hardware-interfacing/super-simple-dac.html

andy

Ken Boak

unread,
Nov 11, 2013, 8:43:53 AM11/11/13
to notti...@googlegroups.com
Gazz

Here's some things you could try - I'm guessing the gauges work like current meters rather than volt meters, so you need to generate a smooth varying current - in the same way a variable resistor will convert a fixed supply voltage into a varying current.

Try using Arduino "Fast PWM"

That should allow you something like 7.6KHz sampling frequency and 9 bit (0-511) range.  

You might want to smooth the raw PWM pulses before the base of the transistor - say using 10K and 10uF as a low pass filter.  The transistor should also be biased so that it is operating in it's linear region.

Follow this link for an example of how to use a function to set up the timers for fast PWM


//  Set up time 1 for PWM   For detail see  http://www.mythic-beasts.com/~markt/ATmega-timers.html

//  timer1_setup (byte mode, int prescale, byte outmode_A, byte outmode_B, byte capture_mode)

 timer1_setup(2,1,2,3,0);       // Fast 9 bit PWM  (2), (allows 15.66kHz operation), prescale =  1 clockdiv, out_mode true on OCR1A (2), out_mode inverted on OCR1B (3) , capture mode = 0

The actual functions needed are :


//-------------------------------------------------------------------------------------
// Set the PWM value to the timers
//-------------------------------------------------------------------------------------

void pwmWrite(int n) {
  
  OCR1A = n;         // set the duty cycle according to input
  OCR1B = n;  
}

//------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------

void timer1_setup (byte mode, int prescale, byte outmode_A, byte outmode_B, byte capture_mode)
{
  // enforce field widths for sanity
  mode &= 15 ;
  outmode_A &= 3 ;
  outmode_B &= 3 ;
  capture_mode &= 3 ;

  byte clock_mode = 0 ; // 0 means no clocking - the counter is frozen.
  switch (prescale)
  {
    case 1: clock_mode = 1 ; break ;
    case 8: clock_mode = 2 ; break ;
    case 64: clock_mode = 3 ; break ;
    case 256: clock_mode = 4 ; break ;
    case 1024: clock_mode = 5 ; break ;
    default:
      if (prescale < 0)
        clock_mode = 7 ; // external clock
  }
  TCCR1A = (outmode_A << 6) | (outmode_B << 4) | (mode & 3) ;
  TCCR1B = (capture_mode << 6) | ((mode & 0xC) << 1) | clock_mode ;
}



I've used this PWM  successfully to control a 100W dc motor down to 1 revolution every 3 hours


Hope this helps


Ken




--

Ken Boak

unread,
Nov 11, 2013, 9:03:51 AM11/11/13
to notti...@googlegroups.com
Gazz,

A few more thoughts, now that I've got my brain in gear:

It would be easy to test if the gauges are ammeter type - they will have a low resistance if measured across their terminals.

To convert to a voltmeter - so you can drive with your raw PWM and a voltage output, you would need to add a resistor in series.

If they need 70mA for FSD, put about 340 ohms in series -and then drive with your 2N2222 just as you have been doing.   For zero deflection   i.e. 40mA you will need to set the PWM value to about 145, so as to lower the effective voltage from 24V to about 13.65V.

If you chose to use the fast pwm, they will drive at 9 bits and 15.6KHz - that should smooth the motion -  without any need for RC filtering and the hassle of transistors in linear mode


Hope this helps


Ken



Gazz

unread,
Nov 11, 2013, 4:35:48 PM11/11/13
to notti...@googlegroups.com
Ahh right,

i remember using the fast PWM code before to stop the coils in the old
gauges from singing (well they still did in fast pwm mode, but the frequency
was out of our hearing range :)

I just added 'TCCR4B = (TCCR4B & 0xF8) | 0x01 ;' to the setup, which set
pins 6, 7 and 8 to fast pwm mode,

but i didn't know about the other part of the code to allow 9 bit working (i
suppose 10 bit is out of the question? as 1024 steps would be silky smooth.

of course when i made the shield with all the transistors on to work the
lights and gauges from 24 volts, i ended up using pins 13, 12 and 11 for the
gauges, not thinking there was a reason i used to use pins 6, 7 and 8
before,

So, first thing i'll do is modify the gauge shield to use the correct pins,
then set timer 4 to fast pwm again, and add the other code to get the 9 bit
resolution... or are the other bits i need to add just a change to the '&
0xF8 | 0x01:' bit?

--------------------------------------------------
From: "Ken Boak" <ken....@gmail.com>
Sent: Monday, November 11, 2013 2:03 PM
To: <notti...@googlegroups.com>
Subject: Re: [Nottinghack] arduino, PWM to variable resistance to earth

Gazz

unread,
Nov 12, 2013, 8:55:13 AM11/12/13
to notti...@googlegroups.com
> It would be easy to test if the gauges are ammeter type - they will have
> a
> low resistance if measured across their terminals.

What would be classed as a low resistance?

There are 3 terminals, positive, earth and sender, i know internally there
are 2 air core windings, one side of one winding is connected to positive,
one sie of the other winding to the sender terminal, and the other ends of
both windings go to the earth terminal, and i believe there is a resistor
across the positive and earth terminals internally,

i measured 512 ohms positive to earth, 280 positive to sender, 230 earth to
sender,

The sender is usually a 180 ohm variable resistor, one end to earth, other
to the sender terminal.

So as it uses a variable resistor to earth to move the needle, do i assume
it is a current based movement?



Andy Harsley

unread,
Nov 13, 2013, 8:41:33 AM11/13/13
to notti...@googlegroups.com
Sounds like you just need to replicate the output of the 3-pin potentiometer which is acting as a voltage divider, although it's resistance is likely chosen to compliment the resistance of the meter, so this may need to be factored in.

A grounded emitter is not the best solution since the output will be non-linear. The emitter has an inbuilt resistance that is dependent on the current, and it'll vary across the output range. For better stability you need an emitter resistor to ground ("emitter degeneration"), but that'd mean you couldn't pull the output signal to ground.

The usual way of dealing with this is to run the emitter to a -ve rail. The collector output can then swing fully from +ve to ground with good linearity. With careful choice of collector and emitter resistors you should be able to match the response from the pot. (Bear in mind that the collector output from a common emitter amplifier is inverted, so your PWM output would also need to be inverted, but that's easy in code.)

An alternative might be something like a cheap 324 op-amp, though it'd need a +ve supply greater than the maximum required output (+2 or 3V probably). It only needs a +ve supply and the output can swing fully to ground, but matching the resistances of the pot would be trickier I think. The feedback would, however, ensure perfect linearity with the input.

andy

Graham S

unread,
Nov 13, 2013, 12:49:34 PM11/13/13
to notti...@googlegroups.com
Gentlemen, if you're reading this then the overseers have allowed me, Graham, a non member, to respond to this post. I've been itching to provide help.

Gazz, your description of the internals of the gauge appears to be in error :-)
I suspect that there is one coil with one end connected to 24v and the other end to earth via an internal resistor.
The other coil is also connected to 24v, but then uses the external resistance of the sender for its earth connection.
When sender resistance equals internal resistance you get equal currents in the coils, which is presumably zero on the gauge.
If I'm wrong, please slap me down. I'm willing to learn. I never heard of air core gauges before now.
The oil pressure gauge is clearly different. Is the internal resistor absent?

Your measurements of resistance indicate that there could be up to 40mA at 12v through the sender. ie- 480mW power dissipation.
Your chosen transistor is only 500mW. I suspect it gets hot and suffers from thermal runaway, giving the 'shooting to max' symptom you described.
You need a beefier transistor, 1W or better, and fit a heat sink.
The emitter resistor described by Andy is also a good idea, it gives negative feedback and deters thermal runaway.
You would have to experiment or take measuremts to figure out what value.
Because of the problems associated with using an emitter resistor I think that a Field Effect Transistor (FET) may be a better choice. It is, after all, a voltage controlled resistor, which is exactly what you need in this situation. I would have to do research before giving advice.

I suggest you replace the Arduino with a variable voltage source and ensure that your transistor works as expected, before twiddling with programs and pins.
Take measurements of current and voltage applied to the sender resistance to determine power dissipation.

Hope this helps. Please report your findings.

Graham

Gazz

unread,
Nov 13, 2013, 5:05:54 PM11/13/13
to notti...@googlegroups.com
Kewl,
thanks to our 'overseers' for letting this post through :)

you know what, i've got most of my info about air core gauges from a site
about making simulated airplane instruments, and i have just re-read this
page http://bellsouthpwp.net/b/o/bobpaige/How%20They%20Work.html
sure enough, it tells me it is current that controls the pointer position,

The coils could well be connected how you say, i only remember from seeing
inside one of my gauges that both the coils are connected to one terminal at
one end, i assumed it was earth, but +ve makes more sense now you point it
out.

The needle moves about 140 degrees, so i guess that's possible with one coil
fully powered, i know that you can drive the coils seperately and get the
pointer to move 305, or even 360 degrees using suitable components, and i do
have the chips to do that, but it needs the gauge taking apart and the coil
wires separating and bringing out the case,

what i am doing with my bus dash a few others are following, and i know they
will not want to open the gauges up to make them work, hence i am trying all
i can to drive the gauges unmodified.


And the power dissipation makes sense now you point it out, thermal runaway
would deffo explain the needles going to max after a certain reading (i.e.
the temp gauge, as the simulated bus engine is warming up, the needle rises,
it gets to around 70 degrees C, and sometime shortly after it'll be at max)

i'll get a few fets and have a play with the spare gauge i have on the
bench,

thanks for the ideas, i'll report back my findings once i've had a play.

--------------------------------------------------
From: "Graham S" <graha...@gmail.com>
Sent: Wednesday, November 13, 2013 5:49 PM
To: <notti...@googlegroups.com>
Subject: Re: [Nottinghack] arduino, PWM to variable resistance to earth

Reply all
Reply to author
Forward
0 new messages