Writing

Feed Software, technology, sysadmin war stories, and more.

Friday, April 6, 2012

Stymied by a trivial microcontroller display problem

Some time back, there was a question going around in a certain circle where I used to participate. One of the members had just acquired one of those microcontroller boards used for small hack projects and needed to print digits. I was looped in because it was C and people knew that I tended to write stuff in that language. Oh boy.

It was introduced to me as a routine that needs a "varchar" and that this individual wanted to print the numbers 0-9 repeating. They had rigged up a for loop that ran from 48 to 58 and needed to "print the ascii type of that decimal number, 0=48, 1=49, etc".

I said, okay, %c is what you want, then.

Apparently this didn't quite help, so the next thing I said was a simple loop like this: for (i = 48; i < 58; i++) { printf ("%c "); }

Then I found out that was no good, since this thing didn't use printf. It used some custom print function which was specific to the hardware. Okay, great. I had no idea what that was or how it would behave.

Further probing established that it took an int called value. I figured, okay, it could be 0-9, and if you're being given 48-58 and need 0-9, then it's just a matter of subtraction (and dealing with your fencepost error, but that's neither here nor there) . That wasn't it, either. I was informed that this person was "creating 48-58 in order to print 0-9".

I asked a different variant: you're being given a 0 and want 48 back from it? Or you're given 1 and want a 49? Isn't that addition?

After some unhelpful probing, I finally said that I don't think the whole picture was being described to me, since it sounded like there was a function which renders things based on ASCII values, and some kind of use case for displaying numerals on the display. I decided to come at it as more of a black box instead of relying on them to cough up pertinent details.

I asked: if you send 85 to this function, do you get a "U"? That much was confirmed, so now I understood what was going on. This person was doing some math, was getting back an integer of some sort, and needed to shift it out to the display. (Note the word shift back there. It's important later.)

So then I explained it another way and added a question: if you have an int equal to 12345, and you want to put it on the display, do you write "1", "2", "3", "4", "5" in that order, or do you send it backwards? I figured anything was possible so it was best to ask. The reply: send it as 1,2,3,4,5. Okay then.

This meant they were going to need to pop the numbers off left to right, and that's always interesting. I said that this was either going to call for some recursion, some clever loop work or some string wrangling. This was another one of those "dog shown a card trick" moments, so I asked for a moment and dashed off something really stupid which would pop digits off with integer division and recursion. The recursive part was basically this:

void digit(unsigned long val) {
  if (val == 0) {
    return;
  }
 
  digit(val / 10);
  printf("send to device: %ld (ASCII value %ld)\n",
         val % 10, (val % 10) + 48);
}

(See, I told you it was stupid. And it looks like it fails for an actual zero. Oops.)

A question was raised: couldn't this be done with sprintf? My answer was: sure, if you want. That's the "string wrangling" option, but it does mean you have to go from an int, to an array of chars, to individual chars, to the device. My approach would keep everything strictly numeric.

Even this didn't really go over well. I'm not sure if they ever "got" what I was trying to convey. The whole thing about having to shift digits out a certain way due to the way numbers work relative to how the display takes input seemed to be completely missed.

This person had a reputation for being some kind of uber-l33t hax0r, but they had no way to come up with "itoa" on their own. That startled and confused me. How could this be?

I mean, this was one of the ridiculously stupid questions which had come up in Joel Spolsky's first guerrilla guide to interviewing way back in 2000! Scroll way down to his list: itoa is #7 and it even notes "great, because they have to use a stack or strrev".

I figured that such a notorious beast of a programmer must have encountered this dumb little list in the years since it had been published, but apparently not.

That FizzBuzz story seems even more plausible now, doesn't it?