May 082016

This post continues the tear down and reverse engineering of the Acurite 0077XW / 00592TX Wireless Remote Temperature Probe Part 1 & Part 2 & Part 3.

A small update to the decoding of the bit stream coming from the remote temperature probes.

It occurred to me the base station has an indicator of remote probe battery condition:

Remote Battery Indicator

If the base station can display the remote probe battery status, or at least low battery condition, the remote probe must be sending battery status as part of the data stream.

To test the idea that the remote probe sends a low battery status I removed the batteries from a remote probe and hooked up a variable power supply to the battery connections in the remote probe.

I loaded the bit stream decoder from my github repo and watched the bits from the remote probe.

I started with the variable supply set to 3V to match two fresh alkaline batteries. With the voltage at 3V the probe sent the familiar bit stream decoded in Part 3 of this series.

Remote Probe Battery voltage at 3V.

38,6c,44,90,09,50,d1,111000,1101100,1000100,10010000,1001,1010000,11010001,208,695,5836668 38,6c,44,90,09,d1,52,111000,1101100,1000100,10010000,1001,11010001,1010010,209,697,5853130 38,6c,44,90,09,d1,52,111000,1101100,1000100,10010000,1001,11010001,1010010,209,697,5869592

After getting stable readings I started turning down the voltage at the power supply to simulate low batteries. At around 2.5V the pattern changed:

Remote Probe Battery voltage at 2.4V.

38,6c,84,90,09,50,11,111000,1101100,10000100,10010000,1001,1010000,10001,208,695,6100054 38,6c,84,90,09,50,11,111000,1101100,10000100,10010000,1001,1010000,10001,208,695,6116509 38,6c,84,90,09,50,11,111000,1101100,10000100,10010000,1001,1010000,10001,208,695,6132973

Notice in the third byte bits 7 and 6 flip from 0 to 1 and 1 to 0 when the voltage drops below ~2.4V. The byte 0x44 changes to 0x84. The change of the upper nybble from 4 to 8 and back again is repeatable and consistent around 2.4 volts.

In Part 3 of this series I posted that the first and second bytes are the ID bytes, the fifth and sixth bytes are temperature, the seventh byte the checksum, and that the third and fourth bytes never change. During my earlier work I was using fresh batteries in all of the modules and never saw a change in the 3rd and 4th bytes. With a variable power supply hooked up to the probe I am able to simulate a low battery condition and observe a change in the 3rd byte.

Given this new information I can monitor the battery health of the remote probes and change batteries as needed. Monitoring the battery level also gives some insight into battery longevity at different temperatures. I will update my logging to capture battery low indication over time and temperature. I have some probes inside the house and some outside. It will be interesting to see how the batteries discharge compared to temperature history.

The first and second bytes of the data are the unique probe address. The upper two bits of the first byte are the probe channel indicator:

11 = channel A 10 = channel B 00 = channel C

The remaining 6 bits of the first byte and the 8 bits of the second byte are a unique identifier per probe.

The upper nybble of the third byte carries the remote probe low battery indication.

When the remote probe batteries are fresh, voltage above 2.5V, the third byte is 0x44. When the remote probe batteries get low, below 2.4V, the third byte changes to 0x84.

The fourth byte continues to stay at 0x90 for all conditions.

The next two bytes are the temperature value. The temperature is encoded as the lower 7 bits of both bytes with the most significant bit being an even parity bit. The MSB will be set if required to insure an even number of bits are set to 1 in the byte. If the least significant seven bits have an even number of 1 bits set the MSB will be 0, otherwise the MSB will be set to 1 to insure an even number of bits.

The last byte is a simple running sum, modulo 256, of the previous 6 data bytes.

Some other interesting blogs and posts on hacking the Acurite probes:

RF sniffing the Acurite data stream Acurite data stream reverse engineering OregonScientific-RF-Protocols-II.pdf Rays Hobby (great info here)

I hope this series was helpful and if you have any comments, questions, or suggestions please leave a comment below.

Feb 262015

This post continues the tear down and reverse engineering of the Acurite 0077XW / 00592TX Wireless Remote Temperature Probe Part 1 & Part 2.

After tearing apart the wireless temperature base station and seeing the straightforward electrical connection between the radio module and the base station logic board, Part 1, and then picking apart the remote probe temperature data protocol, Part 2, I was ready to read the wireless data into a microcontroller.

Given that I want to receive the data from the probes wirelessly then I am going to need a wireless receiver. Also given that I purchased 3 probe plus base station combos just to get the 3 probes I have extra base stations I wont be using. The obvious answer is to pull the wireless module from one of the base stations.

The surgery was pretty straightforward. I desoldered a wireless module from the ribbon cable in the base station, cleaned the solder out of the holes, and soldered in a 4 pin header so I could plug the module into a breadboard.



I plugged the wireless module into a breadboard with an Arduino Pro Mini 3.3V and an oled display.

For this exercise ignore the oled display and the wiring on the backside of the breadboard. We are only interested in the four wires going from the Arduino to the wireless module. The red wire is 3.3 volts, the black wire is ground, the yellow wire goes from D on the wireless module to digital pin D3 on the Pro Mini, and the green wire goes from SH on the wireless module to digital pin D4 on the Pro Mini.


The squelch pin (SH) is an input to the wireless module and so is configured as an output on the Arduino.

The data pin (D) is an output from the wireless module and so is configured as an input on the Arduino.

Arduino pin D3 was specifically chosen as the data input as it is a change triggerable interrupt pin. The bit stream from the probe is captured by the Arduino by taking an interrupt on every level change of the data line from the wireless module and measuring the time from the last change in the data stream to this change. This allows the Pro Mini to measure the width of the high and low parts of each pulse and determine if the pulse is a data sync or data bit.

It is known that interesting pulses are close to 0.2 msec, 0.4 msec, and 0.61 msec long. Pulses that are significantly shorter than 0.2 msec or significantly longer than 0.61 msec are not interesting, are not part of the data stream, and signify the data stream is not yet in sync and Pro Mini should be looking for the data sync pulses.

It is known that the start of the interesting data, the data sync, is eight 0.61 msec pulses in a row. The data sync consists of a 0.61 msec high pulse followed by a 0.61 msec low pulse, with this combination repeated four times.

Since the Pro Mini interrupt pin is configured for change, every time the interrupt is called you can assume there is a change from high to low or low to high on the data line. If the Pro Mini measures the time between every interrupt and every sees eight 0.61 msec times in a row that indicates a data sync has been seen. If a data sync is seen the Pro Mini should immediately start measuring pulse times until 56 data bits, or 112 edges (interrupts) are counted.

Once the 112 high or low pulses are counted the data is filtered two pulses at a time to determine if a 0 or a 1 bit was detected. If the captured pulse stream is a 0.4 msec pulse followed by a 0.2 msec pulse a logic high (1) is recorded. If a 0.2 msec pulse followed by a 0.4 msec pulse is detected then a logic low (0) is recorded. All 112 pulses give the 56 bits or 7 data bytes of the data stream.

Once the data stream is recorded the bytes can be decoded as follows:

The first and second bytes of the data are the unique probe address. The upper two bits of the first byte are the probe channel indicator:

11 = channel A 10 = channel B 00 = channel C

The remaining 6 bits of the first byte and the 8 bits of the second byte are a unique identifier per probe.

[strike]The next two bytes are always 0x44 followed by 0x90, for all of the probes I tested (a sample of 6 probes).[/strike]

[update – see Part 4]
The upper nybble of the third byte carries the remote probe low battery indication.

When the remote probe batteries are fresh, voltage above 2.5V, the third byte is 0x44.
When the remote probe batteries get low, below 2.4V, the third byte changes to 0x84.

The fourth byte continues to stay at 0x90 for all conditions.

The next two bytes are the temperature value. The temperature is encoded as the lower 7 bits of both bytes with the most significant bit being an even parity bit. The MSB will be set if required to insure an even number of bits are set to 1 in the byte. If the least significant seven bits have an even number of 1 bits set the MSB will be 0, otherwise the MSB will be set to 1 to insure an even number of bits.

The last byte is a simple running sum, modulo 256, of the previous 6 data bytes.

Code to capture and decode the bit stream can be found at my github repo.

I’ve created a spreadsheet ProbeX6.xls to paste the decoded data into to check the checksum of each transmission and decode the temperature data.

Decoded data from four different probes is shown here. The data is formatted as hex codes decoded and emitted by the Pro Mini followed by the same data in binary format, and then the calculated temperature.


One thing to keep in mind is that each probe requires a “correction factor” to convert from the probe reading to the correct temperature. After having such success with this portion of the project I went out and purchased three more probe / base station modules. I checked all six probes and each had a different offset to convert from sensor reading to actual temperature.



The next step is to pull the data into a RasPi and create a presentation layer to map temperatures around my house. The first part of this project, the reverse engineering and decoding of the 00592TX protocol was a blast. I expect the next phase of the project, the RasPi and data warehousing to be just as much fun.

I hope this series was helpful and if you have any comments, questions, or suggestions please leave a comment below.

Feb 252015

This post continues the tear down and reverse engineering of the Acurite 0077XW / 00592TX Wireless Remote Temperature Probe [Part 1] .

Knowing that the signals between the logic board and wireless module are standard 3.3 volt logic level signals with tens to hundreds of micro-second long pulses it is time to pick apart the bit stream and see if I can make heads or tails of the encoded data.

With the signal identified as a digital serial data stream the obvious tool to turn to is a logic analyzer, ideally one with protocol decoding built in.

I own multiple different logic analyzers but my goto analyzer for anything but the widest or fastest signals is the Saleae Logic. I own one of the older models but it works like a champ. Analyzing and picking apart digital signals is child’s play with the Saleae software.


I soldered extension wires to the Ground (G), Squelch (SH), and Data (D) lines to make connecting the analyzer easier.


After a bit of picking and probing, and a bit of web searching, I was able to pull apart the bit stream and protocol used by the temperature probes to communicate to the base station.

The SH pin turns out to be the SQUELCH signal from the logic board to the wireless module. When the squelch pin is low the radio module disables data output. I assume the logic board uses the squelch pin to limit the data transmitted from the wireless module between display updates. The base station logic board unsquelches the radio module on a regular periodic basis, reads the incoming temperature data, decodes the data, and updates the display.

The D pin is clearly the data from the temperature probe. The waveform is relative stable when the probe is at a constant temperature and changes when the temperature at the probe changes.

Reverse engineering the data protocol was the more difficult part of the whole effort. I captured multiple bit streams and some patterns were immediately obvious. There was random looking data followed by a consistent pattern followed by a series of wide and short pulses. Eventually I figured out the random pulses at the start of data must be for radio synchronization between the transmitter and receiver. None of the “random” data at the start of the bit stream was consistent between any runs and I ended up simply chopping it off and ignoring it in the data stream.

After the random bits there is a low pulse of varying length followed by 4 data sync pulses. The data sync pulses are 1.2 msec long, 50% duty cycle with 0.61 msec high and 0.61 msec low. Immediately after the 4 data sync pulses are 56 data bit pulses. Each data bit pulse is ~0.6 msec long. A logic high (1) bit is encoded as a 0.4 msec high pulse followed by a 0.2 msec low pulse. A logic low (0) bit is encoded as a 0.2 msec high followed by a 0.4 msec low.

The data stream transmitted by the 00592TX remote temperature probe to the base station is formatted as follows:

The probe first emits a seemingly random length string of random width hi/lo pulses, most like to provide radio (RF) synchronization.

A random length low signal is inserted between the RF synchronization bits and the data sync pulses.

The probe then sends 4 data sync pulses of approximately 50% duty cycle and 1.2 ms period. The sync pulses start with a high level and continue for 4 high / low pulses.

The data bits immediately follow the fourth low of the data sync pulses. Data bits are sent every ~0.61 msec as:

Logic High (1) bit is encoded as ~0.4 msec high pulse followed by ~0.2 msec low

Logic Low (0) bit is encoded as ~0.2 msec high followed by ~0.4 msec low

The 00592TX sends the 4 sync pulses followed by 7 bytes of data equaling data 56 data bits.

Four (4) high and low pulses in a row, 0.61 msec high, 0.61 msec low, constitute a data sync.

The remaining 56 bits of data, or 112 edges, are measured and converted to 1s and 0s by checking the high to low pulse times.

The first and second bytes of the data are the unique probe address. The upper two bits of the first byte are the probe channel indicator:

11 = channel A 10 = channel B 00 = channel C

The remaining 6 bits of the first byte and the 8 bits of the second byte are a unique identifier per probe.

The next two bytes are always 0x44 followed by 0x90, for all of the probes I tested (a sample of 6 probes).

The next two bytes are the temperature value. The temperature is encoded as the lower 7 bits of both bytes with the most significant bit being an even parity bit. The MSB will be set if required to insure an even number of bits are set to 1 in the byte. If the least significant seven bits have an even number of 1 bits set the MSB will be 0, otherwise the MSB will be set to 1 to insure an even number of bits.

The last byte is a simple running sum, modulo 256, of the previous 6 data bytes.

The sync pulses are high for 0.62 ms and then low for 0.62 ms.


Four sync pulses in a row constitute a sync condition.


A logic 1 bit is 0.4 msec high pulse followed by a 0.2 msec low.


A logic 0 bit is a 0.2 msec high pulse followed by a 0.4 msec low.


A sync pulse plus data stream looks like this.


In part 3 of the series I will go through capturing the data stream with an Arduino and decoding the captured bits.

Feb 252015

Were I live, up against the foothills just east of the Rocky Mountains, the temperatures can vary wildly in a single day, 40F degree swings are common and 60F+ degree swings are not unheard of. For a while now I have been wanting to measure and record the temperature variations inside my house in response to temperature swings outside the house. I want at least one temperature probe outside, another in the attic, one in the lower level on a north wall, one in each of the kids rooms, just to see if it is as cold as they complain it is, and maybe one in the garage. I’m talking about at least six probes. They should be wireless for ease of installation and the ability to talk to a remote base station where I can record the temperatures. I want to record the temperature over time so I need a computer interface of some kind. A web page displaying the results would be nice. Maybe push the results to an online data warehouse. Opportunities for fun are endless.

All of the pieces to build a system like this are readily available from the usual suspects, sparkfun, adafruit, ebay, dx, etc. Figure a temperature sensor, micro-controller, wireless module, battery case, wiring, etc. at each location, times six. I can find a temperature sensor for about fifty cents, Arduino mini for five bucks, wireless module for a buck fifty to three bucks, a case and miscellaneous parts for another two bucks, say a round $10 USD per node. Probably a RasPi for the base station, another $45 at least with power supply, case, and wireless receiver. And then I would have to put it all together and blah blah blah, I never got around to it.

The other day I was at Walmart and stumbled on a pile of wireless remote temperature base stations and probes in the clearance bin.

Acurite00771W front

When I flipped the package over I noticed the probe uses 433 MHz wireless to communicate with the base station. I know a lot of low end consumer wireless devices sourced out of China use a wireless module separate from the core logic of the device. Decoupling the wireless functionality from the core functionality makes a product more amenable to delivering to a worldwide market. Different parts of the world have different regulations on wireless transmissions so modularizing the wireless link allows it to be swapped out for different markets with minimal design and manufacturing changes.

Acurite00771W back

If the core and wireless functions were separate there was a possibility I could sniff the communication lines between the two and decode the data protocol. Once decoded I should be able tap the lines and record the received temperature data with an Arduino or RasPi.

A base station plus probe was on clearance at just under $10 USD, I quickly picked up three. If the probe and base station were designed like I expected $10 seemed like a steal, I couldn’t even build the probe for $10, let alone have the base station along with it.

Acurite00771W receipt

Here is the base station and probe out of the packaging. My first impression is good. The buttons are clicky, the probe looks reasonably robust, the display is big enough to be useful.


Removing the battery covers reveals that the probe takes 2 AA alkaline batteries and the base station 3 AA batteries. There is also a backup battery under a cover in the base station to keep time when the main batteries are being changed.

Under the battery cover in both the base station and the probe is a slide switch labeled A, B, C. I’m assuming the switch allows you to have up to three base stations and three probes in the same radio range.

Now was the moment of truth, time to open them up and see what the radio infrastructure looks like. First remove the two screws under the batter cover, shown just above. Next remove the three rubber feet from the bottom of the probe and remove the three screws found there.

Pop off the base plate and then pry the shell in two.


Flipping open the base station revealed the gold! There is clearly a wireless module mounted at the top of the unit, with the blue antenna wire leading out of it and running around the inside of the case.


As an added bonus the wireless module is completely separate from the logic board. The two boards are connected by a four wire ribbon cable.


Even better, the cable between the boards is labeled, SH, D, V, G (click the image to enlarge). V and G seem obvious, D is probably data, SH could be anything but a reasonable guess might be chip select or data available.


Popping open the probe revealed a similar construction, a wireless module near the top of the unit connected to a logic board with four wires.

Acurite00771W probe open



Putting batteries in the unit caused it to power up and within a few minutes it was displaying the temperature. Everything seemed to be working, the remote sensor was being read by the base station, it was time to start probing around to see what I could see.


Step one is check the power, get an idea of what we are working with. As expected with three alkaline batteries the voltage going to the logic board was around 4.5 ~ 4.8 volts DC.

I confirmed connectivity between the ribbon cable ground (G) and the battery ground, that one seemed obvious and was.


Next I probed the V pin between the logic board and the wireless module, a reasonable guess is the V pin is voltage into the wireless module. The V pin turned out to be a solid 3.25 volts, let’s call it 3.3 volts because that’s what it probably is supposed to be.

Next thing to do was unscrew the wireless module, unwrap the antenna, and get a better look at the board.


A macro shot of the main chip on the wireless module revealed it to be a MICRF211, a 3V 433.92 MHz Receiver,

MICRF211 datasheet 1

MICRF211 datasheet 2

The next step was to probe the lines with an oscilloscope and see what the signals between the wireless module and the logic board looked like. This was where the rubber meets the road, if the signals were anything crazy the pain to condition and decode them might not be worth it.

Only one way to find out, start poking and probing and see what you see.


I started with the SH line.


It turned out to be pretty boring. It was clearly a gate or data available line. Nothing very interesting. The voltage was right around 3 volts.


Time to probe the D line and see if it was more interesting.


Probing the D line was way more interesting, something was happening here. The reasonable theory is this is the data being transmitted from the probe to the base station. The signal level is again around 3.3 volts, so no special conditioning required here. The fastest pulse found was on the order of a few micro-seconds, not slow, but not crazy fast either, something I could get a hold of with an Arduino.


Putting both traces on the scope at once clearly shows the gating or data ready behavior of the SH line overlapping the D line.



Now that I know what is in the case and what the data signals look like between the logic board and the wireless module the next step is to decode the data stream and see if it looks like something I can read and decode with everyone’s favorite microcontroller.

Part 2 of this post can be found here.

Acurite 00754 / 00771W / 00772W / 00773W / 00774W / 00592 / 00592TX

Feb 162015

I’ve been using Git as my main source control system for a few years now. I’ve finally gotten around to documenting a set of commands that support a github-flow style workflow. A google search for github flow will turn up a wealth of links pro and con for github-flow vs git-flow. I like the simplicity of github-flow and how it better supports continuous delivery and agile methodologies compared to git-flow.

Here are a couple of introductory links to github-flow:

Below are the raw commands I use to support a github-flow workflow. These could be wrapped in aliases or scripts to lessen the typing and insure consistent use across a team.

Git Process description

  • master branch is always buildable and deployable
  • Create local branches off of origin/master
  • Use descriptive names for feature branches
  • Include tracking number at the beginning of the feature branch
  • Push feature branches to remote often
  • Open a pull request at any time
  • Merge from origin/master often
  • Create a pull request before checking into master
  • Rebase feature branch off of origin/master after pull request is OK’ed
  • Merge –squash feature branch onto master
  • Push to origin/master
  • Alternative is rebase -i off of origin/master and push directly to origin HEAD:master
  • Delete old local feature branch
  • Delete old remote feature branch

Goal is to have master branch buildable and deployable at all time. Anything checked into master must be at least reviewed and pass automated testing.

Never create new features directly in master.
Create a feature branch for creating new assets.

Refresh the source branch, usually master, before branching

  • git checkout master
  • git fetch --prune
  • git merge origin/master


  • git checkout master
  • git pull -p

Create a new feature branch to work the issue. Add the feature or issue tracking number to the start of the feature branch name.

  • git checkout master
  • git pull -p
  • git checkout -b TR-0001-new-feature


  • git fetch -p

The following command creates a new feature branch off of origin/master

  • git checkout -b TR-0001-new-feature origin/master

See for comments on tracking branches. Setting the tracking branch sets the default push/pull tracking branch. We want to use origin/TR-0001-new-feature instead of origin/master as the remote tracking branch.

Investigation indicates the default push schema pushes to the same named remote branch instead of the origin/master. That is if you create a branch off of origin/master

  • git checkout -b TR-0001-new-feature origin/master

and then push that new feature branch to the remote

  • git push origin TR-0001-new-feature

then the default push git push pushes to the same named remote branch.

Looking at the default config for push is simple.

  • git config --global push.default simple

  • git config --global push.default current

The result is that it seems to be ok to branch off of origin/master and then push the new branch to the remote. The result is simple pushes will go to the similarly named remote branch.

Immediately push the feature to github so it is visible to other developers.

  • git push origin TR-0001-new-feature

Create new feature while on feature branch.

  • write code here
  • git add [.][filename]
  • git commit -a -m"commit message here"
  • git commit -m"commit message here" [.][filename]

Merge feature off of master on a regular basis.

  • git fetch --prune
  • git merge origin/master

Push the feature branch to github early and often.

  • git push origin TR-0001-new-feature


  • git push

Build and run automated tests regularly

When you think you are done issue a pull request on github against your pushed feature branch.

When the feature has passed review then squash and commit to master:

First update local master

  • git checkout master

Fetch remote to update origin/master

  • git fetch -p
  • git merge origin/master


  • git pull

Rebase feature branch off of origin/master

  • git checkout TR-0001-new-feature
  • git rebase origin/master

Merge feature onto master

  • git checkout master
  • git merge --squash TR-0001-new-feature

  • git commit -a -m"TR-0001-new-feature

  • git push origin master

As an alternative you can checkout the feature branch, do an interactive rebase off of master to squash all commits and give a single commit message, then push directly to origin/master.

  • git checkout TR-0001-new-feature
  • git fetch --prune to update origin/master
  • git rebase -i origin/master

Pick and Squash as appropriate
Edit commit message as appropriate

  • git push origin HEAD:master

Delete unused branches

  • git branch -D TR-0001-new-feature
  • git push origin --delete TR-0001-new-feature
Nov 262014

Pololu has their P-Star 25K50 microcontroller on black friday sale for $3.95 each, limit 5. That’s a heck of a price.


Even the normal price of $9.75 is not bad at all.


I snagged some of these last night and I’ll be using them as part of the USB on the Microchip PIC microcontrollers series. It looks to be a nice set of features in a nice package, get the Microchip datasheet for the 18F25K50 here.

Here’s a quick screen shot of the basic features:


Nov 262014

This is Part II of the USB on the Microchip PIC series of articles.

In order to do anything interesting on the PIC we’ll need to install a development tool chain. Typically a tool chain consists of at least a compiler, assembler, and linker. Any modern tool chain will likely also include a librarian, loader, and a handful of utilities for transforming and viewing the tool chain output.

In addition to the compiler tool chain a full featured development environment is almost a requirement. I know of developers that swear by simple text editors for code and command line terminals for running the tool chain. I take the position that tools have advanced to the point where they add significant value in terms of ease of use and speeding development. Modern development environments include syntax highlighting, code completion, parameter filling, version control integration, tool chain integration, and often debugging views.

For the Microchip line of PIC microcontrollers the goto Integrated Development Environment (IDE) has always been, and from where I sit, will continue to be MPLAB and MPLAB-X. Microchip makes MPLAB and MPLAB-X available for download for free. MPLAB-X is the successor to MPLAB and is being pushed as the recommended IDE moving forward. MPLAB is still available for download for older projects that require it but in this series of articles we will be using the MPLAB-X environment. I’m aware that other vendors tried to sell compilers and IDE’s into the Microchip development space but really did they ever get any traction? Can you name two alternatives to MPLAB? Me neither.

Along with the IDE you will need to download a tool chain. Microchip again provides a free solution. Microchip makes available for free download and use, even for commercial projects, compilers for all of their microcontrollers. Microchip sells upgraded versions of their tool chains. The only differences listed on the Microchip website between the free and purchased versions of the compilers are available optimization levels.

From the Microchip website:

MPLAB® XC Compiler PRO Edition:
* Provides powerful code optimization at better than 50% when compared to the free edition, giving the most efficient memory usage

MPLAB® XC Compiler Standard Edition:
* Provides a lower cost compiler option with a 20-25% code optimization when compared to the free edition

MPLAB® XC Free Edition:
* Supports all the devices and commands of the Standard and PRO Editions
* No time or memory restrictions
* Limited code optimizations
* Unrestricted use—ideal for a low-cost academic or commercial solution

What this means is that the free versions of the compilers are viable for any project, commercial or not, that is not speed or code size limited. And if you need the higher levels of optimization the costs are not outrageous for a commercial project.

In this series of articles I will be using the XC8, XC16, and C18 compilers, all available for free download from Microchip, look in the Downloads and Downloads Archive tabs. At the time of this writing the latest XC8, XC16, and C18 compilers are v1.33, v1.23, and v3.46. The latest available MPLABX IDE is v2.20.

Microchip is recommending all new development use the XC line of compilers but older projects may or may not compile cleanly under the XC compilers. MPLABX can import old MPLAB style projects, sometimes seamlessly, sometimes not. The XC compilers can sometimes compile projects that targeted the CXX line of compilers, sometimes not. Microchip publishes a conversion document to migrate from the CXX compilers to the XC compilers, MPLAB C18 to XC8 C Compiler Migration Guide. You can find a link to this and other Microchip compiler related documentation on the Documentation tab.

In the mean time I am using a mix of CXX and XC compilers as required. I am doing all of my new development targeting the XC compilers and am migrating older CXX projects to XC as appropriate.

In order to follow along you will need to download and install the XC8, XC16, C18 tool chains and the MPLABX IDE. Each of these downloads is 50 to 150 MB. After downloading the tools you will need to install and integrate them. Installation is a typical process. I am using MS Windows and the installation is typical double click and install routine. Something thing to keep in mind that you might want to consider, at multiple times in the installation and use of the tools you will need to point to the locations of the tools and application libraries, it can be more convenient to put the tools and application libraries somewhere closer to the top of the file system hierarchy rather than accepting the default Windows installation location. The IDE and compilers want to install in C:\Program Files (x86). I typically install the tool chain and IDE in a C:\apps\Microchip directory. Under each of the IDE and tool chain directories I usually install each particular version in a subdirectory. The MPLAB-X IDE supports multiple different versions of the tool chains installed at the same time and allow you to pick between them. This is a bit of a requirement as deeply embedded projects, for good or bad, often rely on or take advantage of specific idiosyncrasies of the tool chain.


After you have all of your tool chains downloaded and installed you need to integrate them into MPLAB-X. Load MPLAB-X and go to the Tools->Options menu.


Under Tools->Options pick the Embedded tab and Add.. each tool chain.


Once you have a project loaded


select the project properties from the File menu


and select the tool chain for your architecture


If you can get to this point you should be ready to begin building for the PIC family of microprocessors. In the next article we’ll look at Microchip Library for Applications and begin building and looking at the output of some of Microchips demo code.

Nov 092014

I am working on a project that needs high speed real time data acquisition, large data storage, and a rich interface to the web. Put these requirements together and one solution is to use an embedded real time system for the data acquisition and a general purpose computer for the data storage and web interface.

Of the many ways to implement a solution like this the solution I chose utilizes a Microchip PIC microcontroller for the high speed data acquisition and and embedded PC style platform running Linux for the data store and web interface. The connection between the PIC microcontroller and the embedded PC is USB.

Over the course of the next few posts I will be showing a how to bring up USB on a PIC microcontroller, both as a bootloader and as an embedded application. I will be relying on Microchip’s Libraries for Applications or MLA to provide the USB and bootloader frameworks. Part of the MLA is a USB framework targeting Microchips 8, 16, and 32 bit processors. The MLS also provides a wealth of example code including a USB bootloader. I will be showing how to target the USB framework for a couple different PIC processors and how to go end to end from a naked chip to a USB application exchanging data with a PC.

I plan to post on the following topics:

  • USB on the PIC – Introduction
  • Installing the MPLAB-X PIC development environment
  • Microchips Libraries for Applications
  • PIC development tools
  • Bootloaders
  • Building the MCHPUSB bootloader for the PIC18
  • Building the HID bootloader for the PIC18
  • Building the HID bootloader for the PIC24
  • Building the HID bootloader for the dsPIC33
  • Writing a USB application
  • USB slave application on the PIC
  • USB host driver and application on the PC

  • You can acquire some of the following tools if you want to follow along:

    A USB Bit Whacker. The UBW is a simple, relatively inexpensive development board sporting the PIC18F2553. The UBW is well supported and ships with a an open source USB bootloader and application. This makes it an excellent starting point for USB development. You can get a SMD UBW or through hole UBW from Sparkfun Electronics.

    [Update] Since I snagged some PIC18F25K50 P-Star development boards on Pololu’s 2014 Black Friday Sale I’ll be updating this series to also work with these micros.

    A Bus Pirate. The Bus Pirate is base on a PIC24 and is an excellent tool to have in your embedded development toolbox. That we can also use it for a development platforms is gravy. You can get a Bus Pirate from Sparkfun, Adafruit, or Seeedstudios.

    You will also want to download the Microchip Libraries for Applications v2014-07-22 and the v2010-08-04 version from the Archives tab.

    I will be building the demo applications in MPLAB-X which you will want to download and install for you flavor of operating system.

    You will need the Microchip XC compiler for the architecture of the chip you will be using, XC8 for the PIC18 chip and XC16 for the PIC24 and dsPIC33.

    If you are serious about Microchip PIC development you will need an ICSP. I use the PICkit2 but the ICD2, PICkit3, ICD3 all should work equally as well.

    Nov 022014

    The Innovation First VEX line of robotic components consists of a wide range of structural, sensing, and motion actuating elements. All of these sensing and actuating components are driven by the one and only control component, the Vex Cortex.

    The Vex Cortex is the controller, or the brains, for a VEX robot. The Vex Cortex sports an ARM processor for user programs, 8 12 bit analog inputs, 12 digital input output ports, 2 UART ports, a single I2C port, 8 3 wire RC servo motor compatible outputs, and 2 H-Bridge 2 wire DC motor driver ports.


    Today we’re going to walk through the first part of a tear down of the Cortex controller. The reason we’re doing a tear down is that as nice as the Cortex is it suffers from at least one well known weakness, the built in H-Bridge motor driver ports are undersized and prone to burn out under normal use.

    The 8 RC style motor drivers rely on external plug-in H-Bridge motor drivers. If a motors stalls or over currents the external bridge can burn out but it is easily replaced. If the built in H-Bridge drivers burn out the Cortex is permanently damaged. Innovation First, the makers of the VEX Robotics line, including the Cortex, will disavow all responsibility after the warranty period runs out. Even if, in my opinion, the weak design of the internal motor drivers is the root cause of the failure.

    VEX Forum\Official Technical Support\Cortex started smoking

    VEX Forum\Official Technical Support\Possible Cortex Motor Controller Burn-Out?

    With the right tools the internal H-Bridges can be replaced and the Cortex brought back to full functionality. The repair of the motor drivers will be covered in another post.

    Keep in mind that opening the Cortex probably voids your warranty, and modifying the Cortex surely makes it ineligible for competition. Given that caveat, here we go.

    Disassembling the Cortex is straightforward, flip the Cortex on it’s back and you will see four philips tip screws, one in each corner.


    After removing the four screws gently pry apart the front and back covers. The circuit board will likely stay with the back of the housing with the front cover lifting off easily.



    With the top off of the Cortex the main circuit board is exposed.


    After removing the top gently pry the circuit board off of the bottom part of the housing. The circuit board is just wedged into tabs on the bottom of the housing and is not fixed in place.


    The Cortex has two thermal overload breakers inline with the motor control circuits. If the motors draw too much current the breakers overheat and reduce current to the motors, effectively putting the motors, and your robot, out of action until the breakers cool down. The breakers serve to protect the Cortex but pose a serious issue in a competition. The breakers take up to tens of minutes to cool down, effectively putting your robot out of the match you are in and potentially out of the next match as well depending on how fast and furious the matches are coming.


    The major components of the Cortex are shown below.


    The main system processor that controls the Cortex is an NXP LPC2458FET180.


    From the NXP website for the LPC2458.

    "The LPC2458 microcontroller is ideal for multi-purpose communication applications. It incorporates a 10/100 Ethernet Media Access Controller (MAC), a USB full-speed Device/Host/OTG Controller with 4 kB of endpoint RAM, four UARTs, two Controller Area Network (CAN) channels, an SPI interface, two Synchronous Serial Ports (SSP), three I²C interfaces, and an I²S interface. Supporting this collection of serial communications interfaces are the following feature components; an on-chip 4 MHz internal precision oscillator, 98 kB of total RAM consisting of 64 kB of local SRAM, 16 kB SRAM for Ethernet, 16 kB SRAM for general purpose DMA, 2 kB of battery powered SRAM, and an External Memory Controller (EMC). These features make this device optimally suited for communication gateways and protocol converters. Complementing the many serial communication controllers, versatile clocking capabilities, and memory features are various 32-bit timers, an improved 10-bit ADC, 10-bit DAC, two PWM units, four external interrupt pins, and up to 136 fast GPIO lines. The LPC2458 connects 64 of the GPIO pins to the hardware based Vector Interrupt Controller (VIC) that means these external inputs can generate edge-triggered interrupts"

    The datasheet for the LPC2458 is here.

    The system processor runs the Cortex system firmware, as opposed to the user uploaded robot control program. The system processor manages the wireless link and the bulk of the communication with the joystick.

    The user processor, the processor that runs the user uploaded code, is a STMicroelectronics STM32F103 ARM Cortex-M0 processor.


    From the STM32F103 datasheet:

    "Medium-density performance line ARM-based 32-bit MCU with 64 or 128 KB Flash, USB, CAN, 7 timers, 2 ADCs, 9 communication interfaces including up to 2 x I2C interfaces, up to 3 USARTs, up to 2 SPIs, a CAN interface, and a USB 2.0 full-speed interface."

    Four particularly interesting chips are the drivers for the internal H-Bridge motor drivers. The internal motor drivers form an H-Bridge consisting of an International Rectifier IRF8313PbF HEXFET Power MOSFET coupled with a Fairchild FDS4935BZ Dual 30 Volt P-Channel PowerTrench MOSFET.



    The top half of the H-Bridge motor drivers are found on the bottom side of the circuit board.



    The Top Half / Bottom Half nomenclature of the H-Bridge comes from the way H-Bridge circuits are typically drawn. The positive voltage to motor control FETs (P-Channel) are typically drawn above (nearer the top of the drawing) and the motor to ground control FETs (N-Channel) are typically drawn near the bottom of the drawing, top half, bottom half.


    That pretty much wraps up the interesting chips. The VEX Cortex controller is not a particularly complex board but it is almost all surface mount components which makes it just this side of impossible for most robotics clubs to work on when it fails. At $250 USD each burning up a Cortex is not a cheap proposition.

    In an upcoming post we will cover how to replace the motor driver FETs when motor ports 1 and 10 fail.

    Nov 012014

    One of our favorite meals is a vegetarian vegetable curry soup over rice, with or without grilled chicken. We like this curry for multiple reasons; first it is delicious, second, it lets us use up vegetables that are on the brink, and third, it freezes well and lets us pop out a dinner on very short notice.

    When we first started making this curry we would make a standard soup pot full, about enough for a dinner and maybe a left over. Once we discovered how much we liked it we started making bigger and bigger pots. Now we are using our big canning pot and making about three and a half gallons at a time. This soup freezes well and heats up to a quick and delicious dinner.

    The soup is mostly a mix of vegetables and fruit, curry spices, and coconut milk. The flavor is a mix of sweet, spicy, and creamy. We usually pick a mix of vegetables and fruit that end up being sweet when tasted alone, then we add enough curry to give it a bite, and then mix in coconut milk to give it a delicious creamy flavor.

    In our curry we usually start with a base of onion, cauliflower, carrots, and apples. Then we mix in whatever extra vegetables we have in the crisper that we want to use up before they go bad. Historically we have tried adding peppers, spinach, broccoli, kohlrabi, cabbage, and pears. The recipe is not exact, use what you have, or keep it simple if you want a simpler taste.









    Step one is to wash, sort, and trim the produce. I usually wash all of the vegetables and fruit, then I trim off the ends and any bad spots. I core the fruit and toss out any obviously bad leaves or stems. I usually leave the skins on and cook them into the soup. I do not add in the greens from the vegetables.

    Step two is to dice up the produce, mostly just to have it pack in tighter and cook quicker.









    Step three, add all of the chopped fruit and vegetables into an appropriately sized pot and add water to just under the level of the produce.







    Step four, boil the produce for anywhere from a half an hour to an hour and a half depending on the quantity and mix of vegetables. Soups heavy on carrots and other root vegetables will likely need to boil a bit longer. Test the softness of the vegetables every ten minutes or so after the first half hour to get a feel for the progress. You should be able to easily stick a fork into the produce when it is cooked.




    Once everything is nice and soft it is time to blend it. Turn down the heat from high to a mid range temperature. You want the soup to stay hot and continue to simmer but not to fully boil.

    To blend the soup you MUST use an immersion blender. Do not try to use a mixer or counter top blender. You are working with a pot of boiling hot vegetable paste. You really need to keep all of the hot soup in the pot and bring the mixer to the pot, not the other way round. I happen to use a Kitchenaid Variable Speed Immersion Blender. I like the extra length, the metal construction, and the variable speed. We used to use a simple all plastic immersion blender when we were making smaller pots of soup but the larger batches really need the extra length of a bigger blender.





    The soup will start out chunky and lumpy but will eventually blend down smooth.



    Once the soup is blended you can taste it to see where it stands. We typically add in a pinch of salt to get the flavors to pop.

    At this point the soup is probably very vegetable, or possibly apple, tasting and is probably a bit on the sweet side. Between the carrots and the apples the base has a very sweet natural flavor. Now you are ready to add the curry. We use a curry paste we buy at our local Asian market. You should be able to find a bunch of different flavors. We tend to like the Red Curry Paste best with Masman or Panang next. Once you’ve opened the paste you need to store it in the refrigerator. This step, the adding of the curry, is a very personal thing. Add in a little bit of curry at a time, maybe a tablespoon at a time depending on the size of your batch of soup, and mix it thoroughly into the still simmering soup. Use the immersion blender to make sure the curry is well dispersed. Keep adding curry until you get the bite you want. The three and half gallon batch we just made took almost a full cup of curry paste. Remember you will be adding coconut milk which will mellow the flavor. I like to go a bit on spicier side and then mellow it out with the coconut milk. Be careful though, it is easy to let the curry get away from you and make a batch with a bit too much bite.



    As you mix in the curry taste as you go. Add curry until the soup has the bite you want. Besides the coconut milk keep in mind what you will be serving the soup with. If you are putting the soup over rice the rice will also act to buffer the spice.

    After the soup is spiced to taste turn off the heat. We are about to add the coconut milk and you don’t want to cook the coconut milk. You want the coconut milk to melt into the hot soup but you don’t want to over heat the milk. Again, turn the heat off under the soup and then add the coconut milk. The amount of coconut milk will depend on the size of your batch of soup and your taste.


    After the coconut milk is mixed in the soup is ready. If you just made enough for one meal your dinner is ready, serve and enjoy. If you made extra let it cool and freeze it in appropriately sized batches. When you need a quick dinner grab out a frozen batch of soup, put it in pot to heat while you make the rice. If you make long cook rice your soup should be hot about the time your rice is done. You can have a hot delicious meal in about a half hour.



    Here is the recipe. Remember this soup is done to taste. Add in more or less curry and more or less coconut milk depending on your taste. Pick vegetables and fruit that you like or have handy.

    Our soup:
    1 to 2 heads of cauliflower
    5 to 12 carrots
    5 to 24 apples
    1/4 to 1 sweet onion

    Optional vegetables and fruit:
    other readily available produce to your taste

    Wash, trim, and chop the produce.
    Add the produce to a pot, add water and bring to a boil.
    Boil the produce until soft to a fork.
    Blend the produce using a hand immersion blender until smooth and well blended.
    Add a pinch of salt to taste.
    Blend in curry paste a little at a time to taste.
    Remove from heat.
    Stir in coconut milk until well mixed. Add coconut milk to taste.