Bryan Mayland

This user hasn't shared any biographical information

Homepage: http://capnbry.net


Posts by Bryan Mayland

Analog Reference switching time with a 0.1uF capacitor at 3.3V

When AREF isn’t AREF (yet)

I’d often noticed that measuring analog inputs on my ATmega, that the first round of values usually differed substantially from subsequent values. The datasheet even warns of a similiar-sounding issue:

The first ADC conversion result after switching reference voltage source may be inaccurate, and the user is advised to discard this result.

Knowing that the Arduino libraries don’t actually set the reference voltage until the time the first sample is made, it seemed logical that these first samples were an artifact of the voltage changing. However, it wasn’t just the first sample, or the first couple samples. It could take dozens of samples before the value returned had stabilized (i.e. stopped increasing by more than 2 LSB). Being a boot-only issue. I was content to ignore it until I started trying to read the on-chip temperature sensor.
More >

Construction complete!

Grill Control Project Part 3

Hardware construction time. Note: this is for the v3 version of the HeaterMeter controller.

I ordered the Arduino Duemilanove and buttons from SparkFun, the WiShield 2.0 from AsyncLabs, and the components and blower from DigiKey. What you end up with is a whole dining room table full of parts.

It helps to not be married if your dining room table is going to look like this for a week.


More >

The Arduino Duemilanove Hadware Platform

Grill Control Project Part 2

Based on Bob’s lead, I chose the Arduino platform as my microcontroller. Specifically the Arduino Duemilanove.

The Arduino Duemilanove Hadware Platform

  • ATmel ATmega168 Micocontroller
  • RISC 8-bit CPU running at 16MHz / 5V
  • 32kB code space (30,720 bytes usable)
  • 2kB RAM
  • 1kB Flash storage EEPROM
  • Integrated ADC, Digital PWM, SPI bus interface, UART TTL Serial
  • C/C++ programming environment

Yeah 2kB of RAM. For comparison, my blog front page is currently 250 times that. 30kB of usable code space? The default Delphi Project1.exe baseline with no user code is 13 times as large. Squeezing everything in to that space seems like a challenge: a web server, LCD and buttons with a menuing system, and I reckon it should control a grill too.

This post was going to be about the platform, but that’s boring. Let’s just jump into the project and I’ll introduce things as needed.
More >

The ACG Happiness Scale

Software Guy Builds Hardware

or: How I Learned to Stop Working at Making Things Burn, the Great Grill Control Project part 1.

Foods cooked on the grill are at the top of my food chain. I am a main predator of Kingdom Animalia, Phylum Grilledatas. The problem with grilling is that the grill is outside, in a place where it is usually hot, far away from my beer, and entertainment-starved unless observing the negative gravitropism of stenotaphrum secundatum is your thing. Barbecue further aggravates the situation by requiring long cook times which may even necessitate losing sleep. Sure you can “barbecue” in an oven, “barbecue” cooked in an oven isn’t barbecue all and bears as much resemblance to the real deal as K-rab does to stone crab. There has to be smoke, and the easiest way I know to get smoke it to light something on fire.

Contrary to what Frankenstein says, fire isn’t always bad, but it can require a good bit of fiddling make it do what you want, sort of light plate spinning. It certainly is a lot easier than plate spinning and you can’t eat anything when you’re done spinning plates for 8 hours, so I’m not sure why I used that analogy. Anyway, I’ve tried the Alton Brown Electric Pot smoker concept, which produced lackluster results even after several attempts and equipment swaps. The initial solution was to step up to the big leagues and buy a Big Green Egg, the self-described “World’s Best Smoker and Grill!” (emphasis theirs).
More >

Proper Timing with GetTickCount()

Often programmers are faced with implementing timers for short-period operations, anywhere from the sub-second to a few hours. These sort of timers are typically used in timeout operations, like idle connection timeouts, stale cache timeouts, and fade timers, but are also used in basic discrete physics calculations, input debounce timers, and timeslice allocations. In these applications I like using GetTickCount().

More information on why I like it and why to choose it over other timing options follow after the break.
More >

Runtime Themes Project Options

How TaskDialogIndirect() can turn Cancel into Yes

User Interface designers are rather sadistic. In the year 3000, when suicide booths will be commonplace, a User Interface designer will be the sort of fellow who places the “Stab Me to Death” button adjacent to the “Enjoy a Lovely Cup of Tea” button on the Slurp ‘N Spear vending machine down at the local Automat. If you’re interested in getting repeat business, you’ll probably want to confirm that the consumer would rather purchase a gut full of twisting metal instead of a mouthful of dried leaves in water.

Consider the following code analog to this situation, where the Delete button looks too much like, or is placed to close to the Save button in a toolbar. As a defensive programmer you safeguard the delete function with a confirmation:

  if MessageDlg('This action is not undoable.'#13 +
    'Are you sure you want to delete all your work?',
    mtConfirmation, [mbYes,mbNo], 0) = mrNo then
    exit;

  DoDeleteAllYourWork();

This works fine and the early bailout situation is preferable in my book when the code of DoDeleteAllYourWork() actually follows inline. The code is written, compiled, shipped and you forget all about it until a few years later someone calls up spitting venom because they pressed Escape and your app deleted their work. What has occurred is a subtle issue created by Delphi switching from their own MessageDlg to Vista’s powerful TaskDialogIndirect() API when you enable runtime themes in your project options.

Runtime Themes Project Options

The little check with 100 implications


More >

Determining ThreadingModel in a Delphi Application

I has occurred to me that someone might need to determine their COM threading model from inside their application. This could be useful for some ASSERT() code or perhaps as part of a unit test. From my last blog post, you’ll recall that this information is stored in an opaque structure located in each thread’s Thread Environment Block (TEB). Actually quite simple to do, with original credit going to John Robbins’ Bugslayer Column from the old MSJ magazine.

{
uses ActiveX;
Ported from John Robbins - Microsoft Systems Journal Bugslayer Column - October '99

http://www.microsoft.com/msj/1099/bugslayer/bugslayer1099.aspx

}
function DebugCoGetThreadingModel : integer;
const
  OLE_APT_MASK  = $0080;
  OLE_FREE_MASK = $0140;
var
  dwOLETLS: Cardinal;
  dwFlags:  Cardinal;
begin

  asm
    // Get TEB
    mov eax, FS:[018h]
    mov eax, [eax+0f80h]
    mov dwOLETLS, eax
  end;

  { Not initialized }
  if dwOLETLS = 0 then begin
    Result := -1;
    exit;
  end;

  dwFlags := PCardinal((dwOLETLS + $0C))^;

  if ((dwFlags and OLE_APT_MASK) = OLE_APT_MASK) then
    Result := COINIT_APARTMENTTHREADED

  else if ((dwFlags and OLE_FREE_MASK) = OLE_FREE_MASK) then
    Result := COINIT_MULTITHREADED

  { Unknown }
  else
    Result := -2;
end;

And some sample usage code

  case DebugCoGetThreadingModel of
    -2: Label1.Caption := 'Unknown';
    -1: Label1.Caption := 'Not initialized';
    COINIT_APARTMENTTHREADED: Label1.Caption := 'COINIT_APARTMENTTHREADED';
    COINIT_MULTITHREADED: Label1.Caption := 'COINIT_MULTITHREADED';
  end;

John also has an excellent blog of his own which is which is a fantastic low-level technical resource. Speaking of old magazines, I just discovered the Bug of the Month ad that has appeared in Dr Dobbs for nearly the past 20 years has an online archive. Head over to Gimpel Software if you’re up for some C-based brain exercises.

Delphi WinDbg Project Option

Debugging a Delphi Lockup with Windbg

While the Delphi debugger is quite good, there are some instances when it isn’t quite good enough.

  • Your application is crashing remotely The worst place for an application to fail is when there is no debugger available. Usually these problems can be corrected via the “Works Fine Here” solution. Unfortunately most bug-tracking systems lack this option to close tickets.
  • Lack of symbol information The best trace you can get in the debugger shows a thread balls deep into Windows API calls for no apparent reason. Some resolution can be gained from the DLL export addresses but without proper symbol information this isn’t enough detail.

The solution to both these scenarios is to use Microsoft’s free debugger WinDbg, available as part of the Debugging Tools for Windows package. You’ll need the version for the host platform where the trace will occur. This means get the 64-bit if you’re debugging on Win64 even if your app is 32-bit. You’ll also need the map2dbg utility, originally by Lucian Wischik.
More >

Who is CapnBry?

This is my first ever blog post in having been on the Internet now for 17 years. I’ve been encouraged to create a development blog to share things that I learn. I’ve found so much great information on the Internet from blogs that I’ve finally decided to commit to keeping one up. I do this for two reasons:

  • Hopefully share knowledge with someone else who has run into the same problem I have.
  • Provide a repository where I can remember the solutions to problems I’ve had, because I might have to use them again.

Let’s start with some information about who I am.
More >