Supercon 2017 Badge – Hardware Orientation

Today was spent getting orientated on the hardware components making up the camera badge for Supercon 2017. The starting point is the project documentation’s “hardware description” page, which gave a basic overview that helps me decide where I want to dig deeper.


The CMOS sensor at the heart of the OV9650 camera module claims to support up to 1280×1024 resolution, which isn’t bad for such an inexpensive component. The sample image posted on the project file section, however, is only 128×96 resolution. It’s not immediately clear where >99% of the pixels disappeared to or how feasible it’d be to bring them back.

Perhaps that resolution was chosen to match the OLED screen, which has 128×128 pixels of resolution controlled by a SSD1351 chip. If this is the case, and more pixels can be captured from the camera with minimal effort, that opens up project ideas such as having the little screen pan across a larger image. (a.k.a. the Ken Burns effect.)

We have multiple tiers of storage that makes different capacity/speed trade-offs. First we have some space for data on the PIC itself, then we have a Microchip 23LC1024 serial RAM, and finally a microSD card.

There’s an LIS2HH12 accelerometer on board which might enable some cool projects, though I’m struggling to think up one that captures my fancy. Maybe in a bit.

The chip that orchestrates all of this is a PIC32MX170F256D. Fortunately for me, I already had the tools on hand to develop for it thanks to my time playing with the PIC16F18345. They’re very different chips, but since they’re both from Microchip I would write code to both using the same MPLAB X IDE albeit with different C compiler underneath: XC8 vs XC32. The PIC32 is set up to run a .hex file off the microSD card, so it’s not necessary to have a PIC programmer. But if I need to flash at a more direct level, the board has headers to connect the same PICkit 3 programmer I use for the PIC16F18345.

All in all, a decent set of hardware. Now I just need to think of a really cool project to do with it all.

Supercon Badge – Initial Exploration

Supercon 2017 is coming up soon and I now have a ticket to attend. Part of the fun is the badge which, unlike SIGGRAPH or WestTec, is not a printed piece of paper. In the case of Supercon (and a few similar conferences) it is actually a circuit board with some functionality. The Supercon 2017 badge is a very minimal low resolution digital camera. Why would we want such a thing when most of us carry cell phones with far superior cameras? Because it is only the start: conference attendees are invited (expected?) to use it as a starting point and build something cool.

Which means I have only about 10 days to do my homework – what would I build with the badge? As a first-time attendee I’m not sure what to expect. Last year I saw brief glimpses of the badge under construction, but I didn’t see any of the projects built by conference attendees.

Well, with any project, the first step is to look for documentation. The official source of information is, naturally, the camera badge’s own project page on I felt intimidated on first look: my own adventures in electronics hardware hasn’t covered anything to do with cameras, OLED panels, or the like. About the only thing I am vaguely familiar with is the microcontroller at the heart of the device. It is a Microchip PIC, though from their PIC32 series which is higher-end and more capable than the PIC16F chips I had been playing with.

Fortunately, it uses the same MPLAB X IDE for development. I had to download and install the XC32 compiler corresponding to the PIC32 chip, but that was relatively easy. After changing the path separators from the author’s Windows machine (‘\’) to the Ubuntu I’m working on (‘/’) the project builds successfully.

That’s a good start. The next step is to go digging through the code base and look for something interesting for me to do.



A 3D-Printed Enclosure to Take My LED Project On The Go

For the Connect Week event put on by Innovate Pasadena, the Hackaday LA group is hosting the “Bring-A-Hack” event where attendees are encouraged to bring projects (in any stage of completion) for show and discussion. Since I’ve been building my LTC-4627JR driver board as a learning project, I wanted to bring it in for show-and-tell.

Now I could just bring the assembled circuit board and pass it around as an inert object, but what fun would that be? I wanted to bring in something that shows it doing something, and provide some way for people to interact with the whole contraption. Looking at my parts on hand, it seemed easiest to rebuild my thermometer test project. I can have a simple Python program run on the Raspberry Pi, reading temperature from the Tux-Lab Si7021 breakout board, and sending it out to my display. That makes 3 circuit boards, plus they’ll need portable power. I will enlist my Amazon purchases: the 3-cell lithium ion battery pack protected by a S-8254A IC, and the MP1584 buck converter to translate the battery pack’s power into Raspberry Pi friendly voltage.

They present a logistics challenge. There are many parts and while it’s fine to just connect them with wires on my work table, it’s too unwieldy to carry on the Gold Line to Pasadena. I’m going to need some kind of enclosure to carry the whole thing.

To Fusion 360 we go! I just needed a simple enclosure so it was pretty fast to draw up. The bottom tray is for power: it holds the battery cells, their protection board, and the buck converter to 5 volt output. The upper tray holds the Raspberry Pi. The lid of the tray holds my custom LED circuit board, and a few clamps holds it all together. The clamps should be easily removable so I could disassemble the box to show people what’s inside.


I had originally intended to mount the Si7021 breakout board as well, but ended up deciding it would be more fun to have it dangling out for people to play with it. Here are the layers without the clamps, so they can be taken apart and show off the insides.


And here’s the “travel configuration”, with clamps holding the pieces together.


This setup worked well. I was able to carry it in my backpack without worrying about tangling up or shorting out wires. Once I arrived, the project was fairly well received and lots of people had fun playing with the thermometer.

PIC Controller for LTC-4627JR LED Now Accepts Strings

Now that our circuit board from OSH Park is populated and running, it’s time to evolve the PIC code beyond displaying a test pattern. The objective of the exercise all along was to display data sent to the unit over I²C, but the exact details of what to send hasn’t been finalized.

Stage 1: Raw Bits

This was the easiest and so was the first thing we implemented. It is the lowest-level way to communicate between the host and the display. The host sends data in the form of raw bytes. Each bit in a byte correspond to the 8 segments in a single digit. The host sending 4 bytes will fill 4 digits. We send that byte directly out to PORT C on the PIC micro controller, which are connected to 8 segments of a LED digit.

This method is powerful in the sense it allows the host to display arbitrary patterns. But it is terribly unfriendly to use. The program running on the host has to tailored to the implementation details of our display: the host has to know which bit corresponds to which segment, and whether a bit value of 0 or 1 corresponds to light or dark. Which means if the user wants to swap out to a different display, they would have to rewrite the host code.

This system served its purpose to prove we could light the LED, but it is not a good way forward.

Stage 2: Hexadecimal Decode

In this system, the bytes sent by the host is decoded into their hexadecimal representation and displayed on screen. Since a hexadecimal digit represents 4 bits, the host sending 2 bytes (16 bits) will fill the 4 digits. This is actually a pretty useful mode in certain debugging operations where we do want to see those values. However, it is very difficult to represent human-friendly information this way. We’re also unable to make full use of the LTC-4627JR this way: there’s no way to represent the decimal point or the colon in the middle.

Since it is useful for machine-level (not human-readable) data debugging, we might want to retain this capability in the form of a special mode later. In the meantime, let’s move on.

Stage 3: Binary-Coded (Hexa)Decimal

The next evolution resembled binary-coded decimal system, which separated out each digit to its own byte. This makes the host program easier to write because each character can be treated individually instead of having to pack 2 characters into the upper/lower 4-bits of a byte. Unfortunately it also shares the limitation that we couldn’t represent the decimal point or the colon.

Which brings us to the latest approach:

Stage 4: String

Since most computer operations that result in human-readable information end up with the string data format, we’re going to try using that as our I²C protocol. It is established, well-understood, and a piece of cake to use from high-level programming languages like Python. The downside is that it is much more verbose. The character sequence to light up all the LED is 8.8.:8.'8. which requires 10 bytes to represent. This is a five-fold increase in bandwidth relative to the 2 byte hexadecimal decode. Will this added bandwidth cause problems? I don’t know yet, we’ll find out.

But for now, we have a very user-friendly interface. Sending the string “79.2F” resulted in the picture attached to this post. The easy interface also enabled a very short example program.

(The project discussed in this blog post is publicly available on Github)



First OSH Park Order Arrived

My first KiCad project was sent to OSH Park almost two weeks ago, and my digital design is now back in my hands in physical form. It is really quite exciting to hold in my hands a circuit board I designed. Three copies of it, in fact, as per usual OSH Park practice.

The first order of business is to check for simple mistakes. I pulled out my multimeter to verify that I have good connection between all the VCC pins to the VCC plane, and similarly all the ground pins are connected to the ground plane. Then I brought up my design in KiCad and checked continuity for the pins I designated. I don’t know if I exhaustively checked them all, but a large portion were verified.

Once I’m satisfied my design has been faithfully produced by KiCad, it was time to pull out the soldering iron. I thought I’d do some incremental tests – solder a subset of components to verify the subset of LEDs light up correctly – but I was eager to see it all light up so I went ahead and populated the whole board. The legs of the 2N2222A transistors in their TO-92 package were closer together than I’m used to in my soldering projects, but other than that challenge it was all simple and straightforward soldering.

Populated LED board

And finally, the moment of truth. I was working in Tux-Lab and a bunch of nearby guys gathered around to see me power up the board for the first time.

<drum roll>

It’s alive! The test pattern already programmed into the PIC started cycling through the LED display. This success is a great confidence-builder. I had fully expected to find problems with the board that I would have to fix in KiCad and send back to OSH Park for another set of circuit boards to be produced. The only problem I encountered was the PICkit 3 does not fit nicely alongside the power connector. I could make it work by making them wedge together at an angle. Neither were happy with it but it should be relatively rare to have the programmer attached.

Well, I guess break time from PIC software is over – I no longer have an excuse to play with other projects. The task of writing my I²C driver routine for this display is back on the to-do list.

Placed First OSH Park Order

After several revisions – including several PCB layouts that were restarted from scratch – I’ve learned a lot about using KiCad.  I don’t know for sure it’s all going to work, but I feel confident enough to make the first revision of my board. If it comes back and the board doesn’t work, I’ll have new lessons to learn. Or if it does, I celebrate!

Off to OSH park!

They have a very KiCad-friendly pipeline that accepts the PCB data file directly, no file conversion or data export necessary. I was worried about file format compatibility since I am running the latest nightly build and OSH Park only officially supports the most recent stable build. Some people have reported issues, but in my case it seemed to have gone through successfully.

The OSH Park verification screen is a great confidence builder. They took my file and generated these images for me to look over. This is awesome! I can clearly tell that it is my design and it generally looks fine. The resolution is a little lower than I would have liked. It is starting to be difficult to make out individual traces on my board, it would obviously be impossible to do so on a large complex board. But I assume detailed checks are not the point, we just need to verify we haven’t uploaded the wrong board and that nothing’s fundamentally broken in OSH Park’s interpretation of it.

OSH Park Verify

Upon checkout I was surprised that two Teensy boards were available as add-ons to my purchase. I don’t know why the circuit board fabrication shop is selling their own edition of the Teensy board, but since I had been thinking about buying one to play with anyway, it was an easy impulse buy to add a Teensy LC to the basket.

And now I wait. The board should arrive in two weeks and I won’t know what I need to fix in KiCad until I get the board and put it to (in)action. This puts a hold on the PIC micro controller hardware side of the project, and I can turn my attention to something else for a while.

(The work described in this blog post are publicly available on Github.)

A Beginner Learns PCB Routing is Hard

Drawing up the circuit diagram/schematic was a new thing, but I got through it with minimal headaches and was feeling pretty good about using KiCad. After I was done with the first draft, I moved on to route all the connections to be placed on the printed circuit board (PCB). Doing this, I get firsthand experience that wire routing is a hard problem.

The first few connections were easy, but then it got progressively more difficult as I struggled to find a route for the later connections. The center of the board inevitably became a traffic jam and I started having to go around the jam. Every track that go around the outside perimeter of the PCB is a surrender that I couldn’t find a better way.

In addition to the traces going around the outside perimeter, another way to quantify my frustration with my circuit is the number of tracks in the KiCad PCB file. This is a number easily readable in the text format save file.

Fortunately, it doesn’t cost anything to learn by doing, redoing, and repeat.

The first attempt was a hopeless mess and I had to abort before I could connect everything. Here is version 2, where everything is actually connected with almost 200 tracks and multiple traces that go around the perimeter in a last-ditch effort.

LTC-4627JR I2C PCB v2

Version 3 changed the layout of the components in an attempt to make routing simpler. Moved the LEDs to the top, etc. It felt cleaner but is still quite a mess. I managed to avoid long traces that went around the left and right perimeters, but I still needed several at the bottom perimeter. And the track count didn’t improve by much – still just under 200.

PCB Route v3

Version 4 had the same basic layout as version 3 but I’ve learned to recognize a few signs of upcoming problems and could work to avoid them. The result had a further reduction in tracks, almost a 10% cut down to under 180. Plus I needed even fewer perimeter rescue paths.


The English language has the colloquialism “Paint yourself into a corner” and this is a very similar thing – it’s very easy to route yourself into a situation with no way out. I wish I could condense the lessons I learned into a summary here, but so far it’s just a lot of trial-and-error. Try something until I run into an obstacle, then try to figure out how to get out of this mess.

At this point the only words of wisdom I could offer is – dive in and try. It won’t work, but you’ll learn. Try and try again until you get good enough to get to a point where everything is connected, however inelegant it might be, and keep iterating to improve from there.

(The work described in this blog post are publicly available on Github.)

KiCad Circuit Diagram Schematic Editor (Eeschema) Amateur Hour

The KiCad Getting Started guide only covers the basics, but it’s enough to let the user embark on exploratory adventures to learn the rest of the tool piece by piece. I know I don’t have the knowledge and experience to do a good job at circuit design, but I’m a believer that such knowledge and experience is built up by learning from mistakes. So: let’s dive right in and try to implement the circuit board for my LTC-4627JR driver project and see what we learn.

The circuit diagram portion was relatively straightforward. Most of the lessons in the Getting Started guide applies, up to and including how to build a custom component for my schematic because the LTC-4627JR was not in the KiCad standard library. Somebody had built a library of components that included the LTC-4627JR, and made it available on Github. But this is a learning exercise and I wanted to learn how to do it myself.

The PIC16F18345 was not actually in the KiCad library, but a sibling part PIC16F18344 was available with a 20-pin DIP footprint, which is what I want right now. However, the eventual goal is to go to the surface mount version of the part and I hope I’ll be able to find another substitute with the same 20-pin SMD footprint.

There was no specific KiCad part for the 2N2222 transistor, but there are generic NPN transistors and I think that’s good enough. I was puzzled by the large number of options until I figured out they were different combination of a transistor’s pins. The three pins were labelled in order of pin number. So the variant tagged “BEC” has the base on pin 1, emitter on pin 2, and collector on pin 3. The “BCE” variant has the latter two pin swapped, etc. Looking at my 2N2222, I decided to use the EBC variant because that’s the order I see in the Wikipedia article.

The resistors were straightforward, as were the two I/O headers on the board. A four-pin connector for power, ground, and the 2 I²C wires. The five-pin connector is for the PICkit 3 to perform in-circuit programming.

From looking over schematics in the past, I got the distinct feeling of a stylistic convention for laying things out. Much like there are conventions for software source code. But a gut feel is not enough – I needed help from somebody to concretely spell out the rules. A web search for “circuit diagram conventions” pointed me to this article on Electronics StackExchange.

Armed with the list of conventions and a few hours to bump my head in KiCad, I got a passable basic schematic.

LTC-4627 I2C schematic

(The work described in this blog post are publicly available on Github.)

LED Practice Exercise May Have Niche Market

I set out to program a PIC to implement an I²C-controlled 4-digit 7-segment LED display because I thought it would be a decently nontrivial practice project to help me learn. I had fully expected it to end up duplicating the functionality of a commercially available product that does it better for a fraction of the price.

Now that my project is in a decently functional state, I went looking for that commercial product to see what else I can try to imitate for the sake of practice. I was surprised that nothing immediately stood out as both “does it better” and “fraction of the price”.

The first item I found was sold by Adafruit. They have an I²C LED display “backpack” in various colors. Here’s the green version, as one example. The driver chip they used is the MAX7219, which I found curious because the data sheet for the chip does not mention I²C communication. Another curious item is that the complete kit – including populated circuit board and LED – has a list price of $9.95 but if I want to buy the MAX7219 by itself from Adafruit it costs the same $9.95. Digi-Key sells the chip for around the same price. I doubt Adafruit get their circuit board and LED for free, so there’s something else I’m missing.

But I couldn’t have used that chip anyway. The MAX7219 is for driving a display unit with common cathode, and LTC-4627JR is a common anode unit. Also, Maxim is telling people to migrate their designs to the MAX6950, which seems to be a surface-mount only chip with no DIP form factor available.

Looking over Sparkfun catalog I found a similar product, but theirs is controlled by an ATMega328 chip. In fact, it is a baby Arduino complete with the Arduino bootloader. This is closer to what I’ve built, but I think the PIC is a simpler and less expensive chip to perform the task which may mean a small niche below the Sparkfun unit.

All this hints at the possibility my project might actually find an audience as a product. If I were to go ahead with this, I would test the market by putting it up on Tindie. It’s a marketplace that seems to cater to the right audience and there doesn’t seem to be a direct competitor product at the moment.

Well, that was unexpected. I might as well keep going and see how far I can take this.


MPLAB Xpress vs. MPLAB X: Git Source Control

MPLab Xpress IDE LogoI loved the promise of MPLAB Xpress that someday I can do all my PIC development in the cloud. Even in today’s limited form, as long as I stay within certain boundaries I was able to work on PIC programming on a Raspberry Pi! But one downside of keeping the project sources up on Microchip’s servers is that they don’t currently offer any kind of source code version control. I understand why they might not prioritize it for the hobbyist crowd getting started in PIC programming, but version control is something I’ve grown used to having in my software development toolbox. And I occasionally miss being able to review and rewind certain things, even in the relatively simple beginner’s PIC projects that I’ve worked on to date.

MPLAB X logoSo after I inadvertently damaged my MPLAB Xpress Evaluation Board, I decided to graduate to using PIC chips directly without an evaluation board. This meant programming the chip using a PICkit 3 instead of the USB storage-based programmer on the evaluation board. And lastly – it also means leaving the web browser-based MPLAB Xpress and moving over to the NetBeans-based MPLAB X IDE installed and executed locally. One result is that the project files are now on my computer, which means I can bring git into the picture!

Obviously git can handle the C source files that I will be working with. What’s less obvious are the other data files in a MPLAB X project. What is worth tracking in version control, and what are easily regenerated as needed? Such information are usually described in a .gitignore file, but Github’s .gitignore collection does not include one for working in MPLAB X.

Fortunately, the MPLAB community has assembled one and it looks OK to me at first glance. I first dipped my toes using a project that was already complete, pushing it up to Github for archiving the sources. It also allowed me to test that all critical information is preserved, by deleting the directory and “git clone” anew to verify MPLAB X is happy with everything and didn’t complain about files missing from the project.

The second trial run incorporated git from the start, tracking changes along the way so I could see what was boilerplate generated by the tools and separate them from the (quite trivial) code I actually wrote. This test is also successful.

And now, trial run number three: take all the 7-segment LED control code I’ve been working on in MPLAB Xpress and translating them into a MPLAB X project in a way that tracks all the individual tasks along the way.

Lite-On LTC-4627JR + I²C = Using All 20-Pin On PIC16F18345

My shipment of my own PICkit 3 and tube of PIC16F18345 has arrived, so it’s time to pick up where I left off with I²C control of the Lite-On LED module.

This LTC-4627JR module has a few extra enhancements over the standard 4-digit 7-segment display. The first is the addition of a period with each digit, so we can display decimal points in our numbers. The period is an additional segment to make it an 8-segment display.

In addition to the periods on each digit, there are three additional LEDs. Two are in the middle of the display making it possible to use this in a clock, as they’re positioned to show the colon in the ubiquitous blinking “12:00”. The third and final additional LED is towards the upper-right of the display. It’s not immediately clear what that would be good for, but since its siblings are clock-friendly, perhaps it can indicate AM/PM with the help of bezel markings. Electrically, these three LEDs are wired in parallel with 3 of the 8 segments of the other digits and enabled with a common anode in parallel with the 4 digits. Together the three additional LEDs are effectively a partial fifth digit on the display.

Effectively, I’m now trying to control a 5-digit, 8-segment display. A few days ago I tried to control it with a PIC16F1847, but that is an 18-pin chip so I didn’t have enough pins to drive the eighth segment  or the fifth digit. Now that I have my 20-pin chip, I can wire up  my breadboard with:

  • 2 pins for power, +5V and Ground.
  • 8 pins for the cathodes of the 8 segments, via 120 Ohm resistor to keep the current below 25 mA.
  • 5 pins for the common anodes of the 5 digits, via 2N2222 transistor to control the (up to) 200mA current.
  • 2 pins for I²C communication, one data and one clock.
  • 3 pins for the PICkit 3 to program the chip, Vpp, ICSPCLK and ICSPDAT.

Using all 20 pins with nothing wasted.

I know that the Vpp, ICSPCLK and ICSPDAT pins can serve double-duty under restricted circumstances, but I don’t yet have a good grasp on when it’s OK to do that. For now I’m  going to leave them alone for exclusive use of the programmer until I have a better grasp.

On a final note: even though I’m driving one more transistor and one more digit than before, the board still ended up cleaner and less tangled with wires. Practice makes perfect I guess.

To establish a baseline of functionality, I hooked it up to a Raspberry Pi to confirm I could talk to the Microchip boilerplate generated I²C code. And I wrote a small program to confirm I could light up all the LEDs. It looks good, we can proceed.


PIC Exercise: Volt Meter

One aspect of PIC micro controllers that I found to be a novelty is their ability to work across a wide range of supply voltages. For my PIC16F18345, the data sheet said it can run anywhere from 2.3V to 5.5V and can (briefly) tolerate up to 6.5V. I looked for configuration information to set it to “3.3V mode” or “5V mode” or something along those lines, but there was no configuration to worry about. The PIC does not care: give it anything in that range and it will go.

In contrast, the Raspberry Pi requires a steady 5V supply voltage. So does an Arduino though most Arduino boards also incorporate a voltage regulator to take a 7-12V power supply and regulate it down to 5V.

I wanted to play with PIC’s power flexibility and I had the hardware ready to go: my PIC16F18345 evaluation board. I damaged the MSSP peripheral in my I²C experiments and retired it from my I²C project, but the rest of the chip seems OK. It is still perfectly capable of displaying numbers, just not with I²C data.

So here’s today’s exercise: the PIC will measure and display its own varying supply voltage. This project is made possible by a few core-independent peripherals (CIP) built-in to the chip. The input voltage will be compared against a reference voltage created by the fixed voltage reference (FVR) peripheral, and the analog-to-digital converter (ADC) peripheral will be configured to report how FVR voltage relates to the input voltage.

[UPDATE: The source files are now available on Github.]

For my project, FVR is configured to 2.048 volts and ADC is configured to determine the FVR position in the range between ground and the input voltage level. The result is expressed as a 10-bit number in the range of 0 to 1023. A few examples:

  • For 5V input, ADC will report 2.048V is 41% of input, represented by roughly 419.
  • For 4.096 V input, ADC will report 2.048 is halfway, represented by 512.
  • For 3.3 V input, ADC will report 62% or about 635.
  • For 2.048 V input, ADC would in theory report maximum of 1023. In practice it would not happen because the minimum voltage is 2.3V and we would trigger a brown-out reset before dropping to 2.048V.

Inside the ADC peripheral, the conversion process takes a little time. Plus the calculation to convert the ADC output to the voltage, then converting that into which LEDs need illumination to convey the voltage to the user, takes a little more time. The process is very fast by human standards, but it paused the LED refresh loop for long enough to cause a visible blink.

Solving this undesirable blink was the extra credit part of the exercise: move the LED refresh code into a timer-driven interrupt service routine, so it can run at guarantee regular intervals. Even if it means briefly interrupting the analog-to-digital conversion process.

Completing the exercise resulted in a PIC that measure and displays its own input voltage on the 7-segment LED. Unlike my earlier project with the 18-pin PIC16F1847, this 20-pin PIC16F18345 has one pin available to illuminate the decimal point. Here it is, running off a fully charged Lithium-Ion battery cell and indicating 4.005V. My multi-meter says 4.041V, so the PIC agrees to within 1-2%. Good enough.


Note: When using the MPLab Xpress PIC16F18345 Evaluation Board (Microchip part number DM164141) shown in this picture, the FVR+ADC calculation is unreliable when connected & powered via the computer’s USB port. This project didn’t work correctly until unplugged from the computer.

Symptom of the failure: ADC result is always the maximum value of 1023, which indicates the input voltage is 2.048 when it is not. This behavior wasted a lot of debugging time which made me less happy with the product.

Si7021 Sensor to Raspberry Pi to PIC to LED

I started this I²C project by creating a simple I²C-controlled LED display using a PIC micro controller. Then I found an I²C Python Raspberry Pi library to communicate with my PIC. The next addition to the mix should be an I²C device I did not create, to verify my code plays well with others.

While talking about I²C at Tux-Lab, one of the past projects came up: a breakout board for the Si7021 temperature and humidity sensor. A unit was brought out for show during this conversation. This particular unit was built a few years ago and has yet to be incorporated into a project.

A web search confirmed this is quite a popular sensor. Lots of sample code and projects. Both Adafruit and Sparkfun sell breakout boards similar to the one Tux-Lab created. And the sensor is also part of the popular Sense HAT. I looked at the data sheet and thought it looked like a good place to start. Best of all, a search for existing code found one in the “Examples” section of the Pi GPIO library I wanted to learn anyway.

I asked to borrow that unused breakout board and added it to my bread board. (Visible in the lower-left of the attached picture.) The additional wiring was trivial, most of the work was on the software side learning Python basics. It didn’t take terribly long to create a rudimentary thermometer. My Python code running on the Pi uses I²C to query the Si7021 for temperature, converted that data for display, and sent that data out the same I²C bus to the PIC.

With the work and learning I’ve put in, I now have an overly complicated contraption that tells me my work space temperature is 75.18 degrees Fahrenheit.

No decimal point on the LED because I ran out of pins on the 18-pin PIC16F1847 chip.


PIC I²C Project Continues with Different Chip (PIC16F1847 for PIC16F18345)

My PIC16F18345 has stopped working properly as an I²C device. It could send data (I could read from it) but it could not receive (I could not write to it.) Debugging this behavior, I got as far as determining a flag on a status register is not being set correctly by the MSSP module. This is beyond my means to repair or work around in software. In the last post I described an ugly hack of a I²C protocol to let me get a little bit of work done, but what I really need is a new chip. I placed an order from Microchip Direct and the replacements are on their way.

In the meantime, I borrowed a PICkit 3 programmer and a tube of chips from Tux-Lab to see if I can continue working until my order arrived. The chip is PIC16F1847, an older design with fewer features but in the same general family as the PIC16F18345 I’ve been learning. I could not load the exact same compiled code onto the chip, but the C code I wrote was fairly painless to migrate. The steps were:

  1. Created a new PIC16F1847 project in MPLAB X.
  2. Configured the chip for I²C communication in MCC.
  3. Click “Generate” to create all the boilerplate code.
  4. Copy the C code I wrote (not the generated boilerplate) from the PIC16F18345 project to the PIC16F1847 project.

That compiled successfully right away, freeing me to make other changes. The pin layout of the PIC16F1847 pin is nothing like that for my existing board, so I had to set it up on a new breadboard. Since I’m rewiring anyway, I incorporated a different, brighter 7-segment LED display unit. This unit uses common anode pins to select the active digit each of which demand more current than a PIC can source. So I also incorporated some 2N2222 transistors to let the PIC control sourcing that current from the positive power rail instead of supplying that power itself.

The remaining key difference is that the PIC16F1847 is an 18-pin chip, where the PIC16F18345 is a 20-pin chip. Before, I had an extra pin unused, but now I’m one pin short for my project. I decided to temporarily sacrifice the decimal point until my 20-pin chip shipment arrives.

This is good enough to get me back up and running. Here’s the setup displaying “1847”



Ups and Downs Implementing I²C on PIC

The original intent of the I²C bus is clearly stated in its name: Inter-Integrated Circuit. It is meant for communication between chips living near each other on the same circuit board. It isn’t designed to be used communicating across wires bridging multiple breadboards on a hobbyist project. So the simplicity of its design is partially related to the fact there’s very little idiot-proofing built-in.

Which is a long-winded way of saying… I broke something. After wiring up the 7-segment LED, I started writing I²C code to control what gets displayed. I was puzzled by the fact my project became gradually less functional over the course of a few hours. I assumed I did something bone-headed in my code but troubleshooting eventually eliminated my code as an issue.

There was a fault in my hardware – the common ground wire I used to connect between the Raspberry Pi and the PIC was only providing an intermittent connection. After repairing the bad solder job, I was surprised to find it did not restore functionality. It’s not clear how the I²C circuit worked while the ground wire was unreliable – the system must have found some other path for ground and something along that line caused damage. Or maybe the intermittent connection was causing current surges through the system as it connected and disconnected at unpredictable times.

The bottom line is that my PIC could still send bytes over I²C but it could no longer receive. When running the boilerplate EEPROM code, this meant my Pi could read from the faux EEPROM on the PIC but any write operation would fail. I guess it’s time for me to get a replacement PIC16F18345.

In the meantime, I wanted to keep working on the 7-segment project. But how could I tell the LED what to display if I can’t send data? This constraint led to an extremely unorthodox I²C communication protocol: I tell the LED what to display by reading the faux EEPROM. The number of bytes retrieved in each read operation is then displayed on  a digit of the LED.

So for the attached picture showing 0x16F1, I performed four reads from the EEPROM: Read 1 byte, stop. Read 6 bytes, stop. Read 15 bytes, stop. Read 1 byte, done. This super ugly hack will unblock my project while I wait for Digi-Key to deliver a replacement PIC, but yuck! This is no way to design an I²C protocol!

The project display dimly showing “16F1”

Wiring up a PIC to control a 4-digit 7-segment LED (Lite-On LTC-5723HR)

Now that I have my PIC micro controller successfully communicating via serial port and via I2C, it’s time to make it do something a little more interesting and practical than just lighting up a single LED. Which means… more LEDs! I could do a RGB triplet and try my hand at colors, or a string of lights, but there’s an existing open project at Tux-Lab that would need to drive some 7-segment LEDs. I borrowed the LED module from that project and got to work.

I could see that the module had 12 pins, but it wasn’t obvious to me how 12 pins would control the display (4 digits * 7 segments+period = 32 individual LEDs.) Fortunately this part was purchased from Digi-Key and still in its shipping bag with the part number, which made it trivial to find the product page and download the data sheet.

Reading the schematic on the data sheet revealed that 8 of those pins are anode (+) connected in parallel across all 4 digits, each of them corresponding to a location on a digit. (7 segments plus a period.) The remaining four pins are cathode (-) for each of the four digits, connected to all 8 segments of the corresponding digit.

It’s immediately obvious we can only have one digit active at any given time, since different digits would probably display different numbers and would need different anode pins active.

Less obvious is the fact we can’t have all the segments on that digit active at the same time, either. The cathode is common across all 7+1 segments of a digit. If all 8 segments light up, that poor cathode pin will have 8*20 = 160mA crashing through all at once. This greatly exceeds the 50mA per-pin current handling limit.

I could probably solve this problem by using the PIC to control transistors that can handle that 160mA, but I don’t have any on hand. So to start with, I’ll cycle through all the segments lighting up only one at a time so there’s only 20mA flowing through the cathode pin. This will result in a display only 1/8th as bright as it could be, but if that’s already bright enough, I won’t have to hassle with transistors.

After wiring work was complete on the breadboard, I wrote a simple PIC program to cycle through all 32 LEDs. The first revision had the cycle running slowly enough for me to follow as it went from one segment to the next. This allowed me to visually verify all the wiring is correct. Then I let the cycle run at full speed to see the brightness level.

It is fairly dim, so I will have to add those transistors later. For now it is visible enough for me to proceed.


I2C on PIC: Microchip MCC Boilerplate Is A Pretty Good Tutorial In Itself.

After completing the MCC tutorial, I knew I wanted to start learning about implementing I²C on the PIC micro controller. I planned to use PIC in conjunction with a Raspberry Pi and I²C is the protocol already used by existing Raspberry Pi peripherals. I wanted my PIC projects to play well with others in this ecosystem.

The Microchip tutorial covered serial communication with the EUSART module but not communication with the MSSP (Master Synchronous Serial Port) module that assists with implementing the I²C protocol.  I went hunting for such a tutorial elsewhere on the Microchip web site but didn’t find one.

At this point I was not terribly worried. The PIC16F18345 data sheet provided an overview of implementing I²C using the MSSP module.  Section 30.5 I2C Slave Mode Operation included a list of operations during normal I²C communication. This list was almost a pseudo-code outline of what the developer needs to do to implement I²C communication on the PIC.

I would be happier if there was a tutorial walking through the actual code of an I²C implementation, but the pseudo-code should be enough to help me take whatever boilerplate MCC (MPLAB Xpress Code Configurator) generated and filling in the missing parts.

I created a new PIC project and used MCC to enable the MSSP module for I²C communication. After auto generation was complete, I went into the code ready to get to work. And… hmm… what’s this?


The MCC boilerplate is more than just a bunch of function prototypes, it’s actually an implementation of an I²C slave acting like a EEPROM device. This was, for all practical purposes, the tutorial I had been looking for. Within an hour I was controlling the brightness of a single LED via commands sent over I²C bus and interpreted by my PIC.

So let this be an announcement to other PIC programming novices: sometimes the tutorial you’re looking for is right in the MCC boilerplate code.


Two Weeks with the MPLAB Xpress PIC16F18345 Evaluation Board

DM164141 boxIt’s been about two weeks since I started learning the MPLAB Xpress PIC16F18345 Evaluation Board in earnest. I went from having only a vague idea about PIC micro controllers to having a decent grasp on the strengths and weaknesses of Microchip’s family of 8-bit PIC micro controllers. From never putting my hands on a physical PIC to writing several simple programs and wiring the PIC up to physical components. This is my two-week report.

The short version: The PIC is solid. Everything around the PIC16F18345 feels like a good start of an idea, but the current state is very rough.

The longer version, starting by getting the bad news out-of-the-way first:

Missing Technical Information: I had made a first pass through the PIC16F18345 data sheet to learn about the chip. It had more information than I could possibly absorb on the first pass. But similar information is nowhere to be found for the evaluation board built around the chip. The only documentation on the product page is a quick start guide that boils down to “Login to MPLAB Xpress website”. There is no data sheet, no schematic.

First example: I stumbled across the USB serial port functionality by reading an example. I should have been able to learn about it from technical documentation.

Second example: There are two soldering pads on the board labelled “3V3” and “5V” implying it’s possible to switch voltage levels, but no details on how. Again, this should have been documented.

I hope this is the effect of a new product in a young product line, and it’ll just take some time for the documentation to show up. In the meantime, I remain in the dark about the specifics of this board.

MPLAB Xpress: I appreciate Microchip is making PIC development more accessible by moving software into the cloud, and building PIC programming hardware into a simple evaluation board. It is all very low-friction up until I found out the MPLAB Code Configurator (MCC) module requires Java to run. I hope they move MCC to be web-based as well. Once they do that, it’ll be possible to do PIC development from platforms like Chromebook and Raspberry Pi. Which will broaden their market for PIC development.

MPLAB X: Since I had installed Java on my Ubuntu anyway, I decided to investigate their full-featured IDE to compare against the web-based Xpress. I thought that I could compile the *.hex file in MPLAB X and copy it onto the evaluation board the same way as I do for MPLAB Xpress. Unfortunately this plan was foiled by how the two components interact.

When MPLAB X launches, the USB mass storage device on the evaluation board disappears. It doesn’t reappear until I quit MPLAB X and unplug/replug the board. I was hopeful this meant MPLAB X could talk to the evaluation board directly, bypassing the file copy stage, but I saw nothing of the sort. None of the MPLAB X programming functions seemed to know how to talk to the evaluation board. So in order to update the program on the chip, I have to quit MPLAB X and unplug/replug the board. This is an unacceptable workflow. I have to stick with MPLAB Xpress until I find a solution.

Serial communication is flaky: In addition to the USB mass storage device disappearing under MPLAB X, I also had problem with the USB serial port for the chip to talk to my PC running Ubuntu. It would frequently fall out of sync with the host PC and result in gibberish. I could work around the issue by making sure software flow control is activated, then quit/restart my instance of minicom. But this shouldn’t be necessary.

No hardware debugging: The USB mass storage based programming interface is pretty innovative. The downside is that there is no way to debug the code running on the hardware through this USB port.

OK, I’m done complaining. It’s time to recognize the good this product represents.

For the audience of people like me, interested in getting into PIC programming, it is fantastic. This product line has lowered the barrier of entry tremendously. Ignoring MCC, the software side is far more easily accessible than before. On the hardware side, the evaluation board has a retail price of $12, a fraction of the price of admission previously charged for PIC development.

Before this product, the least expensive PIC programmer device from Microchip (PICkit 3) has a MSRP of $60. And that money doesn’t even include any of the connectors, the circuit board, serial port breakout, power supply, or the PIC itself! All of those required pieces have been simplified and integrated into a single $12 evaluation board.

What I have in my hands today feels like a very rough first draft of a new and very promising product line. As a PIC development platform for beginners, we’re nowhere near perfect today. The features are rough and the documentation is thin. But I sincerely hope Microchip keeps refining this effort and filling in the gaps of this product line.

Know Thy Chip: Reading the PIC16F18345 Data Sheet

Now that I got a taste of PIC development with the tutorials, I have a much better idea of what a PIC can and can’t do. That survey gave me a rough outline with which I can use to keep myself oriented while diving deeper. So on the advice of a local longtime PIC tinkerer, I dove in to the authoritative source: the data sheet Microchip publishes for the PIC16F18345 chip.

I rarely deal with a PDF with so many pages. Take a deep breath, we’re going in!

This data “sheet” is actually a tome with almost 500 pages (as of rev. E) of dense technical information and it would be unrealistic to expect that I would understand all of it or even be able to remember very much of it. Fortunately that is not the goal. This first pass will let me know the kind of information that could be found in the data sheet. So that when I need to know a specific detail in the future, I know I can find it here.

I was surprised to find power management as a topic again and again, but in hindsight I shouldn’t be. PIC micro controllers are used in a lot of small battery-powered devices, catering to engineers building devices that run on a tiny battery for weeks, months, or years. People who build these solutions (which doesn’t include me… or at least not yet) need to know how the chip can be put into various low-power modes and what functionality does or does not work in those modes.

Another topic that received a lot of pages in the data sheet are the integrated “core-independent peripherals” that handle common tasks. The different sets of peripherals are a large part of how one PIC edition differs from another one in the same family. Each peripheral is briefly covered in the data sheet with basic description and a rough outline of how to use them on a PIC chip.

Some peripherals are fairly straightforward in function: the serial communication tutorial has already introduced me to the serial modules, and I paid special attention to the I²C communication peripheral since I intend to use that to communicate with a Raspberry Pi. I smiled at the Configurable Logic Cell peripheral because I recognized it as the modern replacement for the network of 7400-series chips that I last saw in college lab exercises.

Others peripherals are less obvious to me. I can read the description for modules like the Complementary Waveform Generator, but my brain has yet to make the connection between these tools and the problems I would solve with them. I hope that when the appropriate problem arises, I would recognize it and know to come back to the data sheet to learn how to design a solution.


Combining Tutorials for Serial Communication on PIC16F18345

As I read through the tutorials mentioned in the previous two posts, I tried to follow along on my tool with the long name “MPLAB Xpress PIC16F18345 Evaluation Board“. This was a good exercise because those tutorials were written for different demonstration boards. Following along required some modifications to run on my specific evaluation board, which meant I had to have enough comprehension to know what I needed to do. I couldn’t get away with just monkey-see monkey do.

Case in point: the serial communication project in the MCC tutorial. There were a few differences to reconcile before I got it up and running on my own hardware.

By this point in my PIC self-education, I knew how to resolve most of the differences. The PIC itself was different but not a hinderance. The tutorial’s PIC16F1709 has the same USART module as my PIC16F18345 and understood the same instructions. The tutorial called for a PICkit 3 programmer/debugger which is different from the programmer built into my evaluation board but I’ve learned how to program my board. And the tutorial used the full-featured MPLAB X IDE application whereas my board was designed for the web-based MPLAB Xpress. For the most part it was a matter of navigating different menu structures.

The serial communication lines, though, got a little trickier. The tutorial calls for a PICDEM Lab II development board equipped with a MCP2221 breakout module to allow serial communication back to the PC. I thought I was stuck until I found a serial communication example specific to my evaluation board. This is where I learned the board has a built-in serial communication module hard-wired to specific pins and routed back to the PC connected to the USB port.

USART diagram
This diagram in Microchip’s tutorial labelled chips with different numbers than what’s actually present in our setup, but we get the idea.

From there it was a matter of combining bits and pieces from both tutorials in order to assemble a project that implements the serial communication functionality. This project is also where I experimented with tracking MPLAB X project directories in Github, so I could share the results with the world.