Tip:
Highlight text to annotate it
X
This is the third in my let's learn let's code series. The first three were
based around how to do NTSC video output using an AVR...
both the basics uh... right here if you want to click on a few check it out
and chroma how to actually code chroma into the signal without any real special
hardware just an AVR
so uh... if you're interested, you can click on either of these now, otherwise we're gonna go on with
capacitor sensors - these are the same sort of touch sensors using a number of
projects including the MAGFest badges we're actually going to be using two to
set all this up if you want you can click right there
as well as the number of other projects and even uh... this is the same sort of
system I use in my glass
circuit boards that are touch sensitive if you curious about that
click right here - ok so
the basics are you have a finger
and you have a sensor and you want to know if the finger is touching the sensor.
And we're gonna have some magic
this is what we're gonna talk about and what we're going to do and by the end of
this if you have some experience of AVRs you might even be able to
do this magic yourself
so let's see where the different forms of touch sensors
so we have resistance based which means that you have two terminals
and if there's resistance between the two terminals than all of a sudden
blamo! you know that somebody's touching it
these aren't really that popular anymore mostly because capacitance is
so gosh darn easy
and uh... they have certain problems taking in noisy environments so your
finger it does have resistance to it then you would be able to detect it just
by looking at the resistance between these two
you see this using an ohm meter
across two points on your skin
you'll see that there is some resistance the other kind it is a resistive
touchscreen sort of thing and that that's totally outside the scope of
what we're dealing with here but it has to do with measuring the resistance across a film
and being able to locate a point of contact on that
and other one is contact
so this is very similar to capacitance so far as only needing to have
one terminal
that makes the contact you and uh... this one terminal
so when you youch it, you complete a circuit
and you basically become an antenna and whatever's on the sensor side is waiting
for this thing on signal being strong
but uh... the part that only time I mostly here is capacitance sensor because
for what I do, it is the most useful and it's very simple to implement on an
AVR, so blamo! we're doing now
so let's see what exactly is the general idea of what we're talking about
say we have a capacitance sensor and hooks up to nothing
well then it's gonna say there is no capacitance there because there's nothing on the
other end of that sensor meaning there's no capacitance - it's simple.
But what if we do you put a capacitor on the other end and the sensor what if we have this
hundred picofarrad capacitor right here and we hook it up to our cap sensor?
Nothing. Because the other side of that capacitor is disconnected it's as though this
capacitor doesn't exist at all. But! If we hook up say the other end of the sensor
and complete the circuit ground now the capacitance sensor can tell exactly
what capacitance the capacitor really is. How does this work? Well...
You are the ground. So we have a capacitor and you touch the other side - you basically
complete that circuit there
you're not entirely the ground, but we'll get into that in a moment.
These capacitors - how do they work? Well you have to conductors - one on top - and
an insulating material (a dialectric) in between
and you have another conductor on the other side so this would be a plate
a couple square and this one would
be another square plate uh... a couple square inches
then if we want to measure the capacitances cross here, just put it to
ground and the other to a cap sensor
and we can tell what the capacitance is across these two plates and well if you have two
plates this far apart the capacitance is going to be almost non-existent - so
what we'll typically do is we'll have a very thin gap between these two plates.
and now we have a much
higher capacitance - the physics behind that is totally outside the scope of
this lesson
and you say say well
what about if we would just short it? We should be able to tell if you're touching.
yeah well that doesn't really work because you aren't actually ground it's it's a little
complicated.
You're basically act like a ground because your body can
hold a charge. Well, I say charge
but what exactly does this charge have to do with capacitors?
Well say we have a circuit - we have a switch that we can turn on and we have a
capacitor and resistor
and capacitors resist change in voltage so they can store up voltage over time
slowly gaining gaining gaining and now they have voltage -
energy stored inside of them. This will
which will create a potential across them so say this terminal right here
could be five volts and this terminal here could be zero volts and the voltage
across the capacitors - and if the capacitors are sitting in the middle of nowhere
they just maintain a charge for very long time
actually opened a package once that contains two very large capacitors
and I didn't bother checking to see very voltage initially.
Sure enough even though they'd been shipped to me in over the course of
several months, they retained their charge
So, with what we're doing, we have a resistor here and it's going to deplete the charge in
this capacitor so initially is to start off with zero volts like that if we plop
to switch on this twelve volts - current will
flow into this capacitor and charges it to twelve volts. Then if we let go of that
switch
then naturally the resistors going to be depleting the charge in the capacitor
- the voltage will drift down to zero.
You say Ah!
What if there was no capacitor what if the person wasn't touching it or or
whatever?
well if we have a switch there's nothing charging it
if I turn it on, the voltage will immediately be 12v and then, if I turn it off
It will immediately fall off.
In reality it it doesn't immediately fall off because there is residual
capacity and all sorts of other things but it's night and day - orders of
magnitude sharper.
So it's pretty easy to tell whether or not there's a capacitor just by looking
at that curve.
now I say ok! That's great and all but it's a little difficult to do it that way on an AVR.
So one thing to take note of his we can do it
in entirely the other way.
we can flip it upside down - we can have five volts - what the resistors charged to
so naturally the resistor is going to pull this to
five volts then we can use a switch in order to turn it off
effectively or short it to ground. So, all of a sudden, it's at zero volts being read
right here
then over the next couple seconds after release is going slowly rise back to
five volts once it hits this threshold here we can then mark it so immediately
after we turn off the switch, we can start a stopwatch and then we can make sure that
that delay - so
really the fundamental thing that's going on here is:
[reads slide]
[reads slide]
Your thumb can be the other side of the capacitor.
Your thumb doesn't have to have that much surface area.
And it doesn't have to be that close.
If you don't have your thumb on the circuit at all, then the capacitor barely exists. And you'll get
a very sharp edge - the delay is going to be very small. But if you have your thumb on
there say - that delay is going be much longer and you can use
the timers on an AVR to figure out exactly how long that would be
so uh... let's go take a look at what the sort of thing looks like in the
oscilloscope.
So here, on the oscilloscope, I have what I showed you guys before in the schematic
and uh... on the oscilloscope it basically
sits right here and it turns on the latch, it drives it low - like in the third
schematic
And then it let's go so the voltage rises up because there's a one mega-ohm resistor
pulling the voltage to five volts
It chills there for a long time until again i brought it low.
and let's a look at the code here.
So in the code really this is really simple basic things here, we're
setting up a clock
so that we go at about
fourteen megahertz, we set up the SPI
so that the
SPI can talk by debug mode.
so we can get printing
and we're not gonna be setting timers right now but we will be doing two other
things
one is setting up a marker
right here
and that's make it so that we can sync the oscilloscope go to our clock
so over on the oscilloscope if we look at channel one
we actually have this nice little square wave this is being generated as a marker
so the oscilloscope can have something to latch onto
to be able to keep this waveform nicely in sync.
so back over here
we're going to be saying that uh... PORTB.3 which is the
pin
that this pad right here is hooked up to
well that should always be driven low
well, not always, but if we're driving it, we should be driving it low.
back over here in the code
what I should do is set it to be low.
I'm not driving yet
but it is low.
i'm also sending the string "MARK:" just to make sure that
you know because working and the debugging is working.
so right here
I lock the port down.
and that that's that's this point on the oscilloscope here
right now activating this and it's been driven low
so this is now at zero volts
and go here we can see that i'm also marking it so that the oscilloscope can lock
onto it and everything's fine
we wait one full millisecond so between there and there is one full millisecond
then we release the port
and then we mark it on the oscilloscope and release the port there
and we wait another millisecond
so you can see this is one millisecond and this is one millisecond
here's the interesting part
i'm
completing a capacitor
right here this pad underneath is one side of the capacitor my thumb is
the other side of the capacitor
and
this blue material here I believe this is enamel
it's just the
solder mask is the dielectric
so as you can see the voltage rises very quickly but
when i put my thumb down
the voltage rises much more slowly
so say that this marker right here
let's see if we can zoom in
say that this marker right here is the threshold i don't actually know
what threshold is on the AVR for logical one but let's just assume that it's that
marker right there
right now it crosses right there
which is very very soon after it was released but if i pressed down
it crosses much later
so now
it's basically two to three times longer
and that's how i can tell how hard a person is pressing or
if they're pressing at all
so just by pressing
as you can see here
just take my thumb and
*boop* *boop* *boop* *boop*
and it's clicking and clicking and by doing that
we now have an electrical response that we can take a look at
that's not all that interesting that because i have to have an oscilloscope to tell if i'm
pressing
so how would we go about this in code
well it's not that bad
really all we have to do is set up a timer
and this time I'm going to be using TIMER 1 which is an 8-bit timer on this ATTiny85 bit timer on the c_t_ tiny five that's
running on the MAGFest badge there
which by the way if you're curious you can click on the video about the MAGFest
badge right here
ok! anyway
The idea is that we want to set up a... timer
we're gonna say I wanna do that
divisor one and divisor two
i don't know if that works out to be something like
one sixty fourth the clock rate
and i wanna turn on sleeping and i wanna enable
pin change interrupts
the pin change interrupts is a pretty big deal right now
and uh... you'll see why in just a minute
so like before we'll still want to lock the port down
we'll still want to have a marker
instead of uh... delaying a millisecond we're gonna print something - let's say
a local variable j I'll just print that - sendhex2 j
ok so right now let's make sure that works
terminal does not like that
let's try making it and running it
so now - oh - that's confusing i'm going to fix that
actually want to send a new line, so sendchr
newline
uh... excellent, so j has zero in it. everything is fine
and let's zoom out on the scope
sure it looks like we're still able to track on to everything and it
has a nice still
good curve to it so we're good there
now, the next thing we're going to need to have is an interrupt - this interrupt right here -
not actually using this part yet
but the idea is that whenever this pin changes
we're going to call this interrupt
and we're going to send 'tr' to be TCNT1
that's important because I'm gonna go put this code in
right here
actually I'm going to go put this code in right here
so
like before we release the port
and we set the marker on the oscilloscope but here we something a little bit different
we reset the timer
so setting to zero says start effectively like you just reset your
stop watching your going to start now err it's always running and you hit reset i don't
really doesn't matter i think about it
now I also set TIFR
to be OCF1A
actually don't need to do that quite yet
uh... right here though
actually I guess we do, I will
explain why in a moment
and that's just so that we don't hit the overrun
and right here is the other really key point
I now want to watch
bit value 3
so i'm going to make it so that whenever bit three changes state
so that's from off on in this case
i'm going to go call an interrupt
that will be able to uh... needed to get us out of this sleeping CPU mode
so the idea is the code is going to execute to here
and then
it's going to release the pin
and then
once the pin rises above the threshold
whatever that is that all happen to remember it
is going to continue executing
until then the CPU will remain halted
the only way out of this will be execute this code right here in PCINT1
and this is where i look at the time and send it to the local valued 'tr'
so
let's just for the sake of right after that i'm going to set 'j' to be 'tr'
the reason you do this is to make sure that nothing else happens anywhere else
in the code that could taint the value
so let's give this a shot, I'm going to go run this now
uh... excellent
so now what's going on is it's starting the stopwatch, and setting up all the
stuff that we thought we talked about and puts the CPU to sleep
twenty seven to twenty eight time units later, it crosses that threshold
and continues execution and reports the number back to me
this is great now
if we look on his computer screen here
if i press and hold a button
the number increases
only annoying thing here is it can wrap around so if i press harder harder
harder harder harder
it will eventually wrap around to zero, one
too
you know it is not acceptable. Additionally there's another problem
where if I grab hold will be here
I can cause it to completely trip out
and that's because by making contact with it
i'm just collecting all sorts of interference from the room
and the value on that pin might not get anything suitable for quite some time
as you can see now, it's completely out of sync everything fell apart, so I'm going to have to kill it
the way around this is a set a max time
and so what we'll want to do is we'll want to have another interrupt here
so whenever COMPA gets hit
now
COMPA
right here
I'm gonna enable the interrupt for comparator A
what that's set to is 0xf0
if this timer ever reaches 0xf0 which is two hundred and
forty-eight or something
than that
will go cause an interrupt
so right here
the sleep cpu could either be triggered by the pc interrupt - the pin change interrupt
the pin going past that threshold under normal operations
or by timing out
and being hit by the timer on this this
compare A value here
either way we still want to kind of set up the the 'tr' to be 0xf0
so that we know what it is
that way we don't have to ever worry about going and looping around and
not knowing what value we really are at
so let's try that
okay still is twenty seven twenty eight
now if i grab hold of that
oh something's not quite right let's see what i did wrong
we're enabling the interrupt for that there
perhaps we shouldn't be waiting as long there
perfect okay the problem was that we were waiting just absolutely too long
and also on the scope we can see some interesting remember how I said the value was up
there
turns out it's much much lower than i originally expected
so that's why i can press and hold it takes longer longer longer
until it gets up to that other value
i think there's also some AC coupling here so might be seeing some of that
but as you can see by touch it right here on the pad
the value will go all the way up to 0xf0
and there's really nothing much i can do electrically to mess it up and cause
it's a go on forever, or
loop around or cause any other confusion
so
we have just about everything that we need to do
now there's a problem
this this right here takes a certain amount of time to reach that even when
nobody's touch
so we're going to need to calibrate that out
and the way we can do that
is simply by running this could a couple times
and then setting a calibrate value, so unsigned short calibrate equals zero
unsigned char...
so what I'm going to do is run for a couple cycles
and I'm gonna say calibrated plus plus
if calibrated
less than ten maybe
I'm gonna increase that
and i'm not going to update 'j' equals 'tr' until it is calibrated, so else
'j' equals 'tr' so now until this loop is executed ten times
we're not going to actually set
this this value here
now we do need to do is we need to say
the calibrate
is equal to 'tr' so that means after the tenth iteration through her every time
it's gonna be writing the value that it's currently on to this calibrate value
after the tenth time it's going to say ah okay um... we're not doing that
anymore
here
if nothing has changed the value in 'tr' should be the same as the value in
calibrate
so should be able to subtract out calibrate
this is a little bit annoying because i have to detect if 'j' is greater than
0xf0
'j' equals 0x00 the reason we have to be this right here is
if it's fluttering as we had before twenty seven and twenty eight
we're going to want to have that the say calibrate happens to be 28 and tr is equal to
27, 27 minus 28 is a really nasty value
something we can't get
so i'm gonna do is I'm gonna say if it's going to be one of those nasty values
because we can't have anything greater than 0xf0, because of that time out
I'm gonna say if it's zero don't worry about it
so let's give this a shot
excellent - it's right now reading zero
so if i get my finger close you can see it's reading one two three four five six seven eight
and then if i press and hold 0xC8 that means that the calibration value was
relatively
medium high
and uh... i guess you probably assume that it's 0xF0 minus 0xC8 would be
whatever the current calibration value is
let's do one more kind of interesting thing here
so right now we have TCR1 running at
pre-
whatever they are they
are - one zero and two one it's it's dividing it
and it's going very slow
I'm gonna go a little bit faster now
so now it's really really sensitive
if I get my finger even close to here
I don't really have to make contact, as you can see, I'm not making contact
and it's registering just a little bit
so you can get this pretty detailed but the problem is you'll quickly run into
no more room
you'll timeout because we only have an 8-bit timer
before you actually get the data you're looking for
right here
after trying to switch to one zero
or I guess it would be one one
let's try that
yeah even with one one we still just don't have enough value we can't go long
enough an order to get any kind of good data
so yeah this has been my
my little
touch sensor thing here
uh... i hope you guys liked it, this has been the first time I've tried to do a let's code
and let's learn together on one video
and if you guys do you like these these please tell me because it's
a lot more work than I'm used to putting in my videos
but if you guys like it I will keep making 'em
uh... thanks for watching
and don't forget to subscribe if you haven't already