Saturday, February 04, 2017
Writing custom blocks turned out to be an easy thing, so I created blocks to modify the LED display, send audio out to a speaker, or react to button presses. Now you can use blocks to program the clock, while retaining all the functionality present in the older Python interface.
If I was going to redo the Hack Clock, this time I wanted to have a presentable site with full hardware and software lessons, for both Python and Blockly. I revamped the Hack Clock website, completed the Python lessons that I left incomplete last time, wrote new Blockly lessons for the new IDE, and completely re-did the hardware how-tos. Lesson writing took up the lion's share of time, since they all needed new images and better testing.
Another bit o' feedback I had received was that installing the Hack Clock software was too much of a pain. I tried to make this a bit easier this time by offering releases within a Debian pkg, although you still needed to use apt to install dependencies. Still, this cuts down installation from over an hour to about ten minutes... and most of those ten minutes is spent twiddling your thumbs while you want for packages to download and install.
The hardware needed tweaking as well. It turns out the Raspberry Pi headphone jack is just a PWM pin hack and it seemed that GStreamer sometimes just couldn't grok it. The headphone jack was never a complete solution either - it required a discrete amplifier to power speakers, and soldering wires onto a 1/8" jack is a GIGANTIC pain. To make the audio hardware easier to cope with, I moved away from the headphone jack to Adafruit's I2S decoder and amplifier. It provided better audio and cleaner installation without increasing my part count or price. It has proven out to be easier for everyone so far.
The old Hack Clock had another embarrassing flaw: it could only handle one button input and couldn't manage output at all. That drove me nuts and was probably the second biggest thing I wanted to fix. With the latest release the Hack Clock can handle as many buttons as you have GPIO pins, and you can also drive output pins as "switches" in code. The code-by-blocks IDE could deal with buttons and switches as simple function blocks - which meant reacting to user input became much easier to code.
Once things were ready, I installed the Hack Clock software in a mission-critical environment: kids' rooms. So far things have gone well; audio has been more reliable than with the headphone jack, and they have been able to tweak the software more easily than with Python. One bit I noticed this round however: kids don't like looking down to read something, then looking back to code it. The next generation Hack Clock should have an interactive demo to guide through the lessons so they never have to glance away from the IDE.
I'd love to hear what other people experience when they try to get the Hack Clock running as well. A hardware list is posted on Hackaday, and all the instructions are at http://hackclock.deckerego.net/. Let me know what you think!
Thursday, December 15, 2016
Fast forward to Christmas of 2014 - I purchased a arcade cocktail cabinet from Rec Room Masters. After it was assembled in Ikea-like fashion I mounted an old monitor, discarded 2.1 speakers and an Raspberry Pi 3 inside of the chassis. Nifty.
remix a hole cap on Thingiverse and print black caps to fill the gaps.
I wanted the Raspberry Pi to sit a bit out of the way, so I screwed it into the VESA mount that the monitor rested on. After sawing an Adafruit perma-protoboard in half I was able to craft some custom headers that allow ribbon cables to connect from the Raspberry Pi and join with header posts for the joystick pins and buttons. This allowed for much better cable management and room for the subwoofer & speakers underneath.
I wasn't interested in installing a coin door on one side - so I kept it wide open and instead had the cabinet door facing the center of the room. Little had I expected that cats would LOVE climbing in the open gap of the cabinet... and ripping cables off my Pi. I shoved the open side against the wall - allowing the extension cord to conveniently poke through - and now the only access is through the swinging door on the opposite side.
On the software side, joysticks and buttons are mapped through mk_arcade_joystick_rpi, an archaically named but amazingly useful module that allows GPIO pins to become joystick inputs recognized by Linux. It took some work in order to have libretro recognize these buttons; many of them had to be remapped. However, libretro quickly became my go-to MAME emulator and now supports controls on both sides of the cocktail cabinet.
RetroPie display setup to rotate the screen 90˚, but luckily so many cocktail cabinet titles were programmed for this 4:3 aspect ratio. Titles are working flawlessly now, and I can host two-player action by flipping a few emulated dip switches.
One thing I found interesting was how MAME distributions were entirely dependent on the exact name of your zip file. In addition, each ZIP was a true manifestation of the on-board arcade ROMs - in that sometimes a US distribution or second edition game actually piggybacked on top of a previous ROM. In this same way, two ZIPs were sometimes required to run a single title: one for the older ROM, one for the later version. I ended up combining the two ZIP archives into a single one - in this way older ROM images were still injected as a dependency, while the ZIP name was that of the older title and was still executed correctly.
Pizza night at the household now takes on an entirely new meeting. A few slices and a frosty beverage helps me appreciate Ms. Pac-Man in a whole new light.
Wednesday, October 07, 2015
While the current Raspian distribution still relies on wiringPi 2.24, the most recent 2.29 version has a much nicer way of addressing GPIO in userspace by exposing the GPIO ports in /dev/gpiomem. All too often Raspberry Pi developers run GPIO apps as root to access the array of general purpose I/O pins, however this leads to all the lovely security holes and vulnerabilities that privileged access brings. You never want Apache or Python or any user-created apps running as root - so instead you must find a way to export these ports and allow unprivileged users to access them. Traditionally this has been done using wiringPi's export utility, however the latest gpiomem exposure seems to be much cleaner.
With Jessie I've been able to significantly cut the complexity of installing Garage Security and Sprinkler Switch. I don't need to manually install wiringPi, Node.JS, Video4Linux and a number of other packages. Things seem to largely "just work" as one might expect of a modern distro. One example is that Motion has been updated and appears to be pre-packaged on Raspian, and the necessary Video4Linux bcm2835-v4l2 kernel module properly creates a /dev/video0 device. CPU utilization appears to be much lower with the current stack, and it appears that I can just tweak Motion's configs to save videos in an HTML 5-friendly way rather than transcoding them with a script.
Garage Security and Sprinker Switch are being updated now for Jessie and testing is underway... the new Jessie builds are looking very promising so far.
Friday, September 25, 2015
For a long while I’ve relied on Jabber/XMPP support within Google Talk to communicate with back-end systems like my Garage Security monitor. Garage Security could push notifications to me when motion was detected, and I could reply back to ask for camera snapshots or current temperatures. It’s almost as if I was using XMPP and Google’s Talk servers as a message bus; everything was a request/response pair that I could receive as notifications in a nice lil’ mobile interface. This was a superior approach to having a peer-to-peer communication channel over the Internet at large - I could keep my firewall completely closed and instead publish events to a trusted broker over at Google HQ. I essentially treated Google Talk like a hosted RabbitMQ instance.
This "XMPP broker” approach continued to work after Google moved from Google Talk to Hangouts and dropped full XMPP support (notably for federation), however things appear to have become a bit more difficult when two different systems (like Garage Security and my new Sprinkler Switch) want to share the same Hangouts user ID. Previously both systems would receive an inbound message, so I would filter by a token in the message body. If I asked for “garage status,” Garage Security would catch the “garage” keyword and respond while Sprinkler Switch would just ignore it. As Hangouts has turned the XMPP support decidedly more text-message-ish, it seems now the last system to authenticate will starve out the previous system, and only one system will actually receive the messages.
This is not outside of the XMPP spec it seems, and the protocol itself specifies two ways for the systems themselves to deal with the issue:
- When connecting to the XMPP server set the priority for your connection. A higher priority is more likely to get inbound messages.
- Specify a resource name within your XMPP user identifier. This allows a system to be uniquely addressable with the same username.
The first option doesn’t necessarily help my situation - I want both systems to receive inbound messages. The second option is possible using XMPP’s definition of user IDs… where a user identifier is actually the composite of:
- The username that is used for authentication
- The domain that the user resides within
- The resource that uniquely identifies who is signing in
email@example.com/garageand have it uniquely identify Garage Security, while
firstname.lastname@example.org/sprinkleruniquely identifies Sprinkler Switch. It’s not entirely unlike the routing key in AMQP or a topic name in JMS…
chucklefacecould be considered your message type,
gmail.comcould be considered your exchange, and
garagecould be considered your ID. Or something like that. It makes sense in my head at least.
Hangouts, however, just cares about chat messages. It could give two craps about my resource name. There’s no way to specify that in a contact either… with Hangouts you specify an e-mail address which in turn becomes a username and a domain. That’s fine for chat… but when I want to address an individual system I’m kinda outta luck. Hangouts will just reply back to the last resource that sent it a message - no way to specify a specific resource.
I've posted a demo using Python on GitHub which lets you build a quick XMPP client. An example might be:
>>> from jabtest import Jabber >>> jab1 = Jabber('email@example.com', 'apikeyh4x0r5', 'testone') Opened XMPP Connection >>> jab2 = Jabber('firstname.lastname@example.org', 'apikeyh4x0r5', 'testone') Opened XMPP Connection >>> jab1.send_msg('email@example.com', 'Testing One') Sending message:
I don't have a fantastic solution for now... so in the interim I've disabled Jabber support for Sprinkler Switch.
Monday, January 05, 2015
Even though the driving force behind the blog had faded away, and even though no one else reads this blog (aside from the State of .NET Integration Frameworks post), I kept updating it. Writing - even if it exists only for your own edification - really does help with communication and critical thinking regardless of what you write about. Even though my day job has nothing to do with garage door openers, my posts on my garage door security system helped me organize the build in a way that informed the Hack Clock project. Back in 2006 I began investigating vector processing, and the resulting frameworks have helped me think about and design microservice architectures. Of course, there was plenty of venting as well with my favorite software companies being dissolved or SuSE Linux winning and failing and winning and failing again. All of this writing helped me when performing comparative analysis at work, or designing parallel architectures, or watching trends in software development.
It is hard to believe a decade has slipped by. It doesn't even seem real. I don't think I've evolved much since that one cram session in a crystal chair, but I'm glad to have my collected ramblings to reflect back on.
Sunday, January 04, 2015
I was able to take a Leaf out for an extended test drive and make sure it fit my commute - which it did. I couldn't find another auto manufacturer that actually had an EV on the lot aside from Tesla, so the Leaf was the only auto at my price point. Luckily there are many Nissan dealerships in my general area and I ended up picking a Model S Leaf that I have been driving for a few weeks now.
One great thing about an all-electric auto is that your garage is transformed into a "gas station," and you never need to leave your house to refuel. Bear in mind this does not necessarily mean you can use your normal 120V outlets to charge the car (using a Level 1 plugin-in charger) - you will at the very least need a dedicated circuit for charging, lest you blow a fuse from too much load. On my 24-hour test drive I quickly found out that the 120V outlet in the garage was on the same circuit as the master bathroom; when the car's 120V charger was powering up the battery it was consuming 11.3A of power, and a typical hairdryer will eat 12.5A. The combined 24A of load will trip your typical 15A circuit breaker quickly.
Ultimately a 6 kW, 240V/30A (Level 2) charger is necessary for home charging since even a dedicated 120V outlet will require 21-ish hours to go from empty to 100% charge. Normal usage often requires a 10.5 hour charge with 120V, which can easily be done in 4 hours with a Level-2 charger. The good news is that while the chargers offered through the dealership appear to be fairly expensive, Home Depot and Amazon will sell Level-2 30A chargers for under $500. If you add in the cost of an electrician adding a 40A 240V dedicated circuit, you can have a 6 kW charging station for under a thousand bucks. The daily cost per kilowatt will be the same, and while there are some who worry about peak/off-peak charging hours most residential agreements seem to bill based on volume, not based on time of day. 6 kWh at 2 AM is billed the same as 6 kWh at 2 PM.
The technology is changing rapidly. Level 2 chargers are rapidly eating from 20 amps to 30 amps to 40 amps, and Tesla is building a nationwide Level 3 charging network based on renewable energy. It's hard to say how all of this will play out... in 5 years we may have sedans with a 400 mile range... in 10 years we may have self-driving cars in metro areas... in 20 years 25% of new car sales may be EVs. Ari Jay's comparison between the Leaf and the Tesla S85 is a great example of the current state of the market - in the end both cars are great, to serve two different purposes and two different drivers. We're getting past early adoption, sliding past the peak of inflated expectations and heading towards the trough of disillusionment. Sure people are getting a bit anxious on range and worried about cost... but on the other side is mainstream adoption, and the widespread infrastructure to support electric vehicles and cross-country road trips.
Wednesday, December 31, 2014
and it is time to look at something more efficient than a controlled explosion eighteen inches from my knees.
The first issue I encountered when shopping for an EV was that dealerships still seem to be getting accustomed to selling all-electric cars. Several salespeople outright refused to speak to me about the Leaf, and instead passed me off to other sales reps. I couldn't find a single salesperson who would let me drive a Ford Focus. After I pried a bit further, it seems like the more "senior" sales staff believe that EV buyers are too high maintenance - the buyers don't understand the range issues, they fear higher return rates, they get cold feet and back out of the deal. Even the sales staff that would talk to me pressed very hard for a commitment, wanting faux signatures and asking for money down prior to delivery. I spoke to lot managers about the Leaf turnover rates, since I felt they had a more accurate sense of how inventory was moving, and they seemed to think the actual return rates were much lower than the rates the sales guys were assuming. For one lot, out of 15 Leaf sales only 1 had been returned.
If you troll the EV forums you find that there is some hint of truth to the conception that potential all-electric owners are a high-maintenance bunch. Several complain that they had to wait a whole 5 minutes in a maintenance bay, others are incensed at the 87-mile range, and many aren't quite ready for the anxiety of finding a charger when they need one. If you are planning on using an EV as a secondary commuter car the stress can be much less, however an all-electric primary car can definitely give you an ulcer. Electric vehicles definitely require a cultural fit right now, which may be why there is such friction between buyers and sales people.
As odd as it might seem, Focus/Leaf/i-MiEV/Soul/i3 owners are more akin to Corvette than to Corolla owners. A happy Leaf owner frets over charging temperatures, battery chemistry, wind resistance, regen strength, residential electrical codes, LED vs. halogen amperage - and enjoys doing so. Just as a Corvette owner is worried about properly gap'ing spark plugs, an EV owner is worried about electrolyte conductivity. If you wouldn't enjoy obsessing over the winter tires of a 'Vette, you likely wouldn't like obsessing over the optimum tire pressure for maximum EV range.
In all honesty, I've never been a car guy. I know that the engine belts form a mobius strip to allow for even wear... and... there are cables? And various and sundry liquids? Not sure. However, the mechanics of an EV are much simpler to understand, which lets dullards like me become car guys because there is
so much less to know. As is entirely too apparent, I'm more than happy to obsess needlessly about the baubles of technology... and so I think I can make the shift from the mainstream "it just works" mentality to the gear-headed "how does it work" mentality. Mainstream adoption may not be there for EVs just yet, but wannabe car guys have the perfect inroad now.