Teensy 3.2 AnalogRead issue with 50k pot

yeahtuna

Well-known member
Teensy 3.2 AnalogRead issue with 50k pot (SOLVED!!!!)

Hi all,

I'm hoping someone could solve or even just explain a weird problem I'm having. The issue is in regards to reading some relatively high impedance expressing pedals with a Teensy 3.2 micro-controller. I've been able to reliably read these pedals with the Teensy 2.0 and the Teensy LC, but for some reason the Teensy 3.2 doesn't like them. The pedals in question are the Moog EP-3 and Yamaha FC7. I know Teensy is optimized for 10k pots, but these pedals perform flawlessly with the Teensy 2.0 and LC, so I'm really hoping to find a way to get them playing well with the Teensy 3.2.

The Problem
There's a 'deadspot' in the analogRead() measurement for the pedals such that the measured value will very predictably 'jump' over a portion of the voltage range.

Please have a look at this video to see what I'm talking about. Note that I say it's a 25k pedal, but it's more like a 50k. See the schematics for the pedals at the end of the post.
https://www.youtube.com/watch?v=DxGnB3oeQsI

The Search
I've been googling my ass off and trying every suggestion I could without luck:
  • added a 0.1uF capacitor (cleans up the high frequency noise, but not the dead spot)
  • hacked analogRead to add some delay between setting up the MUX and reading the value.
  • used the ADC library to slow down the ADC measuring and sampling rates
  • tested with a multimeter to verify that it's not an anomaly in my code
The Band-aid Solution

The only solution I've found so far is to filter out the dead spot in code. While the following code works, I consider it a dirty hack and I don't feel at all comfortable with it. A further complication is that if I adjust the “attenuator” knob of the Moog, the location and size of the dead spot change and I have not figured out how to deal with that.

Code:
#define DEAD_SPOT_SIZE 84
#define DEAD_SPOT_LOW_THRESH 400
#define DEAD_SPOT_HIGH_THRESH 530

int offset = 0;

float filterDeadSpot () {

int val = analogRead(valPin);

if (val <  DEAD_SPOT_LOW_THRESH) offset = 0;
else if (val >  DEAD_SPOT_HIGH_THRESH) offset =  DEAD_SPOT_SIZE;

return (val – offset) / (1024.f - DEAD_SPOT_SIZE);
}

Schematics

schematics.png
As I couldn't find a reliable diagram online, I opened up the EP-3 and checked the pot values and wiring. When I measure the resistance with a multimeter, I get 50k. I don't really understand that as I'm not so hot with electronics, but I've read other places people suggesting it was 50k.
 
Last edited:
Can you make a version which prints to the Arduino Serial Monitor only? And check if the dead spot happens with it? And then post the full code? I'll give it a try here with a 50K pot.

Even if the code seems trivial, sometimes the smallest details matter, which is why we have the "Forum Rule" top of every page.
 
Can you make a version which prints to the Arduino Serial Monitor only? And check if the dead spot happens with it? And then post the full code? I'll give it a try here with a 50K pot.

Even if the code seems trivial, sometimes the smallest details matter, which is why we have the "Forum Rule" top of every page.

Hi Paul,

I did exactly as you asked. Using the schematic from my previous post, the pot read fine. I then built up my circuit a bit and was able to reproduce the issue. Following is the circuit and the code as asked.

Circuit
schematic2.png

Code:
#define POWPIN1 1
#define POWPIN2 0
#define VALPIN1 A1
#define VALPIN2 A0

int lastVal = 0;

void setup() {

  Serial.begin(9600);
  pinMode(POWPIN1, OUTPUT);
  pinMode(POWPIN2, INPUT);
  digitalWrite(POWPIN1, HIGH);

  analogReadResolution(7);
}

void loop() {

 int val = analogRead(VALPIN1);

 if (val != lastVal) {
    Serial.println(val);
    lastVal = val;
 }
 delay(100);
}
 
Last edited:
Oh, this circuitry is definitely not good. At first, I couldn't imagine how this could work at all, but I connected it here, and much to my surprise it does sort-of work.

pot.jpg

Anyway, this is definitely *not* a good way to connect the pot.

To fix this, keep one side connected to ground. Connect the center directly to A0. Connect the other side pin through the 220 ohm resistor to 3.3V (or you can wire it directly to 3.3V without the 220 ohm resistor - but the resistor will prevent shorting out Teensy's power if there's a problem in the cable or connectors). You don't need to connect anything to A1 or digital pins 0 or 1.

When you wire it up this way, I'm sure you see it works *much* better. :)
 
Oh, this circuitry is definitely not good. At first, I couldn't imagine how this could work at all, but I connected it here, and much to my surprise it does sort-of work.

View attachment 6878

Anyway, this is definitely *not* a good way to connect the pot.

To fix this, keep one side connected to ground. Connect the center directly to A0. Connect the other side pin through the 220 ohm resistor to 3.3V (or you can wire it directly to 3.3V without the 220 ohm resistor - but the resistor will prevent shorting out Teensy's power if there's a problem in the cable or connectors). You don't need to connect anything to A1 or digital pins 0 or 1.

When you wire it up this way, I'm sure you see it works *much* better. :)

Hi Paul,

I need to connect it the way I'm connecting it. Again, this circuit works perfectly fine with Teensy 2.0 and Teensy LC. Please give it a try with one of those boards.

Regards,
Rob
 
I don't mean to sound rude, but do you understand how what you're trying to do, or are you trying to do what someone else has done? Can you explain, or post a link to an explanation?

Pat
 
I'm a bit like Paul and dogP here ... the circuit in #3 is a bit confusing .... you want to connect the middle wiper pin to analog Read (check), and not have it connected to a resistor or a power source or a digital pin

And, I see you are using a digital pin driven high as your power source ...why not just use 3.3V ...

your schematic for the FC -7 is correct btw

referring to the schematic in #3 .....The code you have posted shouldn't probably work since it is apparently reading the voltage on the bottom leg of the pot ... you should be reading analog1 / valpin2

powerpin 2 / digital 1 should be output and driven high .... but why not just use 3.3V?

It looks to me like you are reading the pot voltage divider backwards, if that makes any sense? I'm not good with electricity, but I used a slider pot in a project and reading it like I have said worked for me on a teensy 3.1. So it can be done.:D
 
Last edited:
Hi Paul, I updated the code (changed the defines) so that it's doing the analogRead on the wiper as it's supposed to. Could I please trouble you to test again. Sorry for this mistake.

I don't mean to sound rude, but do you understand how what you're trying to do, or are you trying to do what someone else has done? Can you explain, or post a link to an explanation?

Hi, Pat. Yes, I do understand what I'm doing.
 
I see you turn the power on in the setup loop ... digitalWrite (HIGH) etc .... I would just use 3.3v ... but anyway, I wonder if it makes any difference if it is in the main loop? Maybe the digital input is also pulled up automagically (but why is there a digital input on this circuit?? .... that could affect voltages?
 
Last edited:
I already took it all apart and put all the stuff away. My workbench space is small, and many other projects and issues await...

Before I set this up again, perhaps you could try the normal way, where GND and 3.3V feed the outside terminals on the pot and the center goes directly to the analog input pin? Even if you can't use that way for some reason, at least testing that it works properly might help build some confidence? Or if even *that* has trouble, maybe you could post some photos and I'll focus on that first? If I set this up again and do more tests, I'd really like to get this fully resolved, rather than possibly end up on a 3rd round...
 
perhaps you could try the normal way, where GND and 3.3V feed the outside terminals on the pot and the center goes directly to the analog input pin

Hi Paul,

As I said in post #3, that was the first thing I tried and it worked fine--no dead spot. I am quite well aware that I need to be running the analogRead on the wiper, that was a mistake on my behalf and I have changed the defines so that it works properly.
schematic2.png


Code:
#define POWPIN1 1
#define POWPIN2 0
#define VALPIN1 A1
#define VALPIN2 A0

int lastVal = 0;

void setup() {

  Serial.begin(9600);
  pinMode(POWPIN1, OUTPUT);
  pinMode(POWPIN2, INPUT);
  digitalWrite(POWPIN1, HIGH);

  analogReadResolution(7);
}

void loop() {

 int val = analogRead(VALPIN1);

 if (val != lastVal) {
    Serial.println(val);
    lastVal = val;
 }
 delay(100);
}

The code allows me to accurately read the pot on a Teensy 2 and Teensy LC, but there's a dead spot on Teensy 3.2. I use this circuit on products I sell and has led to me purchasing over a 1000 Teensy's from you over the last few years.

Regards,
Rob
 
Does it work if you disconnect from digital pin 0?

Teensy 3.2 has 5V tolerant pins. The 5V tolerance circuit inside the chip, which Freescale doesn't document clearly, appears to have some leakage currents. Those leakage currents seem to vary quite a bit depending on the voltage. We saw this issue with porting the CapacitiveSensor library.

Perhaps that small leakage current is flowing out digital pin 0 and through the pot, causing the voltage to vary unexpectedly. If if you feel you really need that digital pin 0 connection, can you at least try disconnecting it for the sake of troubleshooting?
 
Does it work if you disconnect from digital pin 0?

Teensy 3.2 has 5V tolerant pins. The 5V tolerance circuit inside the chip, which Freescale doesn't document clearly, appears to have some leakage currents. Those leakage currents seem to vary quite a bit depending on the voltage. We saw this issue with porting the CapacitiveSensor library.

Perhaps that small leakage current is flowing out digital pin 0 and through the pot, causing the voltage to vary unexpectedly. If if you feel you really need that digital pin 0 connection, can you at least try disconnecting it for the sake of troubleshooting?

That seems like a very probable cause of the issue. I'll give that a try when I get back to my studio. Assuming that is the problem, is there a solution? Would I risk damaging the board by setting the pin mode of the digital pin 0 to output, low?
 
I am quite well aware that I need to be running the analogRead on the wiper, that was a mistake on my behalf and I have changed the defines so that it works properly.
Ah... okay, that's what threw me off.

What's the purpose of the digital pin on the wiper? I assume it's when you connect that pin that you get the dead spot problem... not the 220 ohm series resistor on Digital Pin 1 or Analog A0 connected to that terminal?

I looked at the MCU datasheet, but I couldn't find a diagram for the I/O pin structure. It's possible that there's some small non-constant leakage current that switches due to the varying analog voltage on the pin. Can you enable the pullup on Digital Pin 0 and see if it makes a difference ( pinMode(POWPIN2, INPUT_PULLUP); )? If you put a voltmeter on the pin, do you see a jump in the voltage at the dead spot (i.e. is the jump real, or an glitch internally)?

Pat
 
What's the purpose of the digital pin on the wiper?

I don't really want to talk about the purpose of the circuit. I have invested countless hours of research and development into my designs that I can't practically patent, so I need to try to keep it a trade secret.

Can you enable the pullup on Digital Pin 0 and see if it makes a difference ( pinMode(POWPIN2, INPUT_PULLUP); )? If you put a voltmeter on the pin, do you see a jump in the voltage at the dead spot (i.e. is the jump real, or an glitch internally)?
I have tested with a multimeter and the jump shows up there, too. I will test with putting that POWPIN2 in different modes and see how it affects performance. If memory serves, setting it to INPUT_PULLUP will negatively affect the accuracy of the analogRead(), but it's worth checking out. Having spent the last 5 months on the development of a new product, $2000 on chips, and $600 on circuit boards, I think I'll try pretty much anything at this point. Thanks for the suggestions.

Regards,
Rob
 
Ah... gotcha. Assuming some sort of calibration, the pullup shouldn't really affect the accuracy... though it will have an effect on the absolute reading. According to the datasheet, the internal pullup (and pulldown) resistors are equivalent to between 20k-50k resistors... so with a 50k pot, a ~35k pullup will drag the actual voltage of the analog input up a bit. But it should stay relatively constant.

Another thing to try would be to change to a different pin. Digital pin 0 is shared with UART RX1 and a touch sense pin. That could give it a different input structure than say pin 2, which looks to be shared with no peripherals.

Pat
 
So, I tested the circuit without Digital Pin 0, and the circuit works as expected--no dead spot. Unfortunately removing that digital pin is not an option for me. I also tried changing the pinmode to INPUT_PULLUP. That did not remove the dead spot and also made the measurement very noisy and non-linear. I also tested setting the pin to digital output, low, and that didn't really work either.
 
Ok, I just wired this up again, and I ran the code from msg #13.

I was not able to reproduce the problem. It appears to work fine. I recorded a 8 minute video, so you can see what I see here while doing the test.

If there's an issue with leakage currents, it's extremely small and I wasn't able to observe any effect. We did have a noticeable leakage current effect with CapacitiveSensor, but that's slowly charging a capacitor through a 10M resistor, not a 50K pot.

I also tested with Teensy LC while the video was uploading to Youtube. It seems to perform exactly the same. Both seem to work perfectly fine.

Youtube is still processing the video. Will post it in several minutes when the link becomes available.
 
Ok, here's the video. As usual with youtube, it's available initially only at low res (360p) and after an hour or so they make the HD 1080p option available.

 
It is possible you might have had the wires or variables swapped? When I tested the first version, it showed *exactly* the problem you described. As you can see in the video, it seems to respond properly when wired up correctly. I can't seem to see any interference or sudden jumping.

This code and the diagram where 0 and 1 swap is error prone. Digital pin 0 and analog A1 for one terminal, digital pin 1 and analog A0 for the other, and then they become 1 and 2 in the code, is pretty confusing. Each time I wired this up, I had to check it a few times to make sure I really followed the diagrams as drawn (and hopefully you can see in the photo and video how I wired this up). Getting this wired up wrong from this documentation could be a really easy mistake to make.
 
Oh, it was still "draft". I just changed to "unlisted". Can you see it now? If not, I could change it to public.... but honestly, this is probably the most boring video I've ever shot, so would prefer not to spam my youtube subscribers if possible.
 
Your video shows the jump at 2:56 seconds....you even say that you saw it. in order to see the jump again, you will need to turn the pot back down to under '40' in the serial monitor...I was on the edge of my seat, btw :)
 
Last edited:
Back
Top