I really enjoy the Elixir Programming Language. I've dabbled in some Phoenix projects both at work and at home. Something I haven't tried yet is embedded programming. There's a lot of hype around Nerves so I decided to check it out. The only problem? I work in Windows, I'm way too cheap to buy a Mac, and I don't want to get a laptop only to brick it by trying to install Linux.
Looking at the official documentation for installing Nerves it states
For Windows users, some people have had success running Linux in a virtual machine or using the Windows Subsystem for Linux available in Windows 10.
Turning to the World Wide Web yielded a few nuggets of information that were invaluable in pointing me to a working path. This article by Michael Schmidt gave some great insight on using Docker or Windows Subsystem for Linux on Windows to develop a Nerves project. I didn't use Docker but I eventually took a stab at WSL (ultimately WSL doesn't get 100% what I wanted). Inside the article there's a link to this YouTube video from Timothy Mecklem I garnered a little more information in my quest to develop a Nerves project on Windows.
Ultimately I was trying to follow this tutorial to get the light on my raspberry pi zero w to turn on or off. Knowing that I wanted to do this in Windows I couldn't follow it exactly.
I decided to try running in a virtual environment so I installed VirtualBox and created an Ubuntu VM. I created a VM with 8 GB of memory, 2 processors, and a disk size of 10 GB. I don't know if there's an "official" recommendation for VM specs but this seemed to work well for me. If I would change anything it might be to create a bigger disk (I'm getting warnings that I'm running out of disk space). Also I don't know if it makes a difference but I installed the Guest Additions.
Next inside the VM I followed the Nerves installation instructions for Linux located on the official documentation. This includes asdf to manage the erlang and elixir versions as well as fwup to enable the firmware creation process.
Following the steps in the other tutorials and videos I've listed I got to the point where it was time to create a firmware image. I tried in vain to find a way to get the Ubuntu VM to communicate with the SD card reader on my Windows host laptop. The interwebs were replete with various recitations of, "This can't be done." I tried various "workarounds" that ended up not working around the issue.
In the end I had to settle for creating the firmware image in the Linux VM and then transferring the file to my host Windows machine. Using the
mix firmware command in Linux builds the firmware file. Use the last line of the output from the firmware command to see where the firmware file was placed. Use the VirtualBox File Manager under Machine > File Manager to move the file easily from the guest (Linux) to the host (Windows).
On the Windows machine I installed fwup using Chocolatey. fwup is the same application used in both Linux and Mac to burn the firmware image to the SD card. After installing fwup it is simple enough to burn the image. (Big thanks to Timothy Mecklem's video here)
- Launch an administrative command prompt so that you have more privileges and can burn the image.
- Navigate to the location where you copied the firmware image file inside of Windows.
fwup <name-of-firmware-file>and it should be able auto discover the SD card inserted in the SD card slot and burn the image.
- If you have problems with auto discovering refer to the fwup documentation.
- Remove the SD card and insert it into the raspberry pi zero w.
I know that Timothy Mecklem's video says he couldn't connect to the nerves device over USB from Windows. In the Nerves documentation it seemed to hint at a way to do this with enabling mDNS addressing. My Google Fu could not find a way to do this in Windows. I blame that on myself and do not claim that there is no way.
I did however come up with my own solution that does work through the Linux VM.
After I plugged in my nerves device to the USB I went to VirtualBox and on the menu selected Devices > USB > Linux CDC Composite Gadget as shown below
Then I was able to ping the nerves device from a shell inside the Linux VM using
ping nerves.local as described in the nerves documentation. After verifying the VM can see the device I ran
ssh nerves.local to connect to the nerves device. After connecting I'm able to turn the LED light on and off on my raspberry pi zero w! 🥳
At some point in setting up the VM and installing asdf, elixir, and erlang and creating the project and trying to burn the image onto the SD card I left the VM and tried using the Windows Subsystem for Linux because of some frustration or other that I can't remember now.
Most of the good stuff here came from Timothy Mecklem's video. He does a great job showing how to get things set up and some of the pitfalls you'll run into. One of the caveats that he points out is that you can't connect to the nerves device over USB on Windows. I can confirm that this did not work for me and after trying to ask Google to find me a Random Guy from the Internet with answers on how to do this I gave up but that led me to...
I tried to connect to the nerves device over WiFi trying to follow the instructions in the nerves documentation for a raspberry pi 3B thinking it would also work for my raspberry pi zero w. I was sorely disappointed. I'm sure I'm doing something wrong but I haven't figured it out yet.
It took me a couple of days to figure out how to do this but it was well worth it for me. I'm excited that I can try out a few new things this way in nerves on a Windows box.
While it's not really developing Nerves projects in Windows itself it doesn't feel too out of place working inside the VM and using Windows solely to burn the image to the SD card.