Human factors and ramen

Optimizing the transfer charactaristic of a resistive-transducer-based voltage divider for ATD reads

Many applications of thermistors and other resistive transducers involve reading their voltage into a microcontroller through an ATD converter. Setting this up involves designing a circuit that shifts and contorts the transfer characteristic of the transducer into a range the ATD accepts.  While circuits that map precisely to an ATD's range are well-known (TI paper), the output of a simple resistive voltage divider may map the transducer's output to enough steps of the ATD's range that sufficient precision is attained for the application. A major benefit of using a voltage divider is it's simplicity; the only additional components it needs are a source (I use VCC from my microcontroller), a resistor, and possibly a diode if overloading the ATD is a concern. This post demonstrates how I calculated the best static resistance to use to obtain the widest possible voltage range for my thermistor in this circuit.
If we connect a V_S -volt source in series with a variable resistance R_T and some constant resistance R_K , the voltage drop across the transducer will be \frac{R_T}{R_T+R_K}\cdot V_S\ \ \text{V}. Conveniently, this function is monotonically increasing along positives, meaning maximum voltage drop will occur when R_T is at it's highest, and minimum voltage drop when it is at it's lowest. The span of voltages the transducer will take on is then:

|V|(R_K) = \left[\frac{R_{T_\text{max}}}{R_{T_\text{max}}+R_K} - \frac{R_{T_\text{min}}}{R_{T_\text{min}}+R_K}\right]\cdot V_S \ \ \text{V}

Since we want to maximize this value, we must differentiate it and find the positive root for variable R_K :

\frac{\partial |V|}{\partial R_K}=\left[\frac{R_{T_{\text{max}}}}{(R_{T_{\text{max}}}+R_K)^2}-\frac{R_{T_{\text{min}}}}{(R_{T_{\text{min}}}+R_K)^2}\right]\cdot V_S = 0

\ldots \Rightarrow R_K = \sqrt{R_{T_{\text{max}}}}\cdot \sqrt{R_{T_{\text{min}}}}\Omega

The thermistors I am using fluctuate between 5 and 10kΩ under normal operating conditions, so my optimal resistance would be \sqrt{5}\cdot\sqrt{10}\text{k}\Omega , or about 7kΩ. They will be powered by my microcontroller's built-in 5.12V source, so the thermistor will span \left[\frac{10\text{k}\Omega}{10\text{k}\Omega+7\text{k}\Omega} - \frac{5\text{k}\Omega}{5\text{k}\Omega+7\text{k}\Omega}\right]\cdot 5.12 \text{V} \approx 0.878 \text{V}. The ATD module reads from 0 to 5.12V in 0.005V increments (10 bits), so I will get \lfloor\frac{0.878}{0.005}\rfloor=175\ \text{steps} of accuracy. Pretty good for a simple voltage divider!

To ensure that a power surge doesn't fry the ATD, I have installed a 5.1V Zener diode in parallel with the thermistor's leads where the ATD is hooked up.

Programming a 68HCS12 in Assembly

Recently I have been working on a research project at the NCSU OSL to design, construct and test a blackbody radiator for the calibration of IR cameras. It will essentially be device that holds a 4*4in surface at a constant temperature using thermistors to read the temperature and thermoelectric coolers to sustain the temperature. These components will be interfaced by a Technological Arts NanoCore12 prototyping board, which is built around a Freescale 68HCS12, a descendant of the old Motorola 6800.

My supervising professor said that assembly language is best suited for this project, so over the past several weeks I have been picking up this architecture's dialect. It's been my first exposure to assembly so I've hit a few speed bumps along the way, many due to my being stuck in a different frame of mind coming from higher level languages like C++ and Java. There is a stark difference in workflow coming from purely software-based environments with step-through debuggers and loads of example code to one where the only relevant documentation is buried in a maze of manuals. Here is a list of the most important things I've learned so far from working on a prototyping board:

1) Check and re-check all your bread-boarded circuits until your eyes are sore before you supply voltage to them, and go ask for help as soon as you get stuck.

At the beginning of last week I shorted some leads on a live board for several hours, but didn't cognize that I was doing so until much later. I spent the remainder of the week glazing over extremely basic code to blink an onboard LED on and off with respect to an input voltage. To my dismay, the processor started overheating to egg-frying temperatures under no load and the LED wouldn't turn off consistently. After way too much time of not getting anywhere I took the problem to my professor and he concluded in under an hour that the board's Analog to Digital module was fried, along with some other parts. This colossal time sink would never have occurred had I just installed some resistors near the voltage source (or had just went and asked my professor sooner).

2) Simulators are not debuggers.

One of the most indispensable tools I have used in this project is a processor simulator similar to the one found here. For a while I treated this tool like an on-board debugger that I so long for in the assembly environment. However, since the simulator only reproduces the architecture's processing instructions and not any processor modules, the simulator's response doesn't always perfectly correspond to what the board's actual behavior, especially in situations like #1. My workflow so far has been to get the code working in the simulator first, then start mucking around in module documentation when it doesn't work in real life.

3) Change only one thing per trial during experiments.

After I got a new board to work on, my blink code still didn't work. I somehow convinced myself that I wasn't properly implementing subroutine returns, and that the ATD module was misconfigured. I mangled these areas of my code in all kinds of different ways to try and figure out what was wrong. Out of desperation I decided to mentally step through every single line of code and think about the operation's definition in the architecture documentation, and the description in module documentation of the register the operation acted on. Only after grilling every relevant codeblock line-for-line in this manner did I realize that that it was because while the ATD output was unsigned, I was comparing values using a signed check (BLE/BHE instead of BLS/BHS). Virtually no abstraction happens within the syntax, so there is nothing to stop you from comparing apples to oranges since they are all basically just bits. In retrospect, I can't really think of how I would have found the problem without going through that process, but I would have arrived to it with much less grief if I had tried the systematic, controlled approach first.

4) Make your source code verbose.

6800 assembly is the ugliest language I have ever seen in real life, and I'm sure most other assembly dialects are about the same. It is difficult to write readable assembly for many reasons. Everything is in structured in columns, but consistent delimiters are not enforced (e.g. Python) so if you copy and paste your code anywhere there's a fairly high chance your lines will get stretched all over the place. The length constraint (around 6 chars) of labels, your only way of assigning names to things, is not long enough to allow for anything descriptive. I am still developing my style but so far I have settled on a few no-brainer guidelines:

  • Keep your source code along with the processor's documentation files and for every line you write to a settings register, add a comment with the relevant documentation's filename, page number, and the options you meant to set.
  • Every time you label an acronym, add a comment that expands the acronym.
  • Keep everything in blocks with comments above them. You can't indent your code, but at least you can indent your comments.
  • Try and structure things like a sane language. Encapsulate what would normally be a function using labeled subroutines. Describe each subroutine with a comment.
  • If you run out of good names, start a name table in a separate file.
  • Comment everywhere!

I have wasted a good deal of time trying to decipher my own code because I though it was obvious at the time of writing. You can save yourself by writing comments better comments than I did!

Learning to write assembly has been very rewarding so far. Hopefully my experience will help other beginners gain some insight on how to approach coding in assembly language.

UZBLSMS: A way to browse the web via text-message

UZBLSMS is a basic Python utility you can run on a Linux computer that allows you to view and control a web browser via anything that is capable of sending SMS messages and receiving MMS. This effectively means that with this software, you can browse the web through a dumbphone without a data plan, just as long as you have unlimited texting. Even though my original intention was to use it with the UZBL browser, you can really use it with any software you would like as long as it can be controlled entirely by keyboard shortcuts.

Most of its functionality and warts are discussed in the README, but I'll reiterate the basics right here. Here's how it works:

  1. You configure the software by changing, then run whatever piece of software you want on some X display.
  2. Run with the X display in the parameters.
  3. Text a series of keystrokes to your GMail account. (Phone-specific, but it can be done on the LG Cosmos by typing an email address into the recipients field)
  4. mimics your keystrokes on the X display, waits a few seconds for things to settle, screenshots the display you specified, then sends the screenshot to your phone via a SMS gateway. (Carrier specific. Most major carriers have them)
  5. Repeat!

I have used this software to update my Facebook status in a place with no reliable internet reception! In my experience, lag is not as terrible as you would expect. I generally received screenshots about 10 or 20 seconds after the keystrokes were sent.


This code is published under the FreeBSD license.

Known issues:

  • It stops accepting commands after being idle for a period of 30 minutes or so. I am almost certain this is due to some trivial X-server misconfiguration, but I could not figure it out conclusively.
  • It relies fairly heavily on external dependencies like ImageMagick.
  • For some reason I chose to write it in Python 3. In retrospect it would probably be good to have started with a more established language like Python 2.

NCSU Registration Process

One can draw parallels to registering for classes at North Carolina State and spawning on the wrong side of the Hoover dam. For future reference, here is a list of all the 'gates' that had to be lifted before I could register for Summer II 2012 classes. Most, if not all of these probably apply to any incoming Freshmen working towards a major.

Gate 1) Admission and Initiation: You need to get your application accepted to before anything. Once this is done you should have a WolfPaw account and a MyPackPortal thing set up.

Gate 2) Advanced enrollment fee: You pay $200 or whatever to confirm that you are indeed going to NCSU, not anywhere else. I payed through WolfPaw although there are probably redundant facilities for it in the MyPack Portal.

Gate 3) Freshman Matriculation: Now that you have entered all your accounts and stuff, the NC State needs to register them into it's system. You have basically no control over when this happens so it's up to the administration. Try asking someone at Admissions.

Gate 4) Transfer Credits Matriculation: Have college credits from high school or community college included in your NCSU application? Even if you had gotten your official transcripts sent to NC State quite a while ago, they won't be associated with your account until some internal date a set time before the semester starts. Again, this is up to the administration.

Gate 5) Enrollment Date: State makes you wait until a certain date before you can enroll for classes. The day and time of this 'enrollment date' depend on how many credits you have. The incentive behind this is that they want to give the first choice of classes up to people who have almost completed their degree; how horrible would it be if you were a Senior with one Fresman-level class left that you couldn't get into because it filled up? Coming in as a Freshman with no credits, you are basically the bottom feeder of all enrolling parties. Once you have passed Gate 3, you will be able to see your enrollment date on the MyPack Portal.

Gate 6) Enrollment Appointment: Besides the enrollment date, you must also get a seal of approval from your undergraduate adviser for any courses you wish to take. However unnecessary it may seem, this step is mandatory. Check on your department's sub-website to find out who your adviser is, then set up a personal meeting with him/her. Note that this can be done before your enrollment date has passed, but not before Gate 3. The meeting will go more smoothly if you prepare a class plan ahead of time through the MyPack Portal's 'Plan of Work' facilities. [You will probably want to wait until after Gate 4 to make your class plan].

Gate 7) Placement Tests: Some classes like introductory mathematics, engineering, computer science or chemistry require you to take a remedial course (Like ECE115 or CH111) to account for what knowledge may have fallen between the cracks during High School or AP classes. Thankfully, NC State offers some online Pass/Fail tests that will place you out of such classes. These exams may only be taken once, although they won't be a source for much of your stress provided you know the material. Perhaps this is something to talk about during the meeting you have with your adviser.

I jumped through the first six hoops over the course of several months, and am now studying for a few of the tests in Gate 7.

Custom Label Colors in Gmail

Some of you may have noticed that after Gmail's theme switch a few months ago, users are now unable to easily specify the color of mail labels.  Instead we are presented with a limited and somewhat ugly palate:

Gmail label color palate

Gmail label color palate

In my fooling around with the internet I discovered that you can specify custom colors in RGB using nothing more than some simple HTML injection.  The palate is displayed as three tables, each cell with it's own background color. It turns out that the color sent to Google is determined by the background color as specified by the client version of the web page. There is nothing stopping you from changing these values.  Here is a demonstration of how you could perform such a change using Firefox and Firebug:

Now your inbox can be less ugly.

OTF Ghostscript Fonts

Ghostscript is a free software suite that provides libraries to help your computer explain your printer how you would like things to show up on a piece of paper. Somewhere along it's development, a typography company called URW++ decided to contribute a sizable pack of fonts to the project. The group of fonts is very nice because it includes near-replicas of typefaces like Helvetica (Nimbus Sans L) but, unlike Helvetica, is free. Unfortunately, it looks like not very many people have taken interest in the collection so it hasn't been distributed much outside of Linux distributions.

I am currently stuck on a Windows machine so I don't have easy access to these fonts. In my rummaging around the internet I couldn't find any copies of the typefaces in a format that would install on Windows so I decided to make some. I took copies of the fonts from a Linux distribution and converted them to OTF. Here is the resulting font pack:
Direct link

The tarball contains the following families:
URW Bookman
URW Century Schoolbook
URW Gothic
URW Nimbus (Sans, Mono, and Roman)
URW Palladio

Because they are all in OTF, they can be installed on Windows. They may look a little wonky in your word processor but that is most probably because of a rendering issue; if you are super anal-retentive and want to be sure, convert your document to a PDF or SVG and examine the font in that format before printing.

Hello world!

Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!