Tindie update: I have a few of the older Rev 0.2 eeZee Propeller breakout boards on clearance at Tindie, $16 each. Also, 10% off eeZee Tiny, 8-pin ATtiny breakout board (coupon code 52CAF8E)
A blog of robotics, electronics, mechanics, programming, and engineering.
Pictures, source code, circuit diagrams, ideas, thoughts, drawings, sketches and real-life goofups.
Thursday, January 31, 2013
Monday, January 28, 2013
Robot Magazine Article
I'm very excited to announce that I've been published in the March-April 2013 issue of Robot Magazine! They should be on the newsstands now.
My article about Data Bus and the 2012 Sparkfun AVC goes into some of the trials and tribulations of building a high speed autonomous rover.
My article about Data Bus and the 2012 Sparkfun AVC goes into some of the trials and tribulations of building a high speed autonomous rover.
Thursday, January 24, 2013
555 Schmitt Trigger Circuit for Wheel Encoders
Schmitt triggers are circuits that provide hysteresis. The concept is simply that instead of one threshold for on and off, there's an upper and lower threshold.
Signal (U), no hysteresis (A), Schmitt (B) - Wikipedia |
Wheel Encoder Adapters
To measure speed and distance travelled, Data Bus uses Sparkfun QRE1113 IR reflectance sensor breakout boards and wheel encoder discs printed with WheelEncoderGenerator.On my robot, using QRE1113 reflectance sensors running at 5V, this is the waveform I get.
It looks similar to a half-rectified AC signal, about 3V peak and around 1.5V offset. Running on 3.3V, I get a 1.8V peak with 0.9V offset. Either one should be enough to trigger logic circuits.
It's not a bad idea to add hysteresis, though. If the sensor is right between encoder stripes, add a little noise and it could trigger more than intended.
555 Timer Schmitt Trigger
While you can easily find many examples of 555 timers wired to provide hysteresis triggering, and we'll look at the two common ones, a third circuit works better for the wheel encoder system on Data Bus.In all cases, the encoder signal is ultimately wired to the Threshold and Trigger pins of the 555.
Inside the 555 timer is a 3-way voltage divider that provides the hysteresis thresholds. When the input voltage is above 2/3 Vcc, the 555's output goes low. When the input is less than 1/3 Vcc, the 555 output goes high.
555 Internals, more or less |
Series Capacitor
By passing the signal through a capacitor, low frequencies (including DC) are filtered. If this high-pass signal is fed in between a voltage divider, it adds a dc offsets to the signal.If the offset is 1/2 Vcc then the new peak voltage will be 0.9 + 3.3/2 = 2.55V, more than enough to trigger. The lowest voltage will be 3.3/2 - 0.9V = 0.75, well below the 1.1V lower threshold.
In the LTSpice simulation below, the red trace is the low threshold, the blue trace the high threshold, and the green trace is the signal with the dc offset.
So we're done. Let's build the board and move on, right? Wrong. I prototyped the circuit on a breadboard and found out it doesn't work like I want. At low wheel speeds, the 555 doesn't trigger at all. Why?
In the picture above, the red trace is the signal coming out of the high pass capacitor. Because the wheel speed is so low, most of the signal is low frequency and thus filtered and thus too small to trigger.
So, all you have to do is slap a big capacitor in place of the small one, right? With a capacitor that's large it can trigger on low wheel speeds, yes. However, it can can also get the 555 output "stuck."
Stuck? Yeah. If the robot sits with the input low too long, the 555 won't trigger for a long time after the wheels start spinning.
The reason is that, with the input voltage low, DC offset increases (the series capacitor charges) until the low voltage is now the new DC offset. When the wheels start moving again, it takes a long time for the circuit to bleed off the DC offset. This is the simulated result with a large capacitor, 220uF. It mirrors the real life experiments I did.
A smaller capacitor reduces the effect. Here's a 47uF capacitor. This also shows the output of the 555. The simulations do a good job of approximating what I'm seeing in real life.
Bottom line: you have to find the right capacitor for your needs. A small cap would work on Data Bus. It goes fast, and is only stopped at the starting and finish line. Still, I don't really like this circuit for wheel encoders. I'd prefer to fix the problem with the first circuit.
Transistor Amplifier Inverter
Using an NPN transistor to amplify (and invert) the phototransistor signal works well. It's not revolutionary although I didn't notice any similar circuits when searching for 555 Schmitt Trigger circuits. So, here it is.
Connect the base of the NPN through a resistor to the encoder board output, tie the collector to Vcc through a resistor, and the collector becomes the output for the 555. Simple, eh?
The Q1 transistor is either nearly 5V thanks to the pullup, or nearly 0V when base current is permitted to flow by the QRE1113 breakout board.
The Q1 transistor is either nearly 5V thanks to the pullup, or nearly 0V when base current is permitted to flow by the QRE1113 breakout board.
As a result, the circuit triggers at the lowest practical wheel speeds and doesn't lock up. Seems reliable enough to use. The only downside is that the duty cycle isn't even close to 50%, although no circuit is going to get it perfect. One can address this issue in software.
Encoder Imperfections and Software
With a pulse train that isn't a 50% duty cycle, calculating speed and distance is probably best done by timing either rising edges or falling edges, but not both.
The longer the robot travels on a particular leg of its journey, the less jitter affects distance calculation.
The longer the robot travels on a particular leg of its journey, the less jitter affects distance calculation.
For speed, it may be wise to adjust control loop timing, encoder resolution, or robot speed ranges to adequately filter jitter and other noise. A slow robot needs more stripes, a fast robot needs fewer. A slower processor needs fewer and/or slower.
Think about how often the MCU has to sample encoder counts to adequately filter noise and calculate speed with acceptable accuracy, given the number of stripes and the robot's typical speed range.
And maybe filtering isn't even necessary. If a speed PID controller is adjusting a robot's speed at every edge, jittery speed adjustments between edges may be effectively filtered by the momentum of a fast, heavy robot.
If the robot is slow and very light, momentum won't filter jittery speed changes very well. Software can do it instead. Change speed based on a running average, leaky integrator, or other software filter. Or, the PID controller can check speed by timing many pulses instead of few.
Wheel imperfections and encoder disc mounting imperfections cause a low frequency modulation of the encoder signal. Sent through a Schmitt trigger, the output pulse width will vary.
That sort of jitter may be a problem when precisely traveling short distances at slow speeds. More precision in the assembly may help. Or increasing the encoder resolution.
Conclusion
The 555 is quite the Swiss Army Knife of ICs. Acting as a Schmitt trigger is one of its many capabilities. With all that said, it's probably just as easy to just use a Schmitt Trigger inverter instead of the 555. I'm looking into that next.
Tuesday, January 22, 2013
LifeCam HD-6000 autofocus fix, Raspberry Pi
The Microsoft Lifecam HD-6000 autofocus is notoriously annoying. It refocuses unnecessarily sometimes every few seconds making the camera nearly unusable. Here's the workaround on Raspbian (Debian) for the Raspberry Pi.
Friday, January 18, 2013
Raspberry Pi Wifi Static IP
My RPi is going to be a telepresence robot so it uses wifi. It also needs a static IP address. Here's how to configure Raspbian Wheezy with a static IP for wifi. Included are two useful techniques. Follow the series of steps and options below.
You can configure Wheezy for 1. Roaming with Static IP, below, or 2. Static IP With No Roaming, WPA2, PSK, below.
allow-hotplug wlan0 iface wlan0 inet manual wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
Next, you'll configure wpa_supplicant. Add a specification for a network Without Encryption below, With Encryption, WPA2, PSK below, or Any Network Specification below.
Now proceed to the 3. Final Steps below.
Now proceed to 3. Final Steps below.
In fact, you can have multiple strings, like home, work, traveling, demo, etc. Once you have edited wpa_supplicant.conf and interafaces, proceed to the 3. Final Steps below.
Specify using static instead of manual for interface wlan0, then specify the address, netmask, and gateway, configure the WPA passphrase and SSID, and the wireless channel. Finally, you have to disable the wpa_supplicant configuration, and you have to disable the default dhcp behavior.
Proceed to 3. Final Steps below.
If you get no errors on the last command, except possibly some ioctl errors, you're a-ok.
Double-check by issuing iwconfig to make sure the RPi is joined to the access point, then use ifconfig wlan0, make sure it's configured correctly, then issue a ping to your gateway (ping 192.168.0.1) and then ping google.com or some other reliable website.
Et voila, you have a wifi static IP. Congratulations!
Did this help you? If so, do me a favor and share via redit, twitter, Google+, etc. Thanks!
You can configure Wheezy for 1. Roaming with Static IP, below, or 2. Static IP With No Roaming, WPA2, PSK, below.
1. Roaming With Static IP
By default, Wheezy is configured for wireless roaming using wpa_supplicant, a daemon that manages roaming and authentication to access points with WPA, WPA2, WEP, or no encryption. With it, you can specify multiple access points and your RPi will join them automatically. First you'll need to add a Static IP Configuration, below.a. Static IP Configuration
First, edit your /etc/network/interfaces and add the following to specify a static IP for demo which is any arbitrary name that we can use in the wpa_supplicant.conf to associate any network with this static IP configuration. You'll also make sure you have your wlan interface configured correctly.allow-hotplug wlan0 iface wlan0 inet manual wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface demo inet static
address 192.168.0.4
netmask 255.255.255.0
gateway 192.168.0.1
b. Without Encryption
To specify a network without encryption, edit /etc/wpa_supplicant/wpa_supplicant.conf, add your network specification to the end of the file as follows. Specifying key_mgmt=NONE says the AP does not require encryption. To use the static IP configuration that you added in your interfaces, set id_str="demo" or whatever name you chose.network={
ssid="BotThoughts"
scan_ssid=0
key_mgmt=NONE
priority=5
id_str="demo"
}
2b. With Encryption, WPA2, PSK
To specify a network with WPA2 encryption using PSK (pre-shared key), edit /etc/wpa_supplicant/wpa_supplicant.conf, add a network specification to the end of the file as follows. To use the static IP configuration that you added in your interfaces, set id_str="demo" or whatever name you chose.network={
ssid="your-ssid-here"
scan_ssid=0
psk="your-pre-shared-key-here"
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
auth_alg=OPEN
priority=1
id_str="demo"
}
2c. Any Network Specification
The bottom line is that you can add any network specification, following various online examples, to wpa_supplicant.conf and use a static IP for that access point simply by adding id_str="demo" or whatever name you chose in interfaces.In fact, you can have multiple strings, like home, work, traveling, demo, etc. Once you have edited wpa_supplicant.conf and interafaces, proceed to the 3. Final Steps below.
2. Static IP With No Roaming, WPA2, PSK
This config does not use wpa_supplicant and is for WPA2 personal with PSK (Private Shared Key). The changes to your /etc/network/interfaces file will result in something like the following.auto lo
iface lo inet loopback
iface eth0 inet static
address 192.168.0.5
netmask 255.255.255.0
gateway 192.168.0.1
auto wlan0
allow-hotplug wlan0
iface wlan0 inet static
address 192.168.0.4
netmask 255.255.255.0
gateway 192.168.0.1
wpa-passphrase yourpassphrasehere
wpa-ssid yourssidhere
wireless-channel yourchannelhere
#wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
#iface default inet dhcp
Specify using static instead of manual for interface wlan0, then specify the address, netmask, and gateway, configure the WPA passphrase and SSID, and the wireless channel. Finally, you have to disable the wpa_supplicant configuration, and you have to disable the default dhcp behavior.
Proceed to 3. Final Steps below.
3. Final Steps
After making your configuration file changes, either reboot, or issue the following commands to restart the wlan0 interface:
sudo ifdown wlan0
sudo ifup wlan0
If you get no errors on the last command, except possibly some ioctl errors, you're a-ok.
pi@raspberrypi:/etc/network$ sudo ifup wlan0
ioctl[SIOCSIWAP]: Operation not permitted
ioctl[SIOCSIWENCODEEXT]: Invalid argument
ioctl[SIOCSIWENCODEEXT]: Invalid argument
pi@raspberrypi:/etc/network$
Double-check by issuing iwconfig to make sure the RPi is joined to the access point, then use ifconfig wlan0, make sure it's configured correctly, then issue a ping to your gateway (ping 192.168.0.1) and then ping google.com or some other reliable website.
pi@raspberrypi:/etc/network$ ifconfig -a
eth0 Link encap:Ethernet HWaddr b8:27:eb:fb:8d:50
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:36 errors:0 dropped:0 overruns:0 frame:0
TX packets:36 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3480 (3.3 KiB) TX bytes:3480 (3.3 KiB)
wlan0 Link encap:Ethernet HWaddr 80:1f:02:86:ef:61
inet addr:192.168.0.4 Bcast:192.168.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:38 errors:0 dropped:1467 overruns:0 frame:0
TX packets:14 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:841044 (821.3 KiB) TX bytes:100717 (98.3 KiB)
pi@raspberrypi:/etc/network$ ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
64 bytes from 192.168.0.1: icmp_req=1 ttl=64 time=3.07 ms
64 bytes from 192.168.0.1: icmp_req=2 ttl=64 time=1.90 ms
^C
--- 192.168.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 1.905/2.491/3.077/0.586 ms
^C
Et voila, you have a wifi static IP. Congratulations!
Did this help you? If so, do me a favor and share via redit, twitter, Google+, etc. Thanks!
Tuesday, January 15, 2013
Tindie, Projects, New Look
New Look
You can't miss the new look if you're visiting bot-thoughts.com right now.After 5 years, I figured it was time for a new look and layout. Besides, every single one of my projects is completely stalled waiting for various parts and boards. What else am I to do with my spare time?
Projects
I mentioned I'm waiting on parts for two projects. Those projects are, respectively, a JeeNode sensor to tell me when the mail has arrived and a tele-presence robot based on a Raspberry Pi.The latter project will be using Pololu tracks and motors to drive around an RPi with a Webcam and WiFi dongle attached. I'll set up a web page on the Pi to control it from anywhere in the world. We'll be travelling this year and I want to check up on the house remotely.
The main challenge? Charging the batteries...
Bot Thoughts Store on Tindie
I've started a Google Group for the Bot Thoughts Store so I can post updates there. All the parts have arrived for the eeZee Propeller and eeZee MicroSD. I'm now waiting on boards. They'll arrive possibly next week. Also, another batch of eeZee Tiny 8-pin ATtiny breakouts will be in stock by Feb 1.Friday, January 11, 2013
Getting Started with JeeNode v6
Two JeeNode v6 kits; RFM12-B radios not installed yet |
Starting with a standard JeeNode v6 kit, let's get cracking with assembly and testing.
Tuesday, January 8, 2013
ATtiny 2313 Breakout and I2C ADC
I have a couple more #tindie fundraisers going:
eeZee Propeller and eeZee microSD boards are on order and I'll be ordering parts soon.
- ATtiny2313 / ATtiny4313 breakout/programmer
- 10-bit I2C ADC board, up to 9 per bus [did not fund]
eeZee Propeller and eeZee microSD boards are on order and I'll be ordering parts soon.
Friday, January 4, 2013
Generating a clock signal with dsPIC33F
dsPIC33F generates a 500kHz clock signal |
Wednesday, January 2, 2013
Subscribe to:
Posts (Atom)