Random notes & other stuff…
…about Linux, electronics, digital photography, whatever…-
Piezo transducer signal conditioning
Posté le 6th juin 2009 Pas de commentairesPiezo transducer are very common, very cheap, and can be very useful as sensors : sound, knock, shock, whenever it “moves” or “makes noise”, a piezo sensor can help.
However, the signal from those things is very unpleasant for the digital hacker : it’s roughly a sinewave that dampens over time. Also, the signal often goes negative which is pretty bad for mots digital chips out there. The ATmega168 (and most of the atmel 8 bit microcontrollers), for instance, indicates that voltage on any pin must be between -0.5V to VCC+0.5V. Piezo transducer easily go far beyond those bounds.
In the capture below, voltage from the piezo goes a down as -52V and goes up to 9.2V. This is more than 60V peak to peak. If you don’t do anything, your poor microcontroller might get sick rather quicly :
In this capture, the signal first drops to -20V, and then flies up to over 35V. Almost 60Vpp here too.
These are just examples, I didn’t tweak the piezo or smashed it with a hammer : just a hit with a fingernail, and you almost always end up having huge Vpp values. Also, the behaviour is not predictable (well piezos are, but the way we smack it isn’t), so it might go up first, then down, then up, who knows…
A close up shows the “dampening sine-like signal” that occurs after the first big spikes :

Piezo signal close up
So signal conditioning is a must with those pesky animals if you’re doing digital.
Let’s recap what has to be done :
- make that signal all positive : most of the time, piezos signals are read by ADC, so we want positive voltages
- restrict signal bounds to 0 - VCC so voltage doesn’t climb to scary values (scary at least for microcontrollers and ADCs),
- shape the signal so it doesn’t make bumps and stays clean and predictable
All these requirements are surprisingly easy to achieve. We will get to this goal in three steps, each spect taking care of one item above. Respectively :
- add a half-wave rectifier, in order to keep positive part of the waves
- add a zener diode, so signal doesn’t climb over zener’s breakdown voltage
- add a RC pair so ripples get filtered
Half bridge rectifier
First, we want to rectify the piezo signal, i.e. make it all positive. We’ll use Schottky diodes for that. Schottky are more interesting since they have a pretty low (compared to standard rectifier diodes) forward voltage drop (Vf), around 0.3V.
You might ask : why not use a complete Schottky-based bridge rectifier, and make the whole signal positive, instead of filtering negative voltages ?
Well, look back at the first scope shots of raw piezo signals. When signal changes sign, it makes it rather violently, and can even be higher on the new side than it was on the previous side. Now try to make the math abs() operation on the shape, mirroring the negative part of the shape on the other side of the time axis. You’ll end-up with an erratic plot : low, then high, then low. This means that, even with some filtering, you wont end-up with clean shape, but with a jittering thing that will look like the first signal, but all positive and less wild. This is not what we want, so we are sacrificing the negative part of the signal to get something nicer (the fine Agilent firmware bug is provided free of charge :).
In fact, well do a bit more than a half wave rectifier. If we just put a Schottky diode in series with the positive we’ll end up with the kind of signal shape shown on the left. We can see there is a fair amount of signal that is still below 0v, and in our circuit, we’re not supposed to have negative voltages. Even if the ADC can stand it, it probably won’t do any interesting measures with a negative signal.
There is probably a good reason for this to happen, but I don’t have a clue right now. If you do, please leave a comment.
So we have to get rid of this negative leftover, by adding a second Schottky diode, between ground and signal lines. We’ll just keep the positive signal, but it will be much easier to filter this way.
Our piezo signal rectified by two Schottky looks like this (the wavefom has been moved to the bottom of the screen for cosmetic reasons). We still have negative voltable building up, but it’s pretty negligible now. I wonder if that -400mV is linked to the diode’s forward voltage.
Althought the scale isn’t the same, the small ripples seem to have disappeared. This might be due to the Schottky diode capacitance (14pF), which, while low, could impact the small ripples with higher frequency. I didn’t have time to check that though.
Now, we need to cap the maximum voltage in circuit, so we don’t fry our ADC.
Zener diodeAs seen above, voltage range is pretty high and can climb quickly to unappropriate values for digital purposes. So wee need to tame the voltage created by the piezo. Zeners have this ability, and can limit voltage to a fixed value. Whenever voltage is higher than the Zener’s rating, the Zeners lets current flow thru and as a side effect, help maintain voltage to a fixed value.
We usually have to add a resistor between the Zener and ground, so voltage builds up around it and current is limited thru the Zener. But this is not necessary with piezo, since involved currents are very very low.
After we add a 5.1v Zener in the circuit, the voltage read from a piezo looks like this.
You can smash the piezo as hard as you want, you’ll never exceed the Zener’s rated voltage.
If we just use this shape as is, we’ll have a hard time trying to guess if the piezo has been smashed or not. We have to filter those spikes to get a smoother shape.
Filtering the signal
This signal can be filtered by using a RC cell. What just need to know how long we want the shape to last. For my application (drum trigger), I want the signal to fade out in 10ms maximum. Since we know that the voltage drops to 10% of the initial voltage after
, we can find the right resistor knowing the capacitor value, and vice-versa.Let’s say we use a 1MΩ resistor, we’ll have to use a
capacitor.So we end up with this simple little circuit :

And get this nice little shape :

Finaly, a clean, ADC friendly signal
Hope this can help you using thosr pesky beasts. We warned that piezo are all differents, and that size matters… So experiment with that before engraving the above stuff in copper.
-
Maximizing ADC range for decent battery voltage monitoring (with minimum parts)
Posté le 29th mai 2009 4 commentairesTracking circuit’s battery voltage can be a nice addition to your project. Knowing what is the battery state can help designing a better, more clever circuit, and take appropriate actions depending on the battery state.
Voltage reference
In some project, I wanted to use my µcontroller ADC to get battery voltage. The first problem you encounter is : how can I measure on my ADC the circuit voltage since the top value of the ADC is the circuit voltage itself ? Yes, indeed, using the ADC this way you’ll always end up reading the maximum value (256 for 8 bits ones, 1024 for 10 bits ones, …), since the circuit voltage is the reference voltage.
This can be solved most of the time. For instance, in atmel microcontrollers, you just have to use the internal reference (most of the time 1.1v or 2.56v) by changing the ADMUX register bits. Atmel AVRs also let you provide your own reference at the AREF pin. The datasheet gives plenty of details about this.
When using Arduino, you can achieve the same ADMUX control by using the analogReference(ref) command where ref can be one of :
- DEFAULT: use the circuit’s supply as reference (5 or 3.3 volts depending on the supply)
- INTERNAL: use the built-in reference 1.1 volts on the ATmega168 and 2.56 volts on the ATmega8.
- EXTERNAL: the voltage applied to the AREF pin is used as the reference.
This being said, we can start working, but the real challenges lies ahead.
Gain
Now that we have our reference, how can we measure that battery (let’s say LiPo) voltage ? Let’s suppose the chosen reference is 1.1v. We can not compare the battery voltage directly. LiPo can go as high as 4.25v, much higher than our reference. So we have to scale it down. We can use a voltage divider (a pair of resistors) to make this easily. By doing so, we are applying a gain < 1, to make the battery voltage range seen by the ADC fit below our voltage reference.
Now, what resistors values should we choose ?
We know that :

Since we want V to be 1.1v (same as our voltage reference) when battery is full (thus 4.25v), the equation can be written as :

Ok, we have our R1/R2 ratio. Since we don’t want this circuit to waste energy (after all, we’re measuring our own battery), we want R1 and R2 to be as high as reasonably possible so current flowing will be negligeable.
Let’s say we take 3MΩ for R2, we can use a 1MΩ resistor for R1.
Great, we now lowered the voltage in our circuit, so when the battery is full (4.25v), we read almost exactly the value given by our voltage reference (1.1 in this case), which is the max value that our ADC can report.
But wait, what happens when the battery is depleted ? Depleted batteries never show 0v. LiPos for instance, are depleted at 2.7v. What will 2.7v show in the ADC in our situation ? Remember :
(we’re basically dividing the battery voltage by 4 with the values choosen for the resistors)Thus, when our LiPo is empty, we’ll read 0.675v, and since :

So our 10bits ADC will tell us some number around 628. So, unfortunately, in this configuration, the only range used by our 10bits ADC is [628-1024], approximately 60% of it’s range. This is pretty bad. Now that we know how to make the voltage range fit below our voltage reference, it could be cool to extend this to the full range of our ADC. We now want our ADC to say 0 when battery is depleted, and not 628.
Offsetting
As you may have guessed, we can achieve that by offsetting. Offsetting means adjusting the range by using an offset value. And in our case, we just want to lower measured signal by the minimum value the battery can have : 2.7v.
Ok, but how can we do that ?
Well, everybody out there probaby know this way to go already. But being self taught in electronics, I just didn’t had the iden in the first place. I probably not very good at Googling too, so, I just searched for a way.
My initial idea was to use a rectifier diode. Let’s say we arrange the circuit on the left, with a diode between Vbat and R2. Voltage between the diode will be
. This is fine, things are starting to take place. Yes we want to drop some voltage thru rectifiers until Vf is 2.7v (the minimum value we are interested in).Unfortunately, this is not practical. First, Vf varies greatly according to the current in he circuit. Take a diode datasheet, find the Vf vs. I graph, you’ll get the idea. The other problem is to get the Vf we want. It varies, but it is usualy pretty low. This means that we would have to chain several diodes to get the desired effect, but might get surprised in the real achieved Vf, since it depends on diode bin, current, the way we read the graphs, etc…
Not very practical. After spending an hour browsing datasheets to find the holy grail having the good Vf, I slammed my head on thedesk : “Just use a Zener stupid n00b!“. Yes, Zener, that was the solution.
Instead of chaining diodes, I just had to put a Zener at the same place, reverse biased, with Vr being the lowest value I needed to measure in my circuit !
But there is still a problem : we are interested in the Zener’s have a reverse breakdown volatge value. But this voltage (usually noted Vr in their datasheets) is given for a certain current. If we use MegaOhm-style resistors, it simply won’t work : you’ll end up with a Vr completely different (around 0.7v, the classic N-P junction Vf with the Zener I tried). Again, we have to open the Zener’s datasheet, and look for the test current.
For instance BZX79 series have an Iztest current of 5mA. This means that we will have to make 5mA flow thru this branch to have the reverse breakdown voltage we are looking for.On the capture below, we can see the ideal situation. Yellow is Vbat, green is Vbat-Vz and purple is Vz (Vz is calculated by the scope, note the different scale).
But the needed current for the Zener to work is pretty high, given we are running on batteries, and we want to be energy conservative. So, how can we do ?
After some more thoughts, the solution came : instead of plugging this circuitry to ground, we’ll plug it to a microcontroller pin. When we want to measure the battery voltage (which is something we son’t have to do very often), we just put the pin in OUTPUT mode, and set it to 0v (low). Despite the name, when a pin is in OUTPUT mode, it will sink current if it’s low. The rest of the time, the pin will be set to INPUT mode (Hi-z). It’s as easy as this.
The circuit now looks like this. With our ADC, we are measuring voltage V, between the “first” resistor and the reverse biased Zener.
How can we choose the component values to maximize ADC range now ? We’ll try to find this out with generic terms, so it can be applied to other power sources.
First, some facts. The maximum value that will be read by the ADC will be Vref when supply voltage is VbatMax - Vz.
The minimum value read will be VbatMin-Vz, and should be equal to 0.We already can deduce how we have to choose Vz (and thus, the Zener) :

Ok, the right Zener Vz should be equal to the minimum reading we’re interested in, just what we guessed above.
Now, let’s try to find the usual relationship between R1 and R2 in our voltage divider. As stated in the above facts, the maximum value that will be read by the ADC is VbatMax - Vz. Ideally, in the middle of our voltage divider, this value should be exactly equal (scaled) to Vref (let’s call it Vmax).
Thus, we can lay down the usual voltage divider equation stuff :


Since all the “Vsomething” are known values, we do have a relashionship between R1 and R2 to create our divider. The values used do not matter, only the ratio… err wait. Let’s not forgot about the Zener’s Iztest ! Remember that to get the reverse beakdown voltage we need, we have a constraint : we have to make the Iztest current flow thru the circuit. So we need to scale R1 and R2 appropriately. Of course, since the battery voltage varies (why would we need to measure it if it wouldn’t ?), establishing a current based on the resistors values is an approximation. When the battery voltage will be low, the current will low too, and our measurement won’t be as accurate as with a full battery.
We have several ways to handle this : we can just ignore this, and assume some average voltage. This would be probably fine for LiPos, since most of the time, they hang around 3.7v. We could get the lowest voltage we want to measure, and take it as a base to calculate resistor values to achieve Iztest. But since this voltage is zero, we won’t go far. The best option is probably to take the microcontroller datasheet, and use the maximum sink current (let’s call it Isink, watch for typos
) when Vbat is at maximum. This will suck the battery a bit during the ADC sampling, but again, we don’t need to check battery voltage every millisecond. Of course, we need Isink to be higher than Iztest. If Isink > Iztest, no problem as long as we don’t go over the Zener’s power rating. If Isink < Iztest, dump that crappy microcontroller, turn computer off, and have a walk.Ok, let’s use this and calculate resistor values to get a correct current, and a good resistor ratio.

Since VbatMax, Vz and Isink are known values, we know what R1+R2 is. And since we have a relashionship between R1 and R2, we have all we need to get R1 and R2 values. Let’s try it out.
Pencil and paper test
Let’s try a real life example. We want to measure our LiPo voltage. So we’ll use these values :




We already know that :

Let’s find the R1+R2 sum first :

Ok, now, we can use the R1-R2 relashionship :

So, reusing the R1+R2 equation above,
(we’ll use the closest standard value 56Ω).Finally,
(we’ll use the closest standard value 22Ω).Converting ADC reading to real voltage
Now that we’ve been this far, let’s not forget what we came here for : get the battery voltage. we have to convert the ADC value back to some human reading.
A n bits ADC reads the voltage at V, and converts it linearly (supposedly) into a value between 0 (meaning 0v in our case) and
(meaning Vref in our case).So to convert for an ADC value to battery voltage, we can use :

Finally :

Cheat sheet (a.k.a. fast forward mode)
Known stuff :
- Maximum voltage to be measured :

- Minimum voltage to be measured :

- Voltage reference :

- Maximum sink current for µcontroller :

Stuff to calculate :
- Zener’s required reverse breakdown voltage :

- Resistor value R1 (low resistor) :

- Resistor value R2 (high resistor) :

- n bits ADC to battery voltage conversion :

Now, I need to test this on the breadboard. Share your experiments if you use the above stuff. And doublecheck the math
-
Bat Detector with adjustable gain
Posté le 22nd mai 2009 Pas de commentairesWhile I stumbled upon Tony Messina’s Simple Bat Detector pages long time ago,I really decided to build one only when I saw that Bre Pettis could :).
So I barely used Tony’s schematics and instructions, but spiced the circuit a bit by adding a gain adjustement potentionmeter, a on/off switch driven by the volume potentiometer, and a LED witness light.
It’s pretty easy to build : thru-hole components, some wires, …. You can use the eagle schematics included below to build yours. The latest version is single sided, and doesn’t need the flying wire on the top side like mine.
The most difficult part is to find the right compononents for the switch capable potentiometer (I choosed a push/push type : push to turn on, push again to turn off) and the box.
The push/push 10kΩ potentiometer used is a tyco Electronics 17PCSA103MC19P. You can grab it at Farnell.
The other potentionmeter is just a standard 10kΩ one, like the Tyco Electronics 23ESA103MMF50NF
The enclosure is a Boss Enclosure, model BIM RETEX 551 (Betabox Series), also available at Farnell.What I didn’t find at Farnell is the piezo-ceramic earplug. Unfortunately, I don’t remember if I got the high (E10P) or low (S83) impedance earplug.
- Poorly routed initial prototype
- Inside view
- Outside view : volume, gain and LED
Grab the schematic and board here :
On the board, there is no connector to plug the potentiometer push/push switch. So you’ll have to wire one pin of the switch to the battery clip, and the other pin to the ‘+’ connector on the board. For ground, just wire directly.
To test your detector, if you don’t have a bat under your hand, just open a water tap and aim the detector at it : it should make lots of noise. If not, try to adjust the gain settings. If nothing works, well… something is wrong
Now, just make it and go out listen for the bats. They’re pretty easy to find in semi-urban area : bats love city lights (well, they love the insects that love the city lights), especially mercury vapor bulbs (white lights), which attract more insects. Unfortunately, most towns are now installing high pressure sodium lamps (orange), which insects doesn’t like as much. The most common bats, Pipistrelle, emit two kind of calls :
- echolocation for hunt, around 48KHz, you’ll hear those with the detector
- social calls, around 20KHz; you can hear them without any device if you’re lucky enough (or young enough)
Finally, but you probably already know that : do not wake up hinernating bats. If you do so, they have to fly, waste energy and even if they come back to sleep again, they will get hungry too early in the season. They will have to wake up to hunt, but too early means no insects, and the bat will probably die by waking too early.
Have fun !
-
Cisco 1841 ADSL configuration for Free telecom
Posté le 17th mai 2009 Pas de commentairesPeople connected via Free, a french internet provider are usually happy customers… until they need to get support. Well, this is a problem with most of providers out there.
When you subscribe to Free, they send you a Freebox : a combo containing a DSL modem, a router, an FXS to hook your telephone, and sometimes more if you’re lucky enough to have TV and other services.
But when you don’t want to use this box, or when it’s dead, you can use alternate ways to get connected. The easiest one if to get a DSL modem (a speedtouch for instance), and use a PPPoE capable routeur (like a Linksys WRT54GL + tomato firmware).
You can also do PPPoA if you have a router with an ATM interface. The configuration included below can be used on a Cisco 1841 routeur with ATM card to connect to Free. It probably can be adapted to other models very easily by changing only interface names.
You can debug what happens by issuing :
debug ppp neg
debug ppp authGood luck.
!
version 12.4
no service pad
service timestamps debug datetime msec
service timestamps log datetime msec
service password-encryption
!
hostname c1841-pppoa
!
boot-start-marker
boot-end-marker
!
enable secret 0 CHANGE_YOUR_ENABLE_PASSWORD
!
no aaa new-model
!
resource policy
!
memory-size iomem 5
mmi polling-interval 60
!
no mmi auto-configure
no mmi pvc
mmi snmp-timeout 180
ip subnet-zero
ip cef
!
!
no ip dhcp use vrf connected
!
! Global pool for the LAN clients
ip dhcp pool CLIENTS
import all
network 192.168.0.0 255.255.255.0
default-router 192.168.0.254
dns-server 192.168.0.254
!
! Static assignements for specific clients
ip dhcp pool pc1
import all
host 192.168.0.2 255.255.255.0
client-identifier 0013.8dd7.2ada
!
ip dhcp pool pc2
import all
host 192.168.0.3 255.255.255.0
client-identifier 0018.f327.3137
!
ip domain name whatever.it.is
!
! Use ssh
! You need to issue
! crypto key generate rsa
! first
ip ssh time-out 60
ip ssh authentication-retries 2
!
! Lets define some user
username _CHANGE_USERNAME password à CHANGE_USERPASSWORD
!
!
!
interface Null0
no ip unreachables
!
! This is LAN side
interface FastEthernet0/0
description LAN connection
ip address 192.168.0.254 255.255.255.0
ip nat inside
ip virtual-reassembly
duplex auto
speed auto
no cdp enable
!
interface FastEthernet0/1
no ip address
speed auto
!
! This is the ATM interface
! We\'re doing PPPoA
interface ATM0/0/0
no ip address
no atm ilmi-keepalive
dsl operating-mode auto
pvc 8/35
ubr 160
encapsulation aal5mux ppp dialer
dialer pool-member 1
!
!
interface BRI0/1/0
no ip address
shutdown
!
! Dialer interface for PPP negotiation
interface Dialer0
ip address negotiated
ip nat outside
ip virtual-reassembly
encapsulation ppp
no cdp enable
ppp authentication chap pap callin
ppp chap hostname 04XXXXXXXX@freeadsl
ppp chap password 0 CHANGE_TO_YOUR_CHAP_PASS
!
ppp pap sent-username 04XXXXXXXX@freeadsl password 0 CHANGE_TO_YOUR_CHAP_PASS
! Required to get DNS servers
ppp ipcp dns request
!
ip classless
ip route 0.0.0.0 0.0.0.0 Dialer0
!
! Required to act as a DNS server for the LAN clients
ip dns server
!
! Oh please no !
no ip http server
no ip http secure-server
!
! Do some NAT for LAN clients
ip nat inside source list 10 interface Dialer0 overload
access-list 10 permit 192.168.0.0 0.0.0.255
!
control-plane
!
line con 0
stopbits 1
line aux 0
line vty 0 4
password 0 CHANGE_TO_SOME_PASS
login local
! We just want ssh, not telnet
transport input ssh
!
end















