The Haskellboard is an electric longboard that uses Haskell to control the motor using input from a Joy-Con. It uses a Raspberry Pi Zero W, which I selected for its form factor and wireless capabilities.

intro

Recently, I’ve had the urge to play around with alternative transport methods. I don’t have a car, so getting around places gets kind of difficult sometimes. Commuting tends to revolve around carpooling, taking Ubers, and, more recently, taking the bus. I like to travel this way over driving, but it does come at the cost of immediate convenience.

During my time in my high school robotics club, it became almost a tradition for upperclassmen to build so-called ‘boosted boards’ — electrically-powered longboards you controlled with a remote. I’ve always wanted to build one myself, but I never really got around to it until now.

why haskell ? ??

Haskell is not the most ideal language to use for this sort of project — it would have been easier to slap some generic Arduino code on and be done with it. During the inception of this board, I was working my way through the Haskell book. I was itching to use it in a practical setting, so I figured that writing the software for the board in Haskell would be a fun way to apply what I’ve learned! It would also be a little novelty for me to mention ;)

code

https://github.com/noneucat/haskellboard

observations

Haskell ecosystem on the Pi

I was pleased to see that (for the most part) everything builds and runs as expected on the Raspberry Pi. A pleasant suprise came in the form of the wiringPi bindings on Hackage. I thought that I’d have to write my own bindings for PWM output myself, but luckily some work has been done on this front already!

Using Yampa

I based the software on the Yampa FRP framework.

A quick overview of Yampa’s approach to FRP: a signal in Yampa represents a time-varying value (Signal a). A signal function represents a transformation of a signal into another signal (SF a b). More complex signal functions can be constructed out of primitive signal functions and then executed as an IO action. I encourage you to take a look at the slides here for a more involved explanation.

The core of the program is one large signal function. It transforms an Inputs signal (representing input updates from the Joy-Cons) into an Outputs signal (representing motor output).

I found it difficult to formulate logic using Yampa, but I feel that this is mainly due to my unfamiliarity with FRP and not Yampa itself. Once I got over the initial learning curve of Yampa’s DSL, I found it incredibly concise compared to other frameworks.

Building Haskell programs for the Pi

I decided to build the project on the Raspberry Pi itself. Although setting up a cross-compiler seemed possible and would have been faster, the process seemed finicky and would have taken a lot of time.

stack on the Pi

stack is not yet in Raspbian repositories, but it seems like it’s possible to run on the Pi. However, I noted the current difficulty of building stack for the Pi, and decided to forgo using stack for this project in favor of using plain cabal.

Joy-Con behavior through evdev

The Joy-Con only seems to send the absolute state of the joystick when connected to a non-Switch device through Bluetooth (e.g. Up, Down, Left, Right instead of x: 0.8, y: 0.2). This may just be a driver quirk.

Pi boot time

I was surprised at how much I could chop the Pi boot time down to by disabling services and components (14 seconds on average). A microcontroller like an Arduino would definitely fare better, however.

technical specs

  • Controller: Raspberry Pi Zero W
    • Bluetooth capability
    • Raspbian Linux
  • HID: a Joy-Con (left side) from the Nintendo Switch
  • Motor: KEDA 56-63 Brushless Outrunner
    • 195 kV
  • Batteries: 2x ZIPPY Flightmax 3S1P
    • capacity: 10,000 mAh
    • discharge rate: 20C
  • ESC: red brick (???)
    • 125A continuous
    • 140A burst