Is this impossible? Stable analog reading of linear tracking resistance strip

robedney

Member
Hi All,

I've been working on a project building a sensor system to read the keys on a conventional manual typewriter (like but differently than usbtypewriter.com). I am specifically building for one model of typewriter, unsupported by usbtypewriter.

I had a great idea (we all know how that goes) at one point. It didn't work, but it's been nagging at me that if I'd known more it might have. The idea: If I simply built a strip with some resistance material and slipped it under the key bars, I could read the resistance (with one analog input) anywhere along the strip when a key bar struck it. The Teensy will happily output a discrete number reflecting the voltage read at any point along the resistance strip. This works. I wrote a sketch (my first dive into Arduino) that took the outputted reading and dropped it through a filter that returned a character equivalent (i.e. if the number equaled +-255 then send "A"). I gave each reading a range to capture to account for bouncy readings.

I initially tested this using a pot as a substitute for the resistance strip. It worked a treat. I got nice, relatively stable readings from the pot that my code translated into characters and sent out. I could "type", albeit slowly, with a potentiometer.
In actual use I never managed to stabilize the readings enough to be useful. I tried "debouncing" in the code, but never got to reliability.

I tried putting a thin layer of foam below the resistance material, thinking that the key bar would bottom out and I could capture the peak reading. No go. It would still throw out readings well above and below the range I was targeting.

I'm not by any means an Arduino programmer or electrical engineer. However, I concluded two things: Analog readings are subject to noise, and because I was targeting a very specific range of numbers for any given key I couldn't get past the spurious readings. Two, the fast mechanical action of the key bar connecting/disconnecting on the resistance strip made for a pretty inefficient switch and just wasn't reliable enough (for an analog signal). In testing, watching the readings as the keys were depressed, I would see the target number but nearly as many spurious numbers well out of any range I could code for.

This seemed like such a nice, simple elegant solution. The resistance strip is electrically isolated from the typewriter, one end is fed ground and the other 3.2 volts from the Teensy. The analog input pin is then grounded to the typewriter body -- and that connection, through all the metal bits -- is reliable. So it works just like a potentiometer -- or, rather, it is a potentiometer. Such a solution could work for any typewriter -- just cut to length, add contacts at both ends and run a program to capture key strokes and calibrate. Alas, it's beyond me.

Here's are the bare bones of the code, minus the various debounce routines I tried. Remember, I'm brand new to this stuff! I've since moved on to building a sensor bar with cascading multiplexers and 43 contact points so it's all digital (no analog) and I know that this will work.

Code for reading resistance strip:

#define cellPin A0

const float mvpc = 4.55;
char myVariable;
float counts = 0;
float mv = 0;
#include<Keypad.h>
#include<keyboard.h>

void setup() {
// put your setup code here, to run ounce;
Serial.begin(115200);
}

void loop() {
// put your main code here, to run repeatedly:

counts = analogRead(cellPin);


Serial.println(counts);

if (counts >0&& counts <28) Serial.println("A");
if (counts >41&& counts <51) Serial.println ("b");
if (counts >64&& counts <74) Serial.println ("c");
if (counts >87&& counts <97) Serial.println ("d");
if (counts >110&& counts <120) Serial.println ("e");
if (counts >133&& counts <143) Serial.println ("f");
if (counts >156&& counts <166) Serial.println ("g");
if (counts >179&& counts <189) Serial.println ("h");
if (counts >202&& counts <212) Serial.println ("i");
if (counts >225&& counts <235) Serial.println ("j");
if (counts >248&& counts <258) Serial.println ("k");
if (counts >271&& counts <281) Serial.println ("l");
if (counts >294&& counts <304) Serial.println ("m");
if (counts >317&& counts <327) Serial.println ("n");
if (counts >340&& counts <350) Serial.println ("o");
if (counts >363&& counts <373) Serial.println ("p");
if (counts >386&& counts <396) Serial.println ("q");
if (counts >409&& counts <419) Serial.println ("r");
if (counts >432&& counts <442) Serial.println ("s");
if (counts >455&& counts <465) Serial.println ("t");
if (counts >478&& counts <488) Serial.println ("u");
if (counts >501&& counts <511) Serial.println ("v");
if (counts >524&& counts <534) Serial.println ("w");
if (counts >547&& counts <557) Serial.println ("x");
if (counts >570&& counts <580) Serial.println ("y");
if (counts >593&& counts <603) Serial.println ("z");
if (counts >616&& counts <626) Serial.println ("1");
if (counts >639&& counts <649) Serial.println ("2");
if (counts >662&& counts <672) Serial.println ("3");
if (counts >685&& counts <695) Serial.println ("4");
if (counts >708&& counts <718) Serial.println ("5");
if (counts >731&& counts <741) Serial.println ("6");
if (counts >754&& counts <764) Serial.println ("7");
if (counts >777&& counts <787) Serial.println ("8");
if (counts >800&& counts <810) Serial.println ("9");
if (counts >823&& counts <833) Serial.println ("10");
if (counts >846&& counts <856) Serial.println ("11");
if (counts >869&& counts <879) Serial.println ("12");
if (counts >892&& counts <902) Serial.println ("13");
if (counts >915&& counts <925) Serial.println ("14");
if (counts >938&& counts <948) Serial.println ("15");
if (counts >961&& counts <971) Serial.println ("16");
if (counts >984&& counts <994) Serial.println ("17");

Serial.println(counts);



delay(500);
}
 
You need a low pass (Google is your friend). A capacitor + resistor on the analog input.

Yup, tried that. As I understand it a low pass filters out extraneous noise. I may not have had the capacitor and resistor values totally tuned in, but I was in the ball park. Remember that I've calibrated the strip to give me readings from 0 to 1024 (no scaling), so I have to let all of that through to the analog pin, as I'm looking for 43 discrete values within that range.

After trying various materials for the strip I ended up making my own by coating a ribbon with a mix of powdered graphite and sodium silicate (believe it or not I had that stuff lying around). This worked quite well. I could get a discrete reading into my software by holding down a probe (connected to analog in) at various places along the strip. It was the fast moving momentary contact of the key bar that blew it out of the water. For amusement purposes (yours, not mine) I also tried some Velostat, which is a flexible conductive plastic that has more or less the right resistance. It kind of worked, and then I discovered that Velostat is pressure sensitive, so that the resistance varies by how hard you press on it. Fun stuff, but all wrong for my application.
 
Low pass filter + fast moving momentary contact seem to be contradicting requirements. I think you would need really good knowledge of the frequencies involved to get it to work, assuming there is enough frequency separation between the dynamics of the key hitting the strip and the analog input noise.
 
I think the problem is connecting the analog pin to the whole typewriter frame - this will pick up a lot of noise due to
its large capacitance to the surroundings (ie pick up loads of mains hum).

I'd suggest using a constant current source into the resistance strip and having the keys and typewriter grounded.
Then the key strike will reduce the active length of resistance strip momentarily and the voltage will dip at the
constant current source and that should be read with an analog pin.
 
I think the problem is connecting the analog pin to the whole typewriter frame - this will pick up a lot of noise due to
its large capacitance to the surroundings (ie pick up loads of mains hum).

I'd suggest using a constant current source into the resistance strip and having the keys and typewriter grounded.
Then the key strike will reduce the active length of resistance strip momentarily and the voltage will dip at the
constant current source and that should be read with an analog pin.

It had occurred to me that the typewriter might be acting like a big antenna -- but I knew very little about analog inputs at that point or the sensitivity to noise. I've since learned a lot! Your idea might just be the ticket. It, if I understand it right, means that the analog pin is only reading the voltage at the constant current source and is more or less isolated from the typewriter. Even though I've moved on to a different idea, I'm going to give that a try. Thanks!
 
Low pass filter + fast moving momentary contact seem to be contradicting requirements. I think you would need really good knowledge of the frequencies involved to get it to work, assuming there is enough frequency separation between the dynamics of the key hitting the strip and the analog input noise.

You may be right. I have just enough knowledge to question the possibility of it all now that I know more. Someone with a lot more expertise than I have, with an oscilloscope, might sort it out.
 
Back
Top