-
Real Results on One Axis!
08/13/2014 at 21:44 • 0 commentsHere's some big news - I've verified that my concept will work! As I've written before, I'm initially testing my touchscreen device in one dimension (along a line), not two (across a surface). This is because the initial circuit I built on a ProtoShield did not give me space to add a third sensor. It's just as well, though, because testing the device in one dimension takes some sources of error out of the equation. In this log I'll show you how I tested the device, what the results were, and where I'll go from here.
This is the spread sheet in which I gathered data and made a chart.
Test Setup
I set up the board comprised of an Arduino, a protoshield with the LPC1114 ARM chip, and some op-amps with the inputs of the op-amps connected to the piezo disc sensors. You can see this circuit in the project's current schematic. I taped some AA batteries on top of the piezo disc and rested the disc on broken-in-half popsicle sticks. Having a relatively large mass on top of the discs with a space underneath allows them to flex more with incoming vibrations and produce a higher voltage. The effect is that they are made more sensitive.
The two discs were placed just over 30 cm apart. Between the two discs I put some tape and marked every two centimeters. The tape will be used for calibration and testing. Here's what the whole thing looked like:
I modified the code slightly so that it printed the difference in times between the two sensors in microseconds, not seconds, and printed them with tabs following them, not carriage returns. These two changes made entering the collected data into a spreadsheet much easier.
Data Collection
Once everything was set up, I started collecting data by choosing a centimeter mark to tap on, tapping on it five times, copying the data from the serial terminal into a spread sheet, and then choosing a new centimeter mark. I did this process for six points along the piece of tape. Here's what I got:
It's important to note that I did NOT do an outliers test like a Q-Test, Modified Z-Score, or similar. That means some of these data might be erroneous. Later on I'll do such an analysis on the data. However, the purpose of this test was to acquire some sore of linear relationship from the data.
To get that linear relationship, I make a scatter plot of the Average vs. Centimeters columns and inserted a trend line. Here's that chart:
As you can see, we got an f(x) equation and an R-squared value. The R-squared value tells us how precise the line fit was - a R-squared of 1 indicates a perfect fit of the line to the data. The .970 we got indicates a strong relationship, which is good enough for me. In science one would typically strive for .990 or better, but this was just a quick test. Any outliers, which were not accounted for, could have caused the slightly low R-squared. The f(x) equation is what we're really after though: it tells us what the difference in delays should be for a given point on the line between the two sensors. With this information, we should be able to determine the point of origin of a specific vibration based on the delays in detection of the piezo sensors.
Pretty cool!
What's Next?
More tests! One test will look at the outliers of a test similar to this one. A test like that would hopefully yield a better R-squared value and a more-accurate f(x) equation. The other test (which will be more fun) will be to write a program to convert a delay printed out by the microcontroller into the location of that vibration's origin. This would be the proof of concept I need before moving on to the 2D version of this device. Stay tuned!
-
A Detour Into Watchdog Timers
08/10/2014 at 03:18 • 0 commentsI'm working on polishing up the code that runs on my board before attempting a full-on test of the system. Remember, you can check out the most recent version of the code here or in the links section of the project page. However, there's been a problem that I haven't been able to get around: the chip just freezes up sometimes. It usually stops in the middle of a printf() call, and since I don't have a fancy debugger, I can't actually see what's going on inside the chip's memory at that exact moment. I suspect the problem is caused when one of the input interrupts is triggered while the chip is writing something out of the serial port. Hard to tell though.
The problem seems to go away upon reset. Since I don't want to include a reset button in the final design (that seems unprofessional), I decided to use a Watchdog Timer. Watchdog timers are found in nearly every modern microcontroller. They are used to reset the chip if the chip halts or gets stuck in a loop. While I had never used one before, it sounded like the perfect thing.
The mbed platform that I'm using doesn't have an official watchdog timer library, but I did find this example program on their site. However, when I loaded it up on my board (modified slightly for where I had soldered my LEDs), I found it didn't work at all. Upon further searching, I discovered that that example was for the LPC1768 which has a slightly different watchdog timer than the LPC1114. The main differences are that the timer control registers a) have different names and b) are in different places. I downloaded the User Manuals for both chips, read through the documentation for the watchdog timer, and about three hours later I had a watchdog timer program that actually worked! You can look it over here.
It's something that I plan on changing in the future because I'm sure it's not perfect, but it does seem to do the job so far. If you are an ARM expert, please feel free to correct anything in that program. I'd love to make it better and maybe eventually into an open-source mbed library. The next immediate step is to integrate it into my main program for my Touchscreen project. I'll keep you posted. Thanks for reading!
-
Making Sensitivity More Sensitive
08/07/2014 at 22:48 • 0 commentsOne of the most important parts of my touchscreen device is the analog circuitry that turns the piezo element outputs into digital inputs for the microcontroller. I'm currently using two op-amps configured as comparators to do this. The way these comparators works is simple: if the input voltage is higher than a given control voltage, the output is low. If the input voltage is lower than the control voltage, the output is high. The control voltage is set using a potentiometer called RV1 on the schematic in my first project log. However, since the control voltage that I've found works best detecting pulses from the piezo sensors is so low, I only use about 15 degrees of rotation of the potentiometer out of the available 270. I've decided to add a new resistor in series with the potentiometer to bring its range of output voltages into an area that closer to what I actually want.
Here's a schematic of the potentiometer as I usually have it set:
The output voltage of a potentiometer wired in a voltage divider configuration like this one is (v0*R2)/(R1+R2). Here, the output voltage is (3.3V*2000)/9000, or .733V. That's the voltage that I would like my modified voltage divider to have as its highest output voltage possible. Here's a diagram of what I would like that new voltage divider to look like:
The trick will be to determine the value R of the added resistor R3. Basically, I want R2/(R1+R2) from the first divider to equal RV1/(R3+RV1) from the second divider. Here goes:
R2/(R1+R2) = RV1/(R3+RV1)
R2*(R3+RV1) = RV1*(R1+R2)
R2*R3 + R2*RV1 = RV1*(R1+R2)
R2*R3 = RV1*(R1+R2) - R2*RV1
R3 = (RV1*(R1+R2) - R2*RV1)/R2
R3 = (9K*(7K+2K) - 2K*9K)/2K
R3 = (81K - 18K)/2K
Giving us...
R3 = 31.5K ohms.
We can double check this with the original voltage divider formula.
V = (3.3V*9K)/(31.5K+9K)
V = .733V. Nice! I love it when it works.
The closest resistor I had on hand to 31.5K ohm resistor was a 33K ohm resistor. That gives a .707V output which I think should be close enough.
UPDATE: I added the new resistor and the math proved correct! I measured the output voltage of the voltage divider with the potentiometer turned all the way up (highest possible output voltage) and measured the output at .732V. Even closer than I expected! Anyway, after using my new extra-sensitive voltage divider in some testing, I determined (empirically) that the best control voltage is 0.081V, or 81 mV. I'll add the new resistor to the schematic soon.
-
Code and Math...
07/26/2014 at 17:29 • 0 comments...Two of my favorite things. In this post I'd like to fill you in on the code I wrote before I started this hackaday.io project and discuss the mathematics that will be used both for testing and for the final product.
Here's a link to the mbed code I'm using on the LPC1114 right now. It's a repository, so it will be updated as I make progress. Here's what it does:
Two interrupts are attached in code to two pins on the chip. These interrupts, when fired, first check whether the other has been triggered by way of the first boolean value. If that interrupt is the first one to fire, it detaches from the interrupt pin, starts a timer t, and sets first to false, indicated that the next interrupt to fire is second. It also sets a reset timer for 0.01s that will reset everything that interrupt has done in case the other interrupt is never fired. This reset function is to avoid hangups caused by invalid interrupt triggerings. If the interrupt fires and finds it is the second to do so, it first stops the timer t and stores its value, then disables the reset timer set by the other interrupt, and sets the boolean value timeAvailable to true.
Wow. That's a confusing read. I promise it will make more sense if you look at the actual code instead. Anyway, that whole part, the really important and time-sensitive part of the program, is all written in interrupts and timers. This allows for speedy, asynchronous execution of the code and (hopefully) very accurate measurements of time. The other part of the program is the main loop. It is written normally (without interrupts) and simple polls timeAvailable to see if there is valid data ready to be sent to the computer. If there is, all the data is sent and the interrupts completely reinitialized. The data sent to the computer will be processed to determine the origin of the vibrations detected by the sensors.
That brings us to the math behind this whole thing: based on a few values indicating the delay between vibrations arriving at sensors, how do we calculate position? At the moment, I've only got two sensor attached to my prototype circuit. This limits us to sensing vibrations in one dimension, or along a line between the two sensors. I'm going to test the setup with just these two sensors for now before adding the third sensor and thus the two-dimensional sensing capabilities of a real touchscreen.
Here's how I derived the equation I'll use position calculation:
That first equation was adapted from a PDF of a pretty dated Navy text on how to navigate by LORAN signals. If you don't know what LORAN is, it was the standard of digital navigation in ships and planes before GPS was available. It actually operates on a fairly similar concept to how my touchscreen will work, but LORAN used radio waves instead of sound waves. You should look it up - it's cool example of older technology.
If you read through my derivation above, you'll notice a constant k. It is used to convert the microsecond values detected by the sensors and microcontroller and sent to the computer into a scale useful for a touchscreen interface. The value k will have to be determined experimentally. I'll get back to you on how I plan on determining k and what it actually is in another log.
Thanks for reading!
-
First Project Log!
07/25/2014 at 23:10 • 0 commentsSince I started work on this project before I started the project page, this post will be to fill in the reader with what I've already done. I decided to use the LPC1114 chip instead of an Arduino (with which I'm more familiar) for a few reasons:
1. Its max clock speed is 50 MHz, about three times faster than an Arduino. Early experiments with my simulated computer version of this indicated that to achieve centimeter accuracy, I would need time measurements on the order to microseconds, so CPU speed is a top priority.
2. It's a DIP chips, which makes prototyping easy.
3. It's an ARM chip, which is something I hadn't used before. ARM chips seem to be the way of the future so I decided to dive right in with one on this project.
4. It has a *built-in* serial bootloader, so programming it is just a matter of hooking it up to an Arduino or similar with a UART.
After doing some research on blogs (these two were the most helpful), I was able to get the LPC1114 running on a breadboard using something similar to the schematic below. I'm using the online mbed compiler which works great and the program lpc21isp to flash the chip via an Arduino.
The other part of the initial design had to capture the vibrations from the piezo elements. Right now I've got the elements taped to a wooden table with their leads going to the connectors P1 and P2 on the schematic below. It took a lot of experimentation to get the current capture circuit. The two elements are connected to op amps acting as comparators with the threshold set by a potentiometer. At first, I had considered using ADC readings and cross-correlation to detect vibrations, but since speed is such an important factor, I opted for the comparator approach which outputs a high or low voltage depending on whether or not the input voltage (from the piezo element) is higher than the threshold. These outputs are connected the LPC1114 microcontroller's interrupts that triggered in the chip's code.
Once I had the microcontroller and the capture circuit figured out, I picked up a protoshield from RadioShack (it was even on sale!) and wired everything up. After a few false starts, I had a circuit that I could program and detected the slightest vibrations with. You can see it in the first picture I've uploaded so far and you can see its schematic right below here:
It's worth noting that while this version has only two op amp comparator units (on the bottom left), the final version will have three. I just couldn't fit the whole op amp on the protoshield :)
So that's the status of the hardware side of things. I'll do a log on the code I'm using in a day or so.
Thanks for reading, skulling, and following!