Thursday, December 19, 2013

Getting an Elevation Profile From a Set of Directions (or Why is my baby crying?!)

My family and I live in Salt Lake City, UT. My wife's family is from the small town of Joseph City, AZ. We recently drove there for the Christmas holiday to spend time with family. It was our six-month-old daughter's first trip to Arizona and her first drive of this length. Without a baby it would take us about nine-and-a-half to ten hours to make the drive, depending on stops we took. This trip took us 11 hours; five short hours and six very long ones. She was not happy at all on the second half of the trip. It wasn't until we arrived in Joesph City that we realized that perhaps she was experiencing some uncomfortable air pressure differentials and wasn't able to "pop" her ears. That would have been nice to know at the time. We also didn't realize that she's teething and I think she just hated being in the car seat that long.

So my question was this: What's the best path to travel home to avoid elevation changes she might find uncomfortable? There are primarily three ways to travel between Salt Lake City and Joseph City. The first two go from Salt Lake to Kanab, UT, then to Flagstaff, AZ, then to Joseph City. They differ between Kanab and Flagstaff. You can either take 89A through the Kaibab National Forest or you can take 89 through Page, AZ (now temporarily detoured through 89T). According to Google Maps, following 89T instead of 89A is 3 miles longer and 2 minutes shorter. Not bad for an over-nine-hour trip spanning almost 600 miles. The third way is completely different. It travels through eastern Utah going through Moab, UT following Highway 191. This path is shorter than the other two by about 25 miles and 15 minutes according to Google Maps. Before the Route 89 landslide (ADOT updates) we would usually travel through Page, AZ. This time we took the 89A route. Had I known about 89T and that it was recently paved I probably would have gone that way. It's nice to have moderately sized cities along the trip like Kanab and Page. There's pretty much nothing between Kanab and Flagstaff going the 89A route. Our biggest worry was that Illa, our daughter, would break down about an hour past Kanab along 89A. That's exactly what happened.

Here's an elevation profile of the roads traveled following the 89A route (thanks to GPS visualizer):

See that giant peak at around mile 350? That's 89A through the Kaibab National Forest and then descending down to the Colorado River. The canyon is very deep and the bridge elevation is actually at about 3500 ft. This elevation plot uses the earth's elevation, not the road's, which only becomes a problem with bridges. Can you guess where Illa got extremely fussy? That peak. Now previous to this there were other similarly rapid ascents and descents but she had slept through them. This was also about 5 to 6 hours into the trip and she wanted out of that seat. So what do the other two paths look like?

Here it is taking the 89T route:
...stupid peak...

And here is it going through the Moab route:

That looks nice, too.

So I already mentioned and it's shown in the figures that these images were made using the GPS Visualizer website (http://www.gpsvisualizer.com/ and http://www.gpsvisualizer.com/elevation). The elevation profiles require either a link to the Google Maps driving directions or a kml file. What I did was download Google Earth for desktop, find the directions there, export it as a kml file, and upload that. The reason is because I couldn't get the links to work. The problem is that the link must be from the "classic" Google Maps and not the new preview version. Doh!

A tip for those who do use Google Earth. In Google Earth there were no alternate route suggestions and I couldn't see a way to add multiple stops. So I typed it in as given in the bold titles in the figures with multiple "to:" labels and locations. And when I say export it as a kml, I clicked this button
which is just below the driving directions box, pasted the contents into notepad, and saved it as a kml file. What a pain. I wish I had realized that Google Maps preview was the problem. To leave the Google Maps preview to go back to classic, find the question-mark-circle in the lower right of the map screen and click on it. There it will give an option to go back. Or you can open an Incognito window in Chrome to temporarily access classic Google Maps.

And a big thank you to GPS Visualizer. What a cool website that offers much more than elevation profiles.

So what will we do about the trip back and the baby? Probably break the trip over two days.

UPDATE (1/17/2014): So the trip back was a couple of weeks ago and I thought I'd follow up. We took the 89T route back, which was good. When we got to Panguitch we decided to keep going and make the trip in one day. That left one large mountain pass to go over. This was state highway 20 between highway 89 and I-15. She definitely got fussy as we climbed and descended but giving her something to chew on helped. Lesson learned.

Friday, November 15, 2013

D-Link DIR-601 Client Bridge with a Broadcom AP

I wanted a client bridge for a D-Link DIR-601 hardware rev. A1 to a ASUS RT-N16 AP running Tomato USB firmware. Is that so much to ask? Apparently, yes. The DD-WRT forums are full of people having trouble getting Atheros and Broadcom based routers to play nice with one another, especially in settings like a client bridge. The official response: Too bad. Maybe if you're lucky, but don't look at us for help.

Thanks.

So instead I try OpenWRT for the DIR-601. They suggest a pseudobridge. Maybe it works but I couldn't get it working. Then I stumble upon Gargoyle firmware. After finding out the hard way that version 1.5.11 is too big, I flashed version 1.5.10. Once I did that it was super easy to set up and worked the first time. Nice.

The easiest way to do it is this:
  1. No matter what firmware the DIR-601 is running right now, D-Link put in an emergency firmware loader that can be accessed in the following way:
    1. Unplug the router
    2. Push and hold the reset button while unplugged
    3. Plug in the router while holding the reset button
    4. Keep holding the button for about 10 seconds until the power light slowly blinks orange
    5. Manually configure your wired connection to 192.168.0.100, subnet 255.255.255.0.
    6. From a web browser, go to 192.168.0.1
    7. If nothing comes up, repeat steps 1-4 and try again.
    8. From here you can upload the original D-Link firmware or DD-WRT or OpenWRT or Gargoyle. Upload the "factory" firmware, that is, the firmware designed to be uploaded when the router is using D-Link's firmware. Don't upload the firmware designed to be uploaded from a third-party firmware. I used Gargoyle 1.5.10. Download it here. For the DIR-601 choose the AR71XX architecture. Search on the page to find 601-a1, choose factory.
  2. Reset your wired connection to accept DHCP.
  3. Log into your now Gargoyle router at 192.168.1.1. The default password is password.
  4. Set it up. It was pretty straight forward from here to get a client bridge going. What a breath of fresh air.
It works great with my Broadcom based access point (RT-N16). So far I've streamed an hour of Netflix with no problems.

A summary of what didn't work (at least for me):

  • DD-WRT (r16214 or r22118)
    • Client Bridge
    • WDS Station
  • OpenWRT (12.09-beta2 or 12.09)
    • pseudobridge (relayd)
    • WDS Station
  • Flashing anything from D-Link's firmware's GUI (not emergency) except DD-WRT r16214
  • Flashing anything from DD-WRT's GUI except DD-WRT
  • Gargoyle 1.5.11. It's too big. Nice to know it's still offered as a download for people who don't check before assuming a firmware is safe (me).

Friday, October 4, 2013

Academic Integrity

I'd like to post more often to the blog but two big things have happened in my life. First was the birth of our first child in May. She's a beautiful baby girl and is a light to our family. I'm so blessed to have her and my wonderful wife in my life. The second is my upcoming PhD dissertation defense that's scheduled for the 24th of October. Between those two things I've got a lot on my hands. I've got plenty of project ideas and I hope that once I settle into a job in January I'll get more up on the blog.

Despite my dissertation defense coming up in just 20 days, today I had to take some time to talk about academic integrity. And by talk I mean get some feelings off my chest because I'm just so annoyed right now. One of my most popular posts so far has been the MSP430 IR Remote Control. It was a ton of fun to do and I've got many more ideas on where to go from there. It was genuinely rewarding to watch that VCR turn on and off and to know that I did that. For that post I intentionally left the code off the site and unavailable unless you emailed me first. I did this for two reasons. First I'm just a sucker for getting emails from people. How fun! It gives me a chance to interact a little more with people who are working on using the IR transmitter for cool projects. I've had a blast hearing how it would be used. The second reason is one I take seriously. One of the big features of the MSP430 Launchpad pushed by Texas Instruments is its educational value. It's used by many universities in engineering courses to teach about microcontrollers and embedded systems. I did not want my work to become the way some student cheated through his engineering coursework or class project. Even without the code I feel like the post spells out pretty clearly the fundamentals you would need to get a project like this going.

Today I received the following email:
Hi, 
I have gone through your blog and found useful information regarding the IR receiver and codes used in the IR remotes. I'm working on an academic project and I need help regarding the code used for IR remotes using MSP430G2553 launchpad. So I thought I could get your assistance.
Thanks
I let the student know that I was happy to help and asked if it was for a class. I received the following reply:
Hi, 
Thanks for your reply. This is for the microprocessor class. I'm using sparkfun's IR remote and IR receiver breakout to communicate to launchpad controls. I'm using MSP430G2553 with CCS emulator. So could you please help me with coding this circuit using "C" language.
Thanks
Seriously? No. Of course not. Not in the way you intend me to. Do you have a specific question about how IR protocol works? Do you have a specific question about how I got something to work on the microcontroller? Or managed some problem you came across while coding? I'm happy to help. Do you want me to do your school project for you? Absolutely no.

I let the student know that I would not provide code and that his/her school's honor code prohibits such. To which I receive:
I do not need you to give me the code for it, you could at least tell me how to go about it, like what libraries to use and the flow diagram.

Thanks
I could at least... what?! I am under no obligation to tell anyone anything. I don't owe any reader more than what I've given. I don't even owe that. I could even remove content from my blog post if I feel like I'm giving too much to you. I think "you could at least" are the words that have bothered me more than any others through this exchange. Maybe "you could at least" have a solid measure of academic honesty in your work. And as far as "how to go about it" goes, I think the post gives more than enough information and that it speaks for itself. I'll link to it again.

At this point I was a little more blunt with the student. You need to read the material I linked to on the post. You need to struggle with the material. You need to make mistakes. That is how you learn. Your professor did not give you a class project to burden you or annoy you. Your project is not an exercise is getting by with as little work as possible by cobbling together others' work into something that maybe will work and that you surely don't understand. Your project is for you, believe it or not. It's for you to grow, make mistakes, ask yourself "what in the world?" a hundred times before that epiphany where you get it, and come out better for it. It's for you to learn. Just like your project, school itself is not some futile exercise on your way to that sweet engineering job you deserve with the six-figure salary you get from day one. It's for you to learn. And if you cheat, you're not fooling the school or your employer. You're not cleverly getting by those dumb restrictions that just aren't used in "the real world." You're cheating yourself out of the best opportunity you have right now to be something more than what you are right now. It takes a lot of hard work to do it right and a lot of time to do it all. That's precisely why it's worth doing. (I didn't say all of that to the student but some of the good bits.)

As a student myself for many years, I don't expect any less of myself or my peers than having high standards of academic honesty and integrity. Don't ask me or anyone else to do work for you. Do ask for help. Don't ask for work.

I've got a dissertation to write.

Sunday, June 2, 2013

OBD-II Adapter used with Snapshot from Progressive

I recently decided to look into car insurance rates again to make sure I wasn't overpaying. I do this maybe every 12 to 18 months or so. Progressive Auto Insurance gave a good quote and in it I was given the option to include Snapshot. It's a device to plug into your OBD-II port in your car. It reports back to Progressive via the AT&T cell network what time of day you drive, how you accelerate and how you brake. The device will make an audible beep if you brake to hard. I've previously written about devices you can plug into the ODB-II port of you car to log and monitor data from your car, in my case with the Torque Android app. It's fun and I haven't done too much analyzing log data but I may still.

I decided to wait on changing car insurance companies but I did decide to do a free 30 day trial of Snapshot. It would give me a sense of how it works and of how much more I could save off of Progressive's rate by letting them know how/when I drive. I got two of their devices in the mail for our two cars. My question was if I could have this and my own OBD-II device plugged in at the same time. I purchased this OBD-II splitter from Amazon because with just a 30 day trial I wouldn't have time for the long boat from China. I tried it out and it works! The Snapshot device will beep when the car first starts and again if you brake too hard. I noticed that the delay from car start-up to hearing the Snapshot start-up beep took longer when I had both devices plugged in. But it did beep. I also intentionally braked too hard to make it beep at me, which it did. All the while I was using Torque to read info from the car in real time. Great!

I can't guarantee that Snapshot would always work in this situation. With or without Snapshot, my own OBD-II device was able to read about 17 PIDs/second (PID is a command/response to/from the car). The Torque wiki of bluetooth adapters lists some that are capable of up to 60 PIDs/second. Assuming 60/s is the limit of the car, this suggests to me that Snapshot has plenty of time with my own adapter attached to get the information it needs. And I bet some cars have slower computers than others (i.e. have varying PID limits) so Snapshot doesn't have a problem with a slowdown due to my adapter sharing the bus. Also great!

There's no free lunch, though. That splitter cable is long. In one car it was causing the two adapters to dangle right next to where I would put my leg when braking. This is extremely dangerous! DO NOT DO THIS! Having things in the way of safely driving your car is NOT an option. If for whatever reason this scenario was something you absolutely needed, get the help of a professional to ensure the adapters and splitter are installed safely. The same goes for using your phone while driving. BE SAFE. When I use Torque I start it logging while the car is parked and then put it away while driving. Don't compromise safety.

TL;DR: The two adapters can be used at the same time. Maybe not with better, faster OBD-II adapters, though. And safety is always first.

UPDATE (2/11/2014):
So I made this test in November and December but there it is. We drove to/from Idaho for Thanksgiving and I captured data during the long trips. The csv files from the Torque app look great. But what about Snapshot? Was it capturing data, too? If you go to Progressive's website, you can look at the data. Here's what I saw for those trips:

You can see that I drove around 75 mph for a few hours, with some stops for lunch or gas. So the Snapshot device and my OBD-II adapter were both able to capture data at the same time.

Saturday, January 5, 2013

MSP430 IR Remote Control

In my post about giving up on using the FT232R for an IR transmitter, I mentioned using a MSP430 as a possible alternative. With the bug in my head, I needed to get this IR transmitter working and the MSP430 did it for me. Here is a list of the key things that helped me get it working with the MSP430G2553 microcontroller:

  • The MSP430G2553 had pre-calibrated data built in for setting the DCO (digitally controlled oscillator) frequency to an accurate 1, 8, 12, or 16 MHz. Using the 16 MHz settings made it very simple to get a very accurate 38 kHz IR frequency (or 57.6 kHz, or whatever), with moderately adjustable duty cycle. I'm using two compares on a single, up-count timer, each compare with its own ISR, for toggling the IR LED. That probably wasn't the right way to do PWM with the timer but it worked. I used the second timer to have the IR LED toggling at its rate for the right amount of time or to stay off for the right amount of time.
  • I knew what to transmit thanks to a few websites and writings:
    • http://www.hifi-remote.com/forums/dload.php?action=file&file_id=6996
      • This is a pdf describing IRP (infrared protocol) notation and how a IR signal is contructed  to send to a device. Click the download button to get the pdf. Very very helpful.
    • http://www.hifi-remote.com/jp1/lookup/
      • Universal remote controls use codes to program the remote to work with your equipment. This site lets you look up a code for a remote to find out what IRP protocol it's using and what EFC (extended function codes) goes to what function (power, channel+, etc.). You can also look up protocols and EFCs by the brand and type of device you want to control. You may get a big list and have to try more than one (just like when you program a real universal remote control).
    • http://www.hifi-remote.com/johnsfine/DecodeIR.html
      • This site lists the IRP for a ton of protocols you might find using the above lookup site or by examining an IR signal. Critical for getting the signal right. Common protocols you may have heard of include NEC1 and NEC2. My VCR used a JVC protocol.
    • http://www.hifi-remote.com/ofa/xref.shtml
      • This page translates EFCs to OBCs (original button codes). EFCs are for programming universal remotes. OBCs are for sending to the device itself. This was a major hangup for me when trying to figure out why I couldn't turn my VCR on. I was trying to send the EFC value, not the OBC value. Doh! I figured this out when I finally pulled out a TSOP38238 IR receiver, made by Vishay, to sanity check my transmitted signal and compare it to what my remote control was sending.
  • My poor-man's oscilloscope was a great help. I cut an audio cable so it had a 1/8" plug for plugging into my laptop's mic jack and bare wires on the other end. Audacity recorded the signal. I set my mic input to record at 192 kHz, giving a bandwidth of over 90 kHz. Mic inputs are AC coupled and I was measuring DC signals. This isn't a big deal for measuring the 38 kHz signal, that goes through without a problem. But when a DC value is held for a relatively long period of time, you can see the value go back to zero with some time constant (that I should have measured). Knowing what I was looking at and with the fast signals I was measuring, this wasn't a problem at all. I didn't need to measure voltages, just short time intervals. This worked for that. This is what also made me suspicious of my FT232R signal.
After figuring out the IRP for my JVC VCR, the device and function code I needed to send to it, and getting the IR frequency right, it worked like a charm!

Looking back now, when I gave up on using the FT232R, I didn't have the right data sent over IR. Maybe I'll go back and try again but, honestly, I don't think it is worth it. Watching a red LED with the FT232R flicker when it was supposed to stay at a steady, dim intensity doesn't give me a lot of hope that correcting that will solve the problem. And an MSP430 launchpad is less expensive than an FT232R, anyway.

Some things that would make the MSP430 an even better remote control (that I may or may not do):
  • The Launchpad allows your computer interface with the MSP430 device over a serial interface. Over the serial interface, one would give the MSP430 the IRP information and then give it the data to send using that protocol. Or have many common protocols preprogrammed and just tell it which one and the data. Then you could write a program that emulates a universal remote control. Press a button on the program, the launchpad transmits the corresponding signal.
  • Include the IR transmitter and a TSOP38238 (or others for other frequencies) in a launchpad booster pack for a transmitter/receiver/learner device.
  • Maybe turn it into a TV-B-Gone type device.
All of this was inspired by the USB Infrared Toy by Dangerous Prototypes. I didn't really feel like buying one and they ignore IRP for their sampling mode, which I think makes more sense for remote button presses. Using the information linked above, there wouldn't be a need to record a signal before being able to transmit it. And if you know the protocol, just giving the MSP430 the data to send using that protocol should be sufficient.

If your interested in the code, let me know. My email is on my "About me" page at the top. Right now it's preprogrammed to transmit a power on/off signal to a JVC VCR but that should be easy to change.

Wednesday, January 2, 2013

Giving Up on an IR Transmitter using the FT232R

I wrote previously about my trouble using the D2XX driver with MinGW. The reason I was doing this was to put the device into asynchronous bit-bang mode to drive an IR LED. This way I could turn my VCR on and off from my computer. No real reason why. Just for fun. Well I'm giving up on that. I'm just getting to much jitter to get a steady frequency for an IR driver. Allow me to explain.

When I tested out driving an LED with the D2XX driver in bit-bang mode, I could visibly see the LED flickering even though it was supposed to be steady and dim from using PWM. This shouldn't have been. FTDI wrote a helpful article explaining optimal transfer sizes for the D2XX driver (application note AN232B-03). In it is explained that there are 64 byte USB transfers, 62 of which are my data. Optimal transfers account for this. Also, the FT232R chip has a 128 byte transmit buffer, or 2 USB transfers. So data essentially needs to be streaming at a pretty steady rate over USB to get a steady output on the asynchronous bit-bang pins.

When I upped the baud rate, to something like 921600 or 1048576, it was clear that there was a 62 byte transfer, which toggled at the set rate, and then it was waiting for the next USB transfer, adding a noticeable delay. This delay varied between 21 μs and 75 μs. Now, assuming 90 μs USB transfers for each 64 byte transfer, that's almost 700 kB/s. That rate is more than fast enough for a 38.4 kHz IR signal. But when the baud rate was slowed down, the toggling output was not at a steady rate. I don't have good pictures from the oscilloscope to show but it was pretty bad. One bit might stay on for the expected 1/BaudRate seconds and then the next would stay on for three or four times that. Because of this, I don't feel like it would be effective to try to perform IR data streaming over USB using the FT232R.

In my previous post, I liked to this site, which is attempting to do the same thing. They have had some success but it is also clear that some people couldn't get their code to work with their FT232R setup. This, and the fact that I bought mine from China off of eBay, suggests to me that perhaps the surrounding components supporting my chip aren't that great, which wouldn't surprise me at all. I also can't put out of my mind that maybe the chip itself it counterfeit but I don't think that's the case.

What's my solution? Right now I think the best thing for me to try is to implement this on an MSP430, which would drive the LED, and communicate to it over a serial interface the parameters of the IR data stream. Maybe I would give the MSP430 the IRP and remote control button press data and it would send out the data accordingly. This is all for another day.

Sunday, November 4, 2012

AES Encryption on the MSP430 Launchpad

I recently got a couple of NRF24L01+ radios from my favorite auction site. They were less than $2 each, which is the main appeal for a tightwad like myself. And, frankly, for any project you want to use the least expensive components you can get away with, within reason. So I could a couple, if nothing else, to try them out. As I was reading the datasheet I found out that they do not handle packet encryption/decryption. The microcontroller would have to do that itself for the data of the packet, as far as I can tell. In many settings you may not even need encryption but I thought it would be nice. So I set out to find some existing code I could use to perform 256-bit AES encryption on my MSP430G2xx series microcontrollers (some the MSP430x5xx and MSP430x6xx chips have AES built in, as we'll talk about later).

Thanks to Bing and Wikipedia, I found this code which is meant to be a very portable, byte-level implementation. That's just what you want for a microcontroller. I tried it out first on my x86 machine using the demo given on the site. It worked great. Then I moved the code over to the MSP430. It didn't need any Modification for CCS to compile it and call the AES functions just like the demo code did. Looking at the buffers while debugging confirmed they were working great.

I was curious just how much time the encrypt and decrypt functions were taking on the MSP430 (specifically the MSP430G2553). CCS doesn't do code profiling for the MSP430 but it can count CPU cycles (while debugging go to Run->Clock->whatever). The problem with that is that it seriously slows down debugging can take forever for very long routines. I had it counting with the encrypt function for many minutes and it still hadn't finished. For a few lines at a time the break point overhead is about the same so you won't really notice and it does work well. A little searching and one solution that seems obvious in hindsight was to use the built in timer to count the cycles. Start the timer before the routine, stop it right after, and then check the register.

The MSP430 has, in general, a 16-bit timer so it can count to 2^16 or 65536 (I was really disappointed when I noticed my car's odometer rolled past that point by a couple hundred miles. That would have been a great picture). If you're sure your code takes less time than that, it's probably a close measure of how long it takes. If the timer overflows, then the register value is no good. I was suspecting overflow so I had the timer's ISR count the overflows. That adds some additional latency, making the count inaccurate, but I wanted a ballpark estimate, not something exact. Sure enough the timer was overflowing. It was overflowing 15 times! That's for encryption or decryption. At 1 MHz the darn thing was taking about 1 full second! No freaking way I could use that for a radio packet encryption tool.

Going back to the CCS cycle counter, if the function takes 1 second and I was waiting over 3 minutes for CCS to count its cycles, that means there's a huge overhead involved. Like orders of magnitude longer. For things that take a few hundred cycles, that's fine. Debugging overhead is high anyway and you might not notice. A million cycles, though, and it's not worth it. If CCS seems stuck on a function you know doesn't take long when it's counting cycles, that's a sign it's taking too long and you should probably use the timer.

The AES code has two ways of performing encryption and decryption. The first generates some needed numbers using functions and the other uses a couple of big look-up tables. The trade-offs are processing time versus memory consumption. Everything above was tested using function calls. I switched the code to use the look-up tables and the program needed an additional 236 bytes for program space. Not terrible but keep in mind the MSP430Gx series has max 16kB flash and some have as little as 2kB. That could also change with optimization. When I timed it again using look-up tables there were zero overflows. The encryption and decryption functions had a speedup of about 50x! They were taking around 20ms when running at 1 MHz. That's a little more manageable. I'm sure there's room for improvement, too. The compiler is also nice enough to give me some "Infos" on where code could run faster if it were rewritten a little. Not today, though.

So, in summary, look-up tables can definitely be worth the additional memory cost. That's been known forever but this was a real eye opener for me to learn that lesson personally. I wouldn't say I learned it the hard way because someone already wrote those tables for me. Thanks to Ilya O. Levin and Hal Finney for the AES code they wrote. Also, it's no wonder they put AES into instruction sets and make hardware accelerators. It can a lot of cycles. If you look in the MSP430x5xx and MSP430x6xx Family User's Guide, for example, it says that its AES accelerator (for 128-bit keys) takes as few as 167 MCLK cycles. So using look-up tables was a couple of orders of magnitude faster than without and using a hardware accelerator is a couple orders of magnitude faster than that. Wow.

And that's one more thing...
Quantified!
(Yeah, it's not on an image. But it's fun anyway)