Redis and 595 Timer States

24 Sep 2014

I wanted to learn about how a 595 timer chip works. I’m a code dude. So when I see this integrated chip and all its pins, it’s scary. I’m sure an EE major is giggling right now but that’s just Impostor Syndrome. For no reason beyond this, I wanted to visualize and grok a 595 timer’s state at any given point by having it’s pins mapped to Redis key/value pairs.

Here’s a quick video explanation of the project.

Sketch

Here’s my initial drawing on how I thought it was going to work.

It didn’t work this way in the end. There were no buttons and it didn’t
send the number over serial. Also, I did 3 bits instead of 8.

Electronics

Reading Values

The biggest problem with reading values off the timer is that eventually it’s going to be sent to redis. And that means Ethernet and the rest of the stack. This is not very easy to do with Arduino even with a shield. I’m not really a huge fan of making the Arduino do “computer” things. I could have made the same Arduino read the values off the 595 but to me it seemed like it would look like there’s some cheating going on. So instead, I decided to have a Raspberry Pi read the values off the 595 timer. It has networking built in and it would give me a chance to learn about its GPIO.

GPIO is not what I expected. There’s some annoying security gotchas. You’ll get cannot access /dev/mem. You will get cannot read /sys/class/gpio/export. If I’m going to use a Raspberry Pi beyond this little toy, I need to figure these things out. I’ve tried adding users to the groups that ship with Raspbian but it doesn’t change the /dev/mem access. I think you don’t want to mess with permissions on that node, it’s too messy/risky even for a toy.

All that annoying stuff aside, reading values with the Ruby gem pi_piper is easy (although not perfect). It’s evented and that made me happy when considering what I would have had to have done in Arduino-land. It would probably be some kind of hardware interrupt and a whole lot more code than what I want.

Putting it all together

Here’s the wiring.

Here’s the ruby program output. It monitors Redis state and prints a table.

What? Even after bouncing my RPi I get this. What kind of clean up isn’t this thing doing? So now I fix it by doing this between program runs:

echo 17 >/sys/class/gpio/unexport
# I was using pin 17

I also wish that you could break out PiPiper’s watch events to have two blocks for the same pin. Like when goes:high = bake brownies and then when goes:low = frost cupcakes. When you try to run two watches you get Device or resource busy. In fact, you get that error all the time no matter what you do. Meh.

What Did I Learn

RPi GPIO isn’t perfect.

Sudo stuff is unfortunate.

The best way to reset GPIO if it complains about Device or resource
busy is to unplug all the GPIO pins and reboot. Rebooting I think is
excessive because reboots in Linux rarely solve anything. What I
think it does do is give the pins time to quiet down. This is strange
to me from a /dev or /proc standpoint. I’ve never seen pins cause
file locks before (in unix, everything is a file, sure but it’s still
weird).

Clocks. I’m reading the state kind of “by chance”. What if the state changes in the middle of a read? Ah! Clocks! It’s like a contract! I get it now. I’m not interested enough in making this “lolscale” to implement this. I bet there’s something better than what I’m doing.

The 595. Through playing with the 595’s various aspects, I feel I grok the 595 now.

This won’t scale forever. Reading the pins is slow and the 595 can really flip states fast. If I really wanted to read this at some kind of insane throughput, I’d have to really think about it. In other words, this toy is kind of performance-stupid.

Grounding is very important. I had some shorts along the way and I don’t understand why.