A cross-platform command-line loader for WifiMCU

Detail photo of the WifiMCU board

I wrote this article as an introduction to the WifiMCU chip and to explain some of the troubleshooting thought process. If you want to get right to the code, jump to the finished product

A little background

I came across the WifiMCU in my latest binge on inexpensive eBay electronics. Following my recent obsession with Arduino’s I wanted to find something wifi enabled but all of the Arduino “sheilds” I found were just too expensive for just playing around. For example the CC3000. Nothing against Adafruit, I love their store, I’m just really cheap.

Soon enough my searching turned up the “new” EM3165 module. These are cheap. The bare module along retails around $8.00. Granted this is a system on a chip (SoC) with a “self hosted wifi library” - you get a lot built in - but it is still pretty far out of my abilities.

…Then i found the WifiMCU…

The WifiMCU is a $13.00 development board based on the EM3165 chip. What you get with this is essentially a platform with all of the power of the EM3165 chip that you can command program over a usb connector. The other fun bonus is that you get a lot of gpio pins on this so instead of using this as a peripheral to your arduino, it can actually do a lot of th hardware controlling. The guys at WifiMCU have done a lot of hard work to make this happen.

So with little hesitation I ordered the WifiMCU module.

This is not an Arduino

So just to be clear this is “arduino-like” in the fact that it is a chip on a board with pins that you can control. You can read inputs and send outputs but this is not programmed like an Arduino.

The WifiMCU is loaded with Lua, a wholly different and much simpler language. This project is still in the beginning stages but you can see they’ve built up a really impressive list of commands already.

Here is the other difference. With an arduino you upload your compiled executable through the Arduino studio (or other software) to be run exclusively when the arduino reboots. The WifiMCU isn’t like that. You don’t “reprogram” it, you run scripts on it. As a result it’s “main program” is always the Lua script interpreter. The way you get it to “run something on boot” is by naming your file init.lua.

So cool, just write up my script and upload it over the serial (USB) interface…


Currently, the only way to “upload’ a file is with the WifiMCU Studio which is a Windows only app. I’ve only got a Mac.

This chip is too cool to just chuck in the bin, so I’m going to work around this.

So how does it work?

After a back and forth with the developers, I found that the way they “upload” files in the WifiMCU Studio is simply to use the native lua commands on the chip to open the file and write it to memory. What this means is that whenever you want to upload or download a file from the chip you are essentially “typing in” the code when you save it and echoing out the text when you want to save it.

You can use a serial tool conneting to wifimcu at 115200,n,8,1 then type the above 3 commands indivaully. The 3 lines comands will create a file named “test.lua”, and the file will be stored in the embeded flash inside wifimcu. This is the uploading procedure. WiFiMCU STUDIO does the same thing. I hope this may help you!

file.writeline("print('hello world1')");

Hacking the code

Day One

I got the initial email from the vendor. I decided I really want to keep this as basic as possible so my initial set of commands will be “get”, “put”, “delete” and “list” - the very basics needed to manipulate files. I’m going to focus on making a very solid and minimal client and then potentially build on that if needed.

While I don’t want to get too elaborate I do want to “engineer” this a little. I’m deciding to use Go for the programming language, the main factor here is that i can make cross platform executables without a very complicated build environment.

I found the tarm/serial library which sounds like it should be pretty portable to Windows, Mac, Linux, etc. so this is where I’ll start.

I will probably use spf13/cobra for the cli since I’ve had really good luck with this in the past

Day Two

Spent a few minutes gathering my thoughts and writing up the previous material. I think I have a good enough mental model built up to start coding soon.

Day Three

Having some difficulties with serial connectivity on my Mac so i setup a dev environment in Linux under Virtual Box

Started working on the code. Got the project folder setup and I’m testing the example code from tamr/serial. I had to make a few changes but the initial serial communications back and forth is working. It’s all downhill from here

Here is the testing code

package main

import "github.com/tarm/serial"
import "log"

func main() {
	c := &serial.Config{Name: "/dev/ttyUSB0", Baud: 115200}
	s, err := serial.OpenPort(c)
	if err != nil {

	_, err = s.Write([]byte("print(mcu.info())\n"))
	if err != nil {

	buf := make([]byte, 128)
	r, err := s.Read(buf)
	if err != nil {
	log.Printf("%#v", string(buf[:r]))

	buf = make([]byte, 128)
	r, err = s.Read(buf)
	if err != nil {
	log.Printf("%#v", string(buf[:r]))

Day Four

Now that the basic concept has been proven, i spent a little time building up some low level functions. First i built read and write functions to avoid future code duplication

func readSerial(p serial.Port) string {
	buf := make([]byte, 1024)
	r, err := p.Read(buf)
	if err != nil {
		 log.Printf("Can't read from serial port\n")
	return strings.TrimSpace(string(buf[:r]))

func writeSerial(p serial.Port, s string) (err error){
	_, err = p.Write([]byte(s + "\n"))
	if err != nil {
		log.Printf("Can't send command\n")
	return err

Next, using these primitives I built up a “command” routine to send a command and retrieve it’s result. Currently, we aren’t trapping for errors but this will be done in the future.

func sendCommand(p serial.Port, cmd string) (out string, err error) {
	err = writeSerial(p, cmd)
	_ = readSerial(p)
	out = readSerial(p)
	return out, err

From here, things build up quick. I was able to put together a higher level command to upload a file. This isn’t quite working yet so i need to do some debugging

func uploadFile(p serial.Port, filename string) (err error) {
	log.Printf("Uploading file: %s\n", filename)
	_, destFileName := filepath.Split(filename)
	log.Printf("Destination name: %s\n", destFileName)

	file, err := os.Open(filename)
	if err != nil {
	defer file.Close()
	log.Printf("Writing file...\n")
	_, _ = sendCommand(p, fmt.Sprintf("file.open('%s', 'w+')", destFileName))
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		//_, _ = sendCommand(p, fmt.Sprintf("file.write(\"%s\")", scanner.Text()))
		fmt.Sprintf("file.write(\"%s\")", scanner.Text())

	if err := scanner.Err(); err != nil {

	_, _ = sendCommand(p, "file.close()")

	return err

Day Five

So the code is getting to the point where we need a little structure so we’ll pull in spf13/cobra and rough in our UI. This will help to keep our code clean

Here is a quick example of the relevant parts. I built out skeleton’s for the commands that we’ll fill in as we go

func main() {
	var rootCmd = &cobra.Command{}
var cmdVersion = &cobra.Command{
	Use: "version",
	Short: "Get the current version",
	Run: func(cmd *cobra.Command, args []string) {
		s := openSerial()
		res, err := sendCommand(*s, "print(mcu.ver())")
		if err != nil {
			log.Printf("Comm error")
		log.Printf("Result: %s", res)

Day Six

Spent a lot of time working on the serial read/writing code. The way the serial prompt was designed it was really made for interactive use. I’m trying a few different ways to “flush” the serial line so that when I issue a command i get only the results. Right now I’m sometimes getting the command results and sometimes getting an echo of the command itself. I’ll need a little more work on this…

I think i finally got it working so now I’m wrapping up the command “interface”. The last piece of the puzzle is adding some configuration around the serial port, update the readme, cross compile and release an alpha version.

Final command set

  • ls - list files on the device
  • rm [filename] - remove a file
  • ver - get the device version
  • put [filename] - send a file to the device
  • config - show the current app configuration
  • version - the version of this app

Configuring the serial port

For configuration I’m using spf13/viper. It’s a little overkill for just the one configuration option (WMC_SERIAL) but it will allow for easy expansion in the future


For the newest versions of Go cross-compiling is a snap. Simply set the GOOS and GOARCH environment variables and Go takes care of the rest. Unfortunately, the underlying tamr/serial code doesn’t appear to support all platforms, so we are a bit limited. It’s opensource, however so we can always contribute changes in the future

The finished product

Okay big disclaimer here, at this point the code has had maybe fifteen minutes of testing. This is not a robust code library at this point, just a quick hack. Use at your own risk. If you do discover a bug please report them to the “issues” page on github. Pull requests are welcome!

My method of organizing email

0-Action, 1-Hold, 2-Archive, 3-Feedback, 4-Awesome, 5-Templates

Lately my posts have slowed down tremendously with moving halfway across the country, starting a new job (twice) and getting married.  Rather than continually put off larger posts because I don’t have enough material built up, I’m going to try to post shorter tips and tricks in between to keep up the momentum.

Today I wanted to share a quick email organization tip that I’ve refined over the years.  Ideally, I try to pull every piece of relevant information out of email as often as possible and stick it into Evernote or an org-mode notes file. Getting information out of email and into an information system of some sort gets you 90% of the way, but there will always be that bit of info you missed in the flood of new emails.  To deal with this I follow the process below to increase my ability to find the information I need.

  1. The first order of business is to get information out of email. Email is a great tool for communication but it was never intended to be an information repository. Search will almost always be cumbersome and even if you find the email you were looking for it can take a great deal of cognitive effort to reconstruct what the train of thought was or way that email was important.  Email generally doesn’t allow for meta-data so by capturing and “editorializing” the information in your own note-taking system you can add in the relevant context

  2. Practice Inbox Zero.  There are really only three “states” that email should live in.  By practicing the art of quickly classifying emails in these categories you can quickly “deal with” large volumes of email rather than letting it build up:

1. "New" - email that you haven't seen yet

2. "Actions" - something you need to do

3. "Archive" - something you need to hang on to
  1. Here is my modified version of “Inbox Zero” with the different folders I have found fit my work-style feel free to improve on this.
1. 0-Action - Emails that are requests or reminders of things i need to do.  If there is a specific task/deadline I will generally remove this to my "official" todo list in a different application and archive the email.  Generally what is in here are reminders or items I need to do _sometime._

2. 1-Hold - Informational emails that i need close at hand but do not represent a "todo" item.  This should be a temporary holding place for "favorites".  An example was a code that I needed for access to a system.  I knew I'd only need it for a short amount of time so I moved the email there and then moved it to 2-Archive after a week.

3. 2-Archive - This is where you put _everything_ that isn't in another folder.  Storage is cheap.  Save Everything.  Rely on good search abilities in your mail client to retrieve anything that you haven't deemed important enough to add to your notes.  If you spend more than three minutes searching for something _add it to your note-taking system_ for the future.

4. 3-Feedback - This is where I keep positive (and negative) feedback to refer back to periodically.

5. 4-Awesome - Funny emails, pick-me-ups, etc.  It's good to make time during the day to stop being so serious and enjoying work

6. 5-Templates - If i write the same email or answer the same question more than once I create a blank email and use it as a template

What organization systems do you use to keep the flood of email/information manageable? Please let me know!

A Dashboard for your Life - a minimal goal tracker using org-mode, go and git

One of the most powerful motivators to keep on track with goals and to keep from getting discouraged is the humble progress bar.  This is a simple and intuitive indicator of progress used in many day to day situations.  Though lack of accuracy can be a downside, the advantage is that it can be intuited at a glace - making it easy to get an overview of a situation by a brief glance.

When I set out to design a dashboard for my personal life I had a few goals from the outset.  First of all I don’t want to reinvent the wheel, I already have a perfectly good todo-list/organizer with Emacs org-mode.  It suits me well to be able to edit a simple text file anywhere I have Emacs installed and sync up with git. The fact that it isn’t 100% ubiquitous on every platform, to me, is a feature.  I normally use scratch paper, emails, etc. as a buffer and then later in the day store and organize these in org-mode.  I find that many of my musings end up being not as critical to actually do as I originally felt.  I like that lag so I can have a bit of perspective when planning my tasks and projects.

The second objective was “no effort”, clearly I didn’t want to reinvent the wheel but also I didn’t want this to feel like a process or something extra I need to do.  If my org-mode notes are the “model”, I want this to just be the “view”.

Getting Started with Org-Mode

Org-Mode is an “add on” to Emacs that is specifically tuned to organizing your life.  I’m not going to go into advanced detail on this since there are already some great tutorials out there.  I’d encourage you to check out the following links first to get yourself familiar with the software

Once your warmed up to org-mode, it’s time to move on…

Tracking your goals

Now that you are comfortable with some of the possibilities of org-mode we are going to extend things a bit and create our own “system” within org-mode to track our goals.  The power of org-mode (and Emacs itself) is the key philosophy that “everything is text”. Building off of this simple idea we can use a few consistent rules of our own to build up a format that we can parse with an external tool further down the road.  This will allow us to “scrape” the notes we are keeping in Emacs/org-mode and create a html dashboard.  Even though I use Emacs constantly every day, I’ve found it very helpful to have a web accessible quick view of where i’m at with all of my goals - keeping an eye on the bigger picture.

Org-Mode formatting “rules”


”* Long Term” - This is one of the ‘categories’ i am using to track multiple goals/projects you can adjust the code and wording as needed

”* Epic Goals” - This is one of the ‘categories’ i am using to track multiple goals/projects you can adjust the code and wording as needed

”* Study Goals” - This is one of the ‘categories’ i am using to track multiple goals/projects you can adjust the code and wording as needed

Regular Todos

** + % = percent complete

** DONE = completed task (note that we are using “**”.  In org-mode this is a sub-heading, this allows us to group multiple “todos” in a single category)

  • = completed task

** TODO = unfinished task  (note that we are using “**”.  In org-mode this is a sub-heading, this allows us to group multiple “todos” in a single category)

  • = unfinished task

Sample Organizer

To help put all of these rules in context, here is a sample of what your org file might look like

* Epic Goals [0/2]
** TODO build a 3d printer
** TODO Run in a marathon [12%]
- [X] 1 k
- [ ] 3 k
- [ ] 5 k
- [ ] 10 k
- [ ] 15 k
- [ ] 20 k
- [ ] 30 k
- [ ] 42 k
* Long Term Goals [1/2]
** DONE Wedding [100%]
  - State "DONE" from "IN PROGRESS" [2014-04-02 Wed 09:42]
- [X] date 26th
- [X] proposal
- [X] rings
- [X] decide where to do ceremony
- [X] invites
** TODO Hobbies - Reading - one book per month 2014 [58%]
- [X] Jan - Tampa
- [X] Feb - map head
- [X] Mar david and goliath
- [X] Apr - fail
- [X] May - fail
- [X] June - american gods
- [X] July - Stuff Matters: Exploring the Marvelous Materials That Shape.. Mark Miodownik
- [ ] Aug
- [ ] Sept
- [ ] Oct
- [ ] Nov
- [ ] Dec

Processing our goals file

Now that we have our file created and have some goals entered we need some way to “scrape” that file.  I’ve created a mini parser called “GoalTracker” that is written in Go. The code is free to use and very easy to get started with ( https://github.com/zpeters/GoalTracker ).  Simply clone from github.  Next install the Go programming language ( http://golang.org/doc/install ).  To compile the code just type “go build goals.go”, this will result in a binary for whatever OS you are using.  Once the binary is created you can issue the following command “goals -dataPath=/my/path/to/my/org-mode-files/ -templatePath=/path/to/the/template/file/included/with/the/code > /var/www/html/goals.html”.  Looking in the code you will see that by default it is looking for a file called “TODO.org” in your dataPath and a file called “Template” in your templatePath.

The resulting html file looks something like this:


Automating Dashboard Updates

Finally, we can automate the update of our dashboard with a simple git-hook.  This allows you to run the dashboard update code in the background every time you commit your updated org-mode files.  The following code should be placed in your _post-receive _file

rm -rf /tmp/Organizer
cd /tmp
git clone /storage/GIT-REPO/Organizer.git
/home/zach/src/go/bin/go run /home/zach/Projects/Goals/goals.go -dataPath=/tmp/Organizer/Organizer/ -templatePath=/home/zach/Projects/Goals/Template > /var/www/html/goals.htm

This is one of my more popular articles. If you have any suggestions for updates or new articles like this please don’t hesitate to leave a comment below, or email me directly at [email protected]