Electronics


I recently converted from SVN to Git and needed to break my legacy SVN repositories into separate git repositories. This turned out to be much harder than I thought.  After a lot of googling and much trial and error, here’s the process I settled on:

  1.  Create new remote repository new-repo
  2. Clone new-repo locally
  3. Execute command line:

    > cd new-repo
    > git remote add old-repo https://github.com/cyberreefguru/old-repo.git
    > git pull https://github.com/cyberreefguru/old-repo.git master
    > git rm -r old-folders
    > git mv files-around-as-necessary
    > git commit
    > git push

Hope it helps someone.

Construction (Sort Of)

In Part 1 we learned about the requirements, and in Part 2 we talked about the design.  Now the rubber meets the road.  I did the research and the design.  Now I needed to manufacture some printed circuit boards and put the design to the test.

Laying out the PCB was a little cumbersome since all the chips wouldn’t fit neatly on a normal sized Arduino shield, so I had to make the board a little larger than “normal”.  Not a big deal, but a little less ideal than the perfectionist in me wants.

After the boards were manufactured, I order some solder stencils and set out to solder everything.  Since the board is almost exclusively surface mount, this would be my first foray into assembling a surface mount device (SMD) PCB on my own.  I’ve done it professionally, but in that case I paid other professionals to do it for me.  I’m way too cheap to pay someone to do it, so I did it myself.  I’ll probably write about that experience separately – it worked out very well and I am super pleased with the results.

Driver Shield and LED Strip PCB

Driver Shield and LED Strip PCB

Driver Shield

Driver Shield

Once the boards were done I had to write all the software for the Arduino.  Writing the initial code was fairly easy, but getting it work properly was a huge pain.  The design / build process was orderly – test the driver first, then test the columns, then put the pieces together.  All went well.  Once I could turn LEDs on and off using the full complement of capabilities, I turned my focus to the multiplexing an driving a 48×16 array.  This is it got really complicated and really frustrating.

I spent many hours futzing with Arduino timers, optimizing the software, and really worrying about how many CPU cycles each routine was using.  In the end, I had to collapse most of the time critical code into a single routine and give up any hope of controlling the full array using the full depth of intensity settings

Embedded Software Design 501

Yes, I said 501.  This is not 101 territory.

This design contains a matrix that tis 48×16, which is 768 “nodes” individually addressable.  Each node has a 12-bit pixel depth, or intensity level.  Microcontrollers don’t understand 12 bit, so we get to round up to 16-bits, or 2 bytes. Easy enough – 48x16x2 = 1,536 bytes to fully control the entire matrix.  Oh, good software engineering says we double buffer the bit maps to avoid any “hiccups” with display intensity, so we need 3,072 bytes.

Now, I spent nearly a decade designing and implementing embedded solutions professionally, so I was very conscience of how much memory my program used.  However, I did not set down in advance and calculate it out like I did above.  Had I done that, I would have predicted, and avoided, many, many hours of exasperation.  You see, the Arduino microprocessor only has 2K of SRAM, and approximately 500 bytes is used by the bootloader, leaving only ~1500 byte free for the user.  So, I had approximately 50% of the RAM available to me that I needed.

Rather than the compiler flagging me and saying “hey, idiot, you have allocated more than than is available”, the code uploaded fine and operated fine.  For a while.  Then it started behaving oddly.  It didn’t stop working – it just stopped working properly.  More importantly, code that used to work, stopped working properly.

**THE MOST FRUSTRATING PART OF EMBEDDED PROGRAMMING EVER**

So after many hours of adding print statements, changing code, commenting things in and out, I finally narrowed the issue.  When I commented some code out, it worked fine; when I commented it in, it failed.  First and most classic sign of a memory problem.  When and finally sat down and did the math.  Duh! I am an **idiot**.

(For the record, adding print statements actually made the problem worse by using up even more RAM.  Great, eh?)

Compromise time.

I needed the double buffering, so my only choice was to narrow the intensity density.  But cutting it in half still pushed the memory requirements to ragged edge.  Remember when I said the boot loader uses “approximately” 500 bytes.  Yeah, well, that approximately is super important when literally every byte matters.  After a lot of debugging, it turns out I was using about 20 more bytes than were available, **if** I called more than 2 subroutines.  And which subroutine I called changed how much memory was required.

This my friends is called the “stack size” and it is really important.  When you push something on to the stack, it uses memory.  When that memory is used by something else, like say a variable in your interrupt service routine, it tends to, ummm, f*ck sh*t up.  Bad.

Ok, so that’s the lesson learned about advanced embedded system programming.

  1. Know exactly how much memory you need
  2. Know exactly how much memory you have
  3. Only use how much memory you have

Seems basic.  But without an embedded debugger and a super expensive logic analyzer, it can take you days to figure out.  Days and days and day.

In the end, I had to combine a number of functions breaking all normal OO programming “rules”, use direct bit manipulation instead of the stock Arduino functions, and count the number of CPU cycles for certain operations before the code worked properly.

Once I got the code to work properly, I had to assemble the entire thing on the Power Tower itself, which led to much fun and amusement.  All of which will be documented in the next article, Part 4.

In Part 1 I discussed the “requirements” for the project and determined none of the solutions I found on the Internet met my needs.  So to the drawing board I go…

The Design

I combined a couple different ideas into a single solution.  I decided to use a PWM-enabled constant current LED driver for the rows, shift registers to control the columns, and a set of “high side drivers” to provide the voltage and current for the columns.

Now, you might think that using a constant current driver would have “solved” the current problem wouldn’t you?  Well, that’s what I hoped but here’s a quick diversion into EE 101 for the implications for my design.

To save on the total number of output pins, I grouped 3 LEDs together.  To turn the LEDs on I need exceed their combined forward voltage.  For normal red LEDs, that’s about 2.1v; for blue and green LEDs, that’s about 3.2.  I wanted a mix of all colors, so I knew the source voltage had to be between 6.3v (2.1 x 3) and 9.6 volts (3.2 x 3).  The “closest” normal voltage is 12v, which is what I settled on.  That means the anthode would be connected to 12 volts while the cathode would be connected to ground.

LED Schematic

LED Schematic

As mentioned above, I decided to use to a constant current driver to control the rows, which puts the constant current driver at the cathode (i.e., ground).  As such, I need to drive the LEDs at 12 volts, but also use a constant current driver at the cathode.  Additionally, I need more current at the anthode than a single microcontroller ping can provide (~500mA vs 30ma).  Therefore, I need some sort of transistor at the anthode and there is where things get complicated.  Nearly every simple switching circuit I found would only work properly if the source voltage does not exceed the voltage controlling the transistor.  In my case, the control voltage is a normal logic level of 5 volts, but the source voltage is 12 volts.

I researched a lot of different configurations before I finally found a solution that meets the needs.  In short, I needed a “high side driver” – a driver that lets a small range of “drive” voltages control a larger range of “source” voltages.  Fortunately, there are a couple ICs on the market that (mostly) met my needs.  I really wanted to switch an entire column with a single control circuit, but an entire column would be approximately 840mA and all the solutions I found maxed out at 500mA.  So, I needed two ICs per column, leading to 16 “columns”.

After it was all said and done, I needed up with up to 48 rows, and up to 16 columns in the final design.  I combined two TLC5947 (code complements of Adafruit) constant current drivers with 2 74595 shift registers for the columns. The shift registers feed a pair of A2982 high side drivers that provide the current to the LEDs. In this configuration, each column can provide up to 500mA allowing me to switch approximately 25 rows at a time.  That almost perfectly separates the design in half; the 5947 provides 24 rows and the 74595/A2982 pair provide 8 columns at 500mA.  Double everything and I have 48 rows x 16 columns, or 768 control lines.  Theoretically, I can control 768 triads of LEDs, which is a whopping 2304 LEDs!

LED Driver v1.0

LED Driver v1.0

Fortunately, I did not need so many LEDs for my purposes.  Part 3 will document the manufacture, assembly, and testing of the final solution.  Stay tuned.

Intro

Last year around this time I started a new project to challenge my abilities in hardware design and software programming.  Truth be told, I have been thinking about the project for a number of years, but never really had the time to work on it.

The idea was to outfit a Faller Power Tower ride with LEDs lining the tower.  There are a number of videos on YouTube with something similar, but none of the videos really show the mechanisms up close or provide any details on how they accomplished it.  I’ve always been fascinated with the shear number of LEDs on some of the videos and prospect of controlling them.  So, I set out researching the control mechanism, mounting techniques, and assembly ideas.

I guess I should forewarn anyone who might read this, I had not fully thought through size and scope of the project.  Nor the slippery slope I was about to slide down.  In the end, the first phase of the project yielded approximately 1000 LEDs lining the sides of the power tower, and Phase 2 led to approximately 219 more LEDs for the mast, and Phase 3 will lead to another 219 for a main sign.

At this point any sane person might think I’m crazy or simply bored.  Neither.  Just the average maker looking for a challenge.

So, on with the description, pictures, and maybe a video or two.

Planning

To drive a lot of LEDs, you need a lot of output pins and a lot of current.  It is simply not feasible to control each (normal) LED individually.  Building a circuit with over 700 outputs would be very problematic, not to mention wiring 700+ wires would be, well, crazy.  Likewise, controlling the intensity of each LED with any level of granularity leads to all sorts of other complications.

I knew multiplexing would be in the future, so researched all the popular mechanisms and prototyped the more popular ones: Matrix Multiplexing and Charlieplexing.  Then I investigated ways to control the intensity, which included Pulse Width Modulation (PWM), Binary Code Modulation (BCM), and a couple other techniques.

Multiplexing and controlling many LEDs with as few pins as possible is well plowed ground.    The Internet is full of ideas, circuits, and code.  After much, much research, I decided a traditional matrix was the best solution.

“Requirements”

The power tower is approximately 25 inches tall.  I felt it would look very odd with only one side lit so I decided I wanted to have LEDs on all 4 sides.  I also determined a single strip of LEDs per side would look very odd.  So I settled on a column of LEDs on each corner of the tower, working out to 8 strips of LEDs, approximately 25″ long.

I designed and manufactured some LED strips for my research with multiplexing (shown below).  The strips are each 3.625″ long, with 6 groups of 3 LEDs each, totaling 18 LEDs per strip.  That means 6 outputs per strip and a common anthode.

LED Strip Schematic v1.0

LED Strip Schematic v1.0

LED Strip PCB v1.0

LED Strip PCB v1.0

Here’s where the real world enters and I start doing the math.  25″/3.625″ = 6.89 strips; I’ll round down and make it 6.  8 columns x 6 strips/column = 48 strips.  18 LEDs/strip = 864 LEDs.  Holy crap.

Ok, so despite the Internet being full of a lot of useful information, nothing I came across led to a matrix of 864 LEDs. Further complicating the situation, my LEDs were grouped in 3’s and powered by 12 volts instead of the more “traditional” 5 volts.  I’ll get to why that’s important later.

I determined none of the “out of the box” solutions would work for me.  I needed more drivers than the solutions provided, or I required more current than the solution offered.

In Part 2, we will discuss the design and the build.

Ok, I have to admit, I may be an evil genius – or just plain sadistic; I’m not sure which.

On my Christmas vacation I decided to work on a project that I have had in the queue for about 2+ years.  When I had my last model railroad, I had a carnival on one side of the layout.  The main attraction of the carnival, besides the massive Ferris Wheel, was a ride called “Top Spin“.  It was a complicated ride to build and the build-out was even more complicated due to one of the main parts being broken when I received the kit.  Of course I didn’t know the part was broken until I was 50% complete with the kit – too far to send it back.

After fixing the broken part and finishing the kit, I added it to the layout and tested it out.  I didn’t work very well and seemed to only partially work right.  More fiddling and more fixing lead to a kit that mostly worked. Here’s a picture of the ride shortly after placing it on the layout:

Top Spin

I’ve never been completely happy with the results and have always wanted to dig into why the kit didn’t seem to work quite right. Well, after 2+ years of waiting, today was they day.  Well, it actually started yesterday, but I finished today. I took a deep dive into the mechanics of the Top Spin and built a new controller to completely figure out what the problems were. Well, not really. The new controller seemed to work much better than the stock controller, so I can only speculate on the problems.

I used a SN754410 half H driver coupled to an Arduino to control the motors on the Top Spin. After figuring out how to set up the pulse width modulation (PWM) capabilities of the Arduino, I set out to control the Top Spin.

My initial attempts actually went very well, but the motors moved fairly slowly – much more slow than what I remembered. I’m pretty sure the motors are 5V DC, and I was using the 5V from the Arduino, but things didn’t move as quickly as I remembered with the stock controller. A little investigation lead to the 1.1V-1.5V drop across the H-bridge circuitry. That means the highest voltage that can be applied to the motors tops out at about 3.5-4 volts rather than 5. Hmpfh.

A little digging into my spare parts led to a variable voltage regulator and a 12V DC power supply.  I quickly whipped up a variable voltage regulator using a surface mount version of a LM317.  The new power supplied fixed the speed problem and yielded a full 5 volts across the motor.  With that problem solved I set out to fully build out the code to drive the animations.

I needed to control 2 motors, read 2 reed switches, and output to two status LEDs.  The LEDs are optional, but helps debugging.  To adequately control the animations I will need to read the status of the reed switches while keeping the motors going.  That requires continuously reading the inputs while changing the outputs. Seems like I’ll need to read the inputs in the “background” using interrupts while driving the motors in the main loop.

Pulsing the motors is easy with the built-in capabilities of the Atmel part used in the Arduino; however, it wasn’t entirely clear which timers where used to control the PWM and which were available to use for other purposes. A little spelunking into the ATMEGA328P data sheet identified Timer 2 as an appropriate timer for interrupts.

To simplify my code, I used a timer library called FlexiTimer2 from the Arduino website. I’ve used it in the past and it has worked well.  Loading the code into my project was easy and the timer worked the first time, so I was off to the races.  I started with a simple sequence of spinning around with the main arm and then rotating the chair where the people will sit.  After some time playing around I quickly realized I need to ensure the animations start from the same place every time or the timing will be off – the arm and chair will end up in different place each time.

Using the reed switches and some fine tuning, I was able to return the chair to the “home” position reliably every time.  From there I continued to randomly build animation sequences without a lot of regard to timing or position of the chair. Without a lot of thought, I ended up with a pretty scary ride. A lot of upside down, backward spinning. After watching it run a few times, I have to say, if I was on that ride, I’d be scared sh*tless. I am an evil genius 🙂

Here’s a short video of the setup and the ride.

You’ll notice the Arduino on the far right and the breadboard with the motor controller and voltage regulator next to it. The ride was connected to the controller with spring clips and jumpers I had laying around.

I noticed after some playing around the voltage regulator seems to drop out if I run both motors at the same time. I’m guessing it’s because the SMD part does not have any sort of heat sink. Hopefully that will be fixed when the whole thing is soldered together.

You can also see in the video where the arms hit the sides and cause the gears to grind a bit. That’s what all the tape is for – to try and hold the sides completely vertical. I know once it’s cemented into place it will work fine (experience speaking), but on my desk it’s a little more difficult to pull off.

So after 16 or so hours fiddling around, I have to say I’m quite pleased with the outcome and the ease of getting everything to behave like I wanted. I guess the next step is to whip up some schematics and a PCB to act as a shield for the Arduino.

It will be a quite some time until I can get the next MRR up and running, but I now know I have a solid HW and SW platform to build from in the future.

About a month ago we purchased a small freshwater fish tank for my son. Now, as some may know, I have a little experience with aquariums. After a month of testing the water and farting around with dipping drops of test solution in tiny little vials, I got bored with the process. Surely modern technology has come further over the last 15 years since I first stood up my last tank. Surely there is an inexpensive, reliable, and comprehensive solution on the market for monitoring/controlling aquariums? Yeah, right.

Don’t get me wrong, there are solutions. The least expensive one is $119, and $279 for what I want. I could of purchased stand alone meters, but in the end it would of cost more ($89 each). So my natural reaction was to google DIY solutions. I found a fair number of people who have built controllers around the open source Arduino platform, which I have some experience with.

So I set out to build myself a aquarium monitor that can monitor pH, temperature, and will keep track of the date/time. Turns out there is a wealth of information on the web showing how to do this, and a bunch of crafty companies have made it really easy.

This article talks about my experience, the process, and the results. Hope you enjoy it.

I’ve recently completed a number of printed circuit boards to help control the rides in carnival. After a few turns on the PCB due to operator error and inevitable “betterness” over time, I arrived at my final design and fully populated 4 PCBs will all the parts necessary to control the rides.

After getting all the PCBs built and mounted, I connected a few rides and tested the software. It all worked perfectly for a while, then some of the rides would randomly restart. Hmmm, clearly a software problem. Many hours ensued, many small issues resolved, but still restarting over time.

Then I noticed that two or three of the rides would reset at the same time. Clearly not a software problem, because the rides all have different sequences and different designs. Hmmm, it started looking like a hardware problem. Using my voltmeter, I determined the power supply was cutting out. I assumed with all 4 boards connected, I was approaching the limit of the regulator chip and it was shutting down. I ordered a commercial switching power supply rated at 5V, 2A. That should be good.

Not so much. Although the restarting was less frequent, it still happened. Further debugging showed it happened with only one board connected, though much less frequently. Thus, one board could not be approaching 2A.

Without access to an oscilloscope, debugging the problem much further became very problematic. A quick search on the Internet yielded tons of new and used oscilloscopes – for hundreds of dollars. Hmmm – again. I don’t really want to spend that much money, so I sought alternatives. I eventually found a low cost, PC-based oscilloscope that got good reviews in some magazines. I ordered it and was ready for detailed debugged.

Once I got the oscope, I connected it to the circuit board and was a little shocked at what I found:



Though an extreme case of considerable harmonics, the amplitude and duration of the noise was pretty consistent every time the relay released the contacts. Note the peak-to-peak voltage of 23V on a 5V circuit. Wow!

It took some debugging, but I determined the issue was not the relay de-energizing, but rather, the switching of the AC voltage for the ride motor. It seems the rapid removal of the voltage was coupling to the signals and ground plane of the PCB and causing some pretty deleterious effects.

I’m in the process of adding a snubbing circuit to the motor to see if I can quiet the noise. More when the problem is resolved or mitigated.

Update – 3.28.09

After adding a snubber to both the incoming AC and the outgoing signal, I was able to eliminate nearly all the transient noise. Here’s a picture of the noise after adding to the outgoing signal. I was not able to get the oscope to trigger at 4.8mV after adding a snubber to both in and out. I hope that means the noise is gone.

Noise Reduction

Noise Reduction

Seems like this “project” is now complete. Next step is to get all the boards wired, mounted, and we’ll be done.