Node.js Scroll pHAT HD Module


Hey all, as part of a project I used a Scroll pHAT HD and Raspberry Pi Zero W for, I ported the python Scroll pHAT HD driver to node.js, my preferred scripting environment.

While I can’t promise support, and there’s some known wonk detailed in the readme, I have pushed my code for communicating with the display from Node to Github and done some work to document it here:

Hopefully that provides enough information that if you’re familiar with node, and node on Pi in particular, you’ll be able to get it working.

Here’s one more minimal example, where we display an alternating field of on and off pixels:

// get a reference to scrollcontroller
var scrollController = require('scroll-controller')

// make an array of 0-255 pixels
var arr = []

for(var i = 0; i < 119; i++){
    arr[i] = i%2 == 0 ? 255 : 0

// scrollController will drop messages it receives before the display is init'ed
// so we wait a 100ms and then call display with our pixel array.

As it wasn’t relevant to my use case, I didn’t port any of the higher order functionality, scrolling behaviors or what have you, but I have been using this code on my Pi for 3 months and have worked out most of the kinks for long term running, so I think its reasonably reliable at least in the hobby use case, so if you, like me, aren’t a huge python fan, maybe this will be what you need!

My project for the curious was a transit/moon phase/weather display, which you can get a glimpse of here:


I wonder if your bug is somehow related to setFrame(currentFrame) or your init routine never being reached. I can’t see anything wrong with the general steps of your implementation, but I have a little trouble following the flow of NodeJS code.


Around here you mean?

Thats roughly analogous to but more js idiom-y, since the i2c-bus module I’m relying on provides async calls I unrolled my chunk writing loop into a series of callbacks.

At line 123, we create but don’t call an anonymous function to swap the back buffer to the front buffer in the event that we are about to write the final chunk. That lambda is called when line 128 finishes, ie after our last chunk write completes.

It does get reached, in that we’re able to flush the whole display buffer and have it display, but there’s something about the state of the screen at boot, or maybe state of system i2c at boot that the first party code handles and my code does not, at least apparently.

Though in talking through what that part of the code does, in typical rubber duck fashion I’m realizing that the error handling in that section wouldn’t … work. I am not near my Pi to test this fix, but that section should likely look something more like this but I’ll have to test it later.


Oh, and we call into init from:

after we’ve successfully opened the i2c bus.

Thanks for giving it a look by the way!