5v to 3.3v analog translation

Status
Not open for further replies.

noisymime

Active member
I'm about to start porting a project of mine (http://speeduino.com) for the Teensy 3.5 and looking at making an adapter board that will allow the Teensy to plug into existing shield boards designed for the Mega 2560. For the most part this is relatively straightforward, but one area that does need more than simple physical connections are the 5v analog signals. Because this is going onto existing boards that are all operating at 5v I cannot simply change the source voltage for the inputs to 3.3v or anything like that.

To put it simply, is there any reason why a simple voltage divider is not suitable for something like this? The total impedance of the circuits with the divider will not exceed 20k, which I think should be fine for the Teensy, and the boards these are plugging into already have sufficient caps and transient voltage protection (I can be confident that input voltage will never exceed 5.1v at most). The readings will all be translated into an 8-bit range (ie 0v to 5v -> 0 to 255) which is then used against a calibration table, so the code itself should be trivial provided the signal itself is brought down to 0v-3.3v and not just cut off etc.

Is there anything I'm missing here that I need to be worried about?
 
I once made boards similar like what you want to do, but on a regular Arduino One footprint: http://www.epyon.be/2014/05/04/teensy-arduino-crossover-tax-shield/

The problem with using regular voltage dividers is that if you use too high impedance the ADC load capacitor can charge too slowly. Because your project is called 'Speeduino', this maybe an issue :) . If you use to low impedance, this might effect the measured circuit.

One easy way to solve this problem is to place a rail-to-rail unity gain opamp after a high impedance resistor divider. This way the circuit is not affected by the measurement and your ADC capacitor is loaded instantly because the opamp can provide sufficient current.
adc_opamp.png

I personally like the MCP6402T, but the LMV358D is equally as well and easier to solder by hand.
 
Last edited:
Thanks for the reply, and the diagram!

That was certainly the other option I'll look at if needed. Whilst the K64 datasheet does recommend the use of a 0.01 μF cap and talks about being able to change the sample time for higher impedance inputs, it doesn't specify a maximum or even recommended impedance anywhere that I can see. I would've thought the 20k or so I'm looking at with the divider will be OK, but it would be nice to be able to confirm.

I haven't sat down yet and done any benchmarking, but you'd be hard pressed to be slower than the AVRs for ADC reads. I force the ADC sampling on the AVR to run at 1Mhz, which is the max the datasheet recommends and even then it's still slow in comparison. From what I can see in the datasheet, the very slowest the ADC clock on the K64 can run at is 15Mhz.
 
Last edited:
Your maximum sample frequency will be dependent on how much current the source can supply to charge the S&H capacitor and external capacitor. Maybe this application note can be informative. I think the K66 also has a SAR ADC?
 
I once made boards similar like what you want to do, but on a regular Arduino One footprint: http://www.epyon.be/2014/05/04/teensy-arduino-crossover-tax-shield/

The problem with using regular voltage dividers is that if you use too high impedance the ADC load capacitor can charge too slowly. Because your project is called 'Speeduino', this maybe an issue :) . If you use to low impedance, this might effect the measured circuit.

One easy way to solve this problem is to place a rail-to-rail unity gain opamp after a high impedance resistor divider. This way the circuit is not affected by the measurement and your ADC capacitor is loaded instantly because the opamp can provide sufficient current.
View attachment 8296

I personally like the MCP6402T, but the LMV358D is equally as well and easier to solder by hand.

Would you still put a current limiting resistor between the op-amp and teensy ?
 
No, you should never do that with an analog input. A series resistor is an easy way to provide some form of current limiting for digital pins which have low impedance, but for analog pins this makes no sense because they are high impedance.

For analog inputs you can worry about overvoltage, but in this case this is not required because the opamp is fed with the 3.3V generated by the Teensy and so can never exceed the maximum voltage of the analog input.
 
Thank you. I did not know that with analog but makes a lot of sense the way you worded it. Thank you again for your schematic.
 
A resistor and 10n cap are usually useful in cleaning up noise for Teensy pins along with the small load created when the Teensy samples the pin. Also a limiting resistor is handy if your powering your op amp from a higher voltage then the Teensy.

I have yet to see an op amp driving an analog signal to an MCU directly where I work, but we only design for 1-600KW motors......
 
So, I've just about got my adapter board finished off. Ended up using a pair of LMV324LIDT quad op amps, basically exactly how Epyon describe, so thanks for the input!

Will report back when I've got an engine up and running, providing everything works on the adapter :)
 
Totally forgot to report back on this one, but I've got my adapter board all finished off and working. It's not 100% in terms of pin coverage of the Mega, but it uses all of the through hole IO on the Teensy, which is really all I trust for this setup.

The board gerbers are viewable at:
http://gerblook.org/pcb/JgvCbLTWkNMmZjByMxoPyB

Here's a quick video of the Teensy running my MX5 as a drop in replacement for the Mega:
 
Long time follower of your project. Nice to see you moving up to Teensy 3.6. I studied your code in the past. Very nice job. I completed a Teensy 3.6 project (hydraulic 4 wheel steering) which receives Canbus data from a Megasquirt. I actually used TunerStudio to display real time steering data and modify the EEPROM data to tune the steering computer. It really reduced development time.

Fyi There are several ADC libraries available with many options for The Teensy 3.6. Frankly using many tips and tricks from many threads on this forum is a must to reduce jitter on the internal ADCs. I experimented with external ADCs which gave me stability, but communication to the ADC via I2C dropped out after period of time. While I could easily recreate the problem in a minimal code test program I never posted it to the forum for help as time constraints were too tight.

So to read each wheel position I bought 4 absolute Postion encoders @ $420 ea.
Coupled those with 4 transceiver chips then bit banged the interface. Perfect 4096 resolution rock solid. Up and reading all 4 wheels on breadboard in a day. I only had one speed bump I actually ordered the encoders with Gray code output (YEA that is a thing). Solved by 4 lines of bit manpulation.


One think you will find useful is the built in FPU. I actually compute ackerman steering angles while the wheels are turning live rather that using previously computed look up tables as I did with Teensy 3.2.

Btw. Brian @ EFI Analytics is my son.

Mark
 
Any idea what the issue with ADC via I2C would have been? I was thinking of using the Teensy 3.5 and some ADS1X15 ADC to read 0-5v analog sensors, however using this mega adapter board would be ideal.
 
Honestly I do not know what sort of I2C communication problem I ran into at that time. I would not worry about it though, the teensy handles I2C fine. Maybe I was just polling the external Adc too fast. I just did not have the time to debug. So I solved the problem digitally by switching to absolute encoders. I just did not want any jitter, so I abandoned analog. I was using the adafruit breakouts for adc at the time.
Mark
 
Status
Not open for further replies.
Back
Top