Programming ESP8266 using Visual Studio Code with Arduino Extension

So now I have used the official Arduino IDE for some time to program the ESP8266. It is a convenient and quick-to-get-started method (check here). But recently I plan to write an application that I feel it would be uncomfortable to write codes using the limited features of Arduino IDE. I find particularly two feature-rich IDEs out there, which are free and highly recommended by communities, namely Atom and Visual Studio Code. With Atom, we need to add the PlatformIO extension for programming embedded systems, including the ESP8266. While with VS Code, we need to install either PlatformIO or Arduino extension.

I had difficulties to get both Atom-PlatformIO and VS Code-PlatformIO working. Somehow the PlatformIO installation was not able to complete. I suspected it was caused by my office internet proxy. I spent quite some time to solve it but did not succeed, so I abandoned it and tried the Arduino extension.

Getting the VS Code with Arduino extension working was not that straight forward either. If you search for the Arduino extension, you will find two choices, either developed by Microsoft or Steve Yin. Initially I chose the one developed by Microsoft. Well, Arduino extension is just an extension that allows users to tell the VS Code where the tools for compiling and uploading code reside. So we must have the official Arduino IDE installed because its tools for compiling and uploading will be used by the VS Code. Then we need to specify the Arduino IDE path in the VS Code ‘User Settings’. Btw, my OS was Windows 8, and I installed the official Arduino IDE version 1.8.2. For unknown reasons compiling sketch using VS Code was always fail with a message saying ‘[Error] Exit with code=undefined’. Actually, I also had an Ubuntu machine, and I managed to get the Arduino extension working. I could compile and upload codes to the ESP8266. But for some reasons, I still preferred to work on my Windows 8 machine.

So, then I gave the Steve Yin’s Arduino extension a try on my Win 8. The compile and upload options in User Settings were more complicated than those of Microsoft one.  But happily I succeeded to compile and write bits of codes to the ESP8266 flash memory. The easiest way to specify the compile and upload options is by adapting them from the command list spat out from the Arduino IDE console output. Again, you can follow this instruction to program ESP8266 using Arduino IDE.

arduino ide compile - for vs code arduino ext

Here is my VS Code ‘User Settings’:

"arduino.uploader" : "C:\\Users\\User-pc\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\esptool\\0.4.9\\esptool.exe",
"arduino.uploadOptions": "-vv -cd nodemcu -cb 921600 -cp COM12 -ca 0x00000 -cf $TARGET.bin",
"arduino.compileOptions": "-compile -logger=machine -hardware D:/Master/arduino-1.8.2/hardware -hardware C:/Users/User-pc/AppData/Local/Arduino15/packages -tools D:/Master/arduino-1.8.2/tools-builder -tools D:/Master/arduino-1.8.2/hardware/tools/avr -tools C:/Users/User-pc/AppData/Local/Arduino15/packages -built-in-libraries D:/Master/arduino-1.8.2/libraries -libraries C:/Users/User-pc/Documents/Arduino/libraries -fqbn=esp8266:esp8266:nodemcuv2:CpuFrequency=80,UploadSpeed=115200,FlashSize=4M3M -vid-pid=0X2341_0X0043 -ide-version=10802 -warnings=none -prefs=build.warn_data_percentage=75 -verbose",
In the “arduino.compileOptions” I omitted the built-path and built-cache options since they caused compiling to fail. The Arduino extension had its own built-cache which worked fine. I had not looked further for the meaning of the other options. They might be fine to be deleted. However they seems didn’t do any harm, by now I just leave it there.
In the “arduino.uploadOptions” we could set the COM port and upload speed. By default, the upload speed is 115200, which was quite slow. I found it somewhere that says we can increase the speed by a factor of 8, so it becomes 921600. It was indeed much faster. But the reference I read also says that this high speed can sometimes be unstable. So, bear this in mind. I did try other higher baud rates: 1500000, 1843200, 2000000. However the uploading time took longer than that of 921600.
vs code arduino ext compile
Initially I thought installing these tools for programming ESP8266 would be just some clicks away. But in fact I had spent a lot of time to get it done properly. I hope you have a nice and smooth installation. In case you face the same problem, hope my experience would help.
Happy coding!

[Raspberry Pi] Installing piCore 9.0

At this moment, I have played with my Raspberry Pi B for quite some time. Instead of using the standard Raspbian Jessie OS, I am curious about running alternative OS. I am looking for something much simpler than the full featured Raspbian Jessie. The reason I am doing this is because I want to comprehend the internal working of embedded Linux. I aim to understand the detail processes of building the Linux OS, and steps involved from power-on, running user apps, until power-off. I suppose the simpler the system, the easier to learn. Back to the alternative OS, it should be lightweight and fast to boot up. One of the options that I encounter — and looks promising — is piCore. It is the Raspberry Pi porting of TinyCore OS.

Here I describe how I install piCore 9.0 on my Raspberry Pi B. compressed image is downloaded from here. Extract it and you will have a 51.4 MB piCore image. According to the official installation guide the image can be extracted directly on SD Card using dd command on Linux or Win32 Disk Imager on Windows. However, my SD card already contains the Raspbian Jessie (using NOOBS image), and I still want to keep it there. So, I am trying to copy the image contents manually in a way that the Raspbian sits still on my SD Card. Later, I can revert back to the Raspbian Jessie. This workaround will just work because of the booting  mechanisms of NOOBS installation. A nice explanation can be found here.

First, go to the directory containing the image and issue fdisk -l piCore-9.0.img command to list the partitions and its corresponding start sector.

Disk piCore-9.0.img: 49 MiB, 51380224 bytes, 100352 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x0009bf4f

Device          Boot Start    End Sectors Size Id Type
piCore-9.0.img1       8192  77823   69632  34M  c W95 FAT32 (LBA)
piCore-9.0.img2      77824 100351   22528  11M 83 Linux

It can be seen that the unit sector size is 512 bytes, and there are two images. So, create two directories for mounting those two images, let’s say: mkdir picore_1 and picore_2. Then mount the images on the created directories:

sudo mount -o loop,offset=$((512*8192)) piCore-9.0.img ./picore_1
sudo mount -o loop,offset=$((77824*8192)) piCore-9.0.img ./picore_2

picore_1 contains the Linux kernel, Device Tree Blobs, initramfs, and booting parameters. All of them will be copied in the /boot partition on my SD Card. But, before copying, I have created a directory /boot/rpi-boot and moved all the exisiting files in /boot to /boot/rpi-boot. By doing so, I can still use the Raspian OS in the future by moving them back into the parent directory, i.e. /boot.

picore_2 only contains a single tce directory. It is copied to /root partition on my SD Card. Now, the SD Card can be put on the Raspberry Pi, and power-on the board. If everything goes well, piCore will boot into command line mode. To install TC desktop packages, issue: tce-load -wi TC. It will download all necessary packages from the repository. Surely, this assumes that internet access has been provided via LAN connection. After downloading has finished, issue command -b to make all settings persistent. So the settings will be automatically loaded on next boots.Now, we can fire up the desktop mode by issuing startx.

Next time we reboot piCore it will automatically go into desktop mode. The video below shows the piCore booting on my Raspberry Pi B. Note that I have enabled showapps boot parameter in /boot/cmdline.txt so that the loaded modules get printed on the screen. It is surprising to me that the overall booting time is not faster than that of Raspbian OS. It is even slower, I think.

At the time of this writing, available apps ported to piCore are still very limited. The only web browser you can install is Dillo 3. Not much can be explored as an end-user. Previously I am thinking to run Firefox or Chromium to compare the performance when run in Raspbian OS, since piCore is advertised to be fast due to its operation that is fully run in RAM.

I also compare the content of /boot partition of Raspbian Jessie and piCore. I found out that there is no initramfs in the Raspbian Jessie. I suppose it is bundled into the kernel image.

It is worth to mention that for unknown reasons sometimes the extended modules do not get loaded during boot-up. And no information whatsoever is spilled out to notify this situation. It try to change the boot parameter to waitusb=5 for example, to give (indirectly) time for the SD Card to get ready. Although I have not done an exhausted test, but it seems to work. Still, I am not sure whether it is the root of cause.

In the meantime, I am still running buildroot to automate the building process of another Linux (official RPi) for my Raspberry Pi. It does take a long time since all the source codes are downloaded from the repositories and then get compiled. Can’t wait to see the result!

Building Embedded Linux for Use in QEMU

In the last couple of weeks, I had been reading books about building embedded Linux systems: Embedded Linux Primer and Building Embedded Linux Systems. The former is a good start to get familiar with the world of embedded Linux. While I found the latter provides more detailed technical steps to build embedded Linux systems. I have walked through the steps given in the latter book, but it was unsuccessful due to toolchain version incompatibility. Having tried to update the tool versions, I still couldn’t get it built successfully.

After googling for a while, I found this nice tutorial. By following the guide, I managed to build Linux kernel 4.4.0 and rootfs image which was populated using Busybox. They were then run on QEMU emulating Versatile Express Development Board.


The feeling to see the screen above for the first time was priceless.. You know what I mean 🙂

One small note about the tutorial above is that there is a change on the link of Linaro ARM compiler. The link below is that I refer to:

Also, in the steps of building the Busybox, the tutorial missed the install command which should be invoked after compile step (make -j4). So I used this command:

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make install

The above command effectively create and populate a directory called _install, whose contents that will be copied in our root file system.

Image-based closed-loop motor control

This was our final setup for the course Embedded System Laboratory, back then in summer 2013. It was always great to work in group with Prithivi Ram Duraisingam. Basically, the task is to make the red circle on the rotating wheel follow wherever the green mark moves. The problem was solved as follows. First, the movement of the green mark was captured by a webcam, which was controlled by Gumstix Overo Fire, an OMAP3530-based computer-on-module. Streaming of images from the webcam was then processed in order to track the position of the green mark. The Gumstix then told Altera DE0-Nano board to rotate the the smaller wheel, which was coupled with the larger one that has the red circle. To do its job, the Altera DE0-Nano board was programmed to have a CPU core and dedicated FPGA-based PWM controller and quadrature encoder. A digitally implemented PID controller was in charge to move the wheel as fast as possible with minimal overshoot.

It was quite a lot of pressure, considering the little time available and also the approaching of other assignment deadlines.There was an interesting experience during the work, and now that experience still remains in my mind. In the progress of our work, for unknown reasons our setup didn’t work. Debugging for days and night, but we could not find out what’s wrong. The codes and setups — everything looked fine.  But in the end it turned out that there was a very very small mistake that was hard to notice; a ‘1’ was in place of ‘I’. In some font types they looked the same. The feeling of relief after spotting the mistake was indescribable. From then on, we progressed pretty smoothly toward the end.

If you are interested, our final report can be found here.

And this post was on my FB wall after we finished our assignment. 🙂


It was not perfect. Sometimes the red circle went too far. Some tweaking was needed but we had not enough time. At least, the proof of concept had been shown. So we left it there, went home, and slept 🙂