ADC, DSP, Teensy-LC, and USB MIDI

Status
Not open for further replies.

ohnoitsaninja

Well-known member
I'm trying to do this on some teensy-LCs.

I need to measure 3 light-dependent-resistor analog voltages and use the data to predict another number and send it out over usb midi.

The weak point in my project is the ADC code and accuracy. My schematic is currently as simple as can be with just the LDRs hooked up to 10k variable resistors for tuning, fed from the 3.3v line. I program in the arduino IDE and can't find/understand much on teensy ADC prescalers/speed/averaging. I have resorted to filling the almost all available memory with buffers for the ADCs and doing very slow software averaging to get better sensor data. I have used an arduino before to do real time audio sampling and effects, so I know that crazy high speed with acceptable accuracy can be reached, I just can't seem to get it setup on teensy. I can't find clear, working, documentation on how to use the adc prescaler and hardware averaging for teensy-lc.

I have limited knowledge on the analog circuitry front. I'ved tried throwing in some 22pf caps, I know I could benefit greatly from a better external ADC or op-amps but I'd like to make a lot of these and keep costs down. I've done some research into high speed sampling and oversampling, but much of the code samples I try are not compatible (ADCSRA not declared for example) with the teensy. Any help in any aspect of this design would be greatly appreciated.

I don't know enough on how to implement any of this easily, but I believe there to be useful stuff in the CMSIS DSP section that could speed this up. http://www.keil.com/pack/doc/CMSIS/DSP/html/index.html
 
Last edited:
That particular graph has lots of smoothing that doesn't show ADC problems I'm having. The imperfectness of the sin waveform is a mechanical characteristic and not the ADC.

This somewhat hard to understand polar graph does a better job of showing the ADC error. http://imgur.com/T5AfCu3. θ in this graph is an high resolution external measurement of the angle, so the ADC error is the distance between the center and lower/upper ranges of the colored line.
 
Last edited:
There is no scale to the plot, but it looks like you have a very weak signal, and you are not using the dynamic range fully. Maybe increase the gain of your amplifiers.
If the signal is not very weak, something generates lots of noise. Also when I imagine a histogram of the magnitude of the signal, it looks multimodal

Edit: I just see you do not have amplifiers.
You might want to check phototransistors. These have much higher gains. As for the cost, I do not know your specifications, but you can already buy them for a couple of cents.
 
Last edited:
I'm not currently using amplifiers. Is this something that can be done in code or do I just need to fix my analog end with different resistors or brighter LED? Possibly Op amps?

I actually bought some phototransistors but haven't been able to get them to work as well. They have lots of aspects that make them better than LDRs for this application, like LDR's 30ms rise/20msfall time that essentially makes two different graphs depending on which direction the light spins, but because of the built in lens and proximity to the LED combined with cost made LDRs a better option. I couldn't get my phototransistors to work well, the example I found that did work my my sensors (3DU7) required expensive specialty op amps.
 
Last edited:
We seem to be out of sync, so there is some cross posting happening.
Can you verify that you have a weak signal, state the magnitude of the signal.
Also see my previous remark about phototransistors.
As to filtering spikes, taking the median of 10 samples performs much better on outliers than averaging.
 
Reading at 12-bit(max of 4096) my readings currently fall between {{64,367},{16,352},{29,308}} and are then map calibrated to compensate, but yes that is pretty bad. It seems the easy solution to raise that range is to crank up the brightness on my light source but that will have to wait until I make up the next iteration of prototype hardware.

Taking the median rather than the average combined with increased sensor resolution will hopefully fix a lot of my problems, thanks.
 
Last edited:
This sounds like an analog circuit problem. You can do a LOT of work in software to clean up poor quality data, but if possible, you should really first focus your effort on getting better quality signals into those ADC pins.

From your description above, it sounds like you've got the LDR between the ADC pin and ground, and a normal (variable, but not light sensitive) resistor between the ADC pin and 3.3V. Is that right, or have I misunderstood how you've connected the circuit?

Assuming it's connected that way, complete darkness should result in 3.3V at the ADC pin. Increasing light should make the LDR conduct more.

You mentioned you're seeing numbers in the 16 to 367 range, out of 4096. Presumably that means you've used analogReadResolution() in your code? (can you understand how much better we could help if you actually posted your code, a schematic and/or a photo of what you've built....)

16 to 367 on a 0 to 4095 scale would correspond to 0.013V to 0.090V. That's only a tiny fraction of the 0 to 3.3V range of the ADC.

First of all, if you're not already measuring the actual voltage at the ADC pin, start by connecting a voltmeter. That's the very first and most important thing you should do to troubleshoot.... before you write even a single line of code!

If you really are seeing tiny voltages, all less than 0.1V, then you've got to adjust your circuit. Just decrease the value of the other resistor. You can do this adjusting of resistor values and watching the voltage without any software at all. If whatever motion you're measuring is fast, just slow it down or move it manually between brightest and darkest positions. That will allow you to watch the voltage easily with a slow multimeter. There's no point bothering with the complexity of an oscilloscope if you can just put the lights (standing still) in the positions for min and max brightness.

It's unlikely you'll get an resistor value to make a signal that spans the entire 0 to 3.3V range. But you should at least try to get your signal to change by a 1 volt between the brightest and darkest levels.

Please, do yourself a favor and step away from the software. Get the analog signals adjusted well, and carefully verified with testing using a multimeter.
 
Sorry for not posting code but there isn't really anything to the arduino sketch other than analogRead and serial out (pretty much 3x the AnalogInSerialOut example) and the many various failed attempts I've made at filtering/averaging. The graphing code is gigantic, messy, and uses proprietary crapware like the Canon DSLR SDK. I strongly empathize with trying to help someone who hasn't given you enough information, I've been on the other side of that table too many times.

I've setup an lm324n quad op amp as a voltage follower for the 3 sensors and now reading values between {11384,38558},{5400,28384},{5155, 36957} at 16bit res(max 65536), which is a pretty considerable improvement. At this range, whatever jittering I was seeing before has been made insignificant.
Thanks for stopping by and sorry for not disclosing more information. p.s. I think it's awesome how involved you are here, thanks for everything you've done!
 

Attachments

  • cleanr.png
    cleanr.png
    15.4 KB · Views: 148
Last edited:
Glad that you solved it, I'm working on the ADC library for Teensy LC. When it's finished you could also play with the sampling and conversion times. But as Paul said, a better signal in hardware is exponentially better than any software filtering or averaging.
 
I'm quite a bit out of my comfort zone, but I've been looking around for the best way to go about using op amps for my circuit. I think that each sensor should go through an op amp as voltage follower and then also through a second set of op amps as differential amplifiers comparing the 3 combinations of sensors. I've come across a programmable 6 channel op amp for 2.50 on digi-key, how feasible is that as an option, or any other ideas about how to better do it? The lm324n I have seems to work fine, but is the a more specific type of op amp that would be better for this? Any tricks I should know before using the op amp calculators and ordering resistors and better trimmers?

I've implemented a quicksort on the analog samples to find the medians and now have much cleaner data.
Update: I've figured out shortcuts to a lot of the math and am working on cleaning up the code and moving it all over to the teensy!
 
Last edited:
Status
Not open for further replies.
Back
Top