Posts Tagged ‘how-to’

Getting Started with MicroPython on ESP32 – Hello World, GPIO, and WiFi

October 16th, 2017 10 comments

I’ve been playing with several ESP32 boards over the months, and tried several firmware images. I started with a tutorial for Arduino Core on ESP32, a few month later I tested ESP32 JavaScript programming with Espruino on ESPino32 board, and recently Espressif Systems sent me ESP32 PICO core development board powered by their ESP32-PICO-D4 SiP, and while I took some pretty photos, I had not used it so far.

So I decided to go with yet another firmware, and this time, I played with MicroPython on ESP32, and will report my experience with basic commands, controlling GPIOs, and WiFi in this getting started post.

Flashing Micropython Firmware to ESP32 Board

Source code is available on Github, as a fork of MicroPython repo as ESP32 support has not been upstreamed yet. We could built the firmware from source, but there’s also a pre-built binary which you can download on MicroPython website.

I’ll be using Ubuntu 16.04 for the instructions, which should be pretty similar for other Linux distributions, especially the ones based on Debian, and if you’re using Windows 10, you should be able to follow the same instructions after installing Windows Subsystem for Linux with Ubuntu on your computer.

Let’s open a terminal, to download the firmware (October 14):

If you have not done so already, install the latest version of esptool:

Now connect the board via a micro USB to USB cable to your computer. The log should like like:

In my case, the device is ttyUSB0, but it may vary depending on the board used. We can now erase the flash, and copy the firmware to the board:

If the last step is successfull,  the output should be similar to the one below:

As a side note, version 2.1 of esptool does not know about ESP32-PICO-D4, but it can still detect an ESP32 device, and the update went through normally.

Hello World Sample / Boot Log with MicroPython

We can test the firmware, by connecting to the board using minicom, screen, putty, or whatever software you feel most comfortable with. I went with minicom, setup a connection to /dev/ttyUSB0 device with 115200 bps baudrate. I immediately tested the print function, and made an hard reset to check out the boot log:

The reset command will first generate some errors message, before rebooting the board:

We can type help function to get some more help:

I also often refered to MicroPython 1.9.2 documentation to write this quick start guide.

LED Blink Sample with MicroPython

The easiest way to test GPIOs is to connect an LED, since the board does not have user LED, only the power lED. I connected a 5V LED to pin 21 via a transistor to make the 3.3V to 5V conversion.

Controlling the LED in the command line interface is easy. Import the machine library, set the pin to output, and change the pin level as needed:

Success! But what about doing a proper blink sample? MicroPython developers’ official PyBoard would show as a USB mass storage drive in you computer, where can copy Python files like and files, but in the case of ESP32 PICO core, it appears the only option is to use the serial console for programming, as we can’t simply copy files to the board from the host computer.

I  found a solution on Techtutorialsx – which also has plenty of articles about MicroPython on ESP32/ESP8266. We need ampy script that can be install from our Linux terminal:

However, the first time I tried it I got an error:

I installed files module, but the error remained. So instead I installed it for Python 3:

I then created on my computer to blink the LED every 500 ms:

Before uploading the file to the board, you can try to run it as follow:

If you have plenty of errors here, that’s probably because your code is incorrect. Since I’m not very familiar with Python, it happened to me a couple of times, until I got the code right, and the LED was blinking as expected.

Now that we’ve made sure the code works, we can now copy our sample to the board…

… reconnect to the serial console, and verify the file is there:

To run the program type the following:

The LED should blink again. You can interrupt the program with Ctrl+C, and if you want to soft reset the board, press Ctrl+D.

In order to automatically start the blink program at each boot, rename to, delete, and copy instead:

Power cycle the board, and the LED should start blinking almost immediately.

ESP32 WiFi with MicroPython (Station and AP modes)

We’ve got GPIOs working, but one of the most important feature of ESP32 is obvisouly WiFi. I’ll start by configuring the board in station mode. First import the network library, set the board to station mode, and scan access points:

The latter should return a list of access points with ssid, bssid, channel, RSSI, authmode, and hidden status as explained here.

I can then connect the board to one of the access points with:

The log above with IP address should give  a clue, but you can check connection status with the following function:

and use ifconfig to get the IP info:

Switching to AP mode is easy with the three commands below configuring the board with ESP32-PICO-CNX SSID:

At this stage I can see ESP32-PICO-CNX on my phone, but it’s an open connection. We can change that with authmode option that can take 5 values:

  • 0 – open
  • 1 – WEP
  • 2 – WPA-PSK
  • 3 – WPA2-PSK
  • 4 – WPA/WPA2-PSK

I’ll use WPA2-PSK and define the password with the config function.

Working as planned…

ESP32 Web Server with Micropython

Many ESP32 project will require a web interface for monitoring or configuration. Let’s first setup the board as an access point using the command we’ve used above:

Now create file based on Python code found here that’s supposed to return the status of some GPIO pins in an HTML table:

Copy the file to the board:

Start the serial console again, import/run the python sample we’ve copied, and connect to the board (in my case


It works as expected, but we wrote the HTML code inside the Python file, and you need to handle socket programming by yourself. To further simply the task, some MicroPython web servers such as MicroWebSrv, and Picoweb are available.

MicroWebSrv (Not working yet for me)

I tried to install MicroWebSrv first, but never managed to make it work. I still reproduce the step I followed in case somebody finds out what I did wrong. I got the code, and copied files from the Linux terminal:

We can check the files are where they are supposed to be:

Go into the terminal (aka REPL console) to start a basic example, after setting up a connection:

I could connect to the server, but I would always get 404 error.


So instead I switched to picoweb, adapting the instructions here and there. It’s very easy to install.  First make sure you have a working Internet connection in your board (i.e. set station mode), and install the web server with upip:

That’s the output if everything goes according to plans:

Now let’s go back to the host computer to create an html document, for example index.html:

as well as sample file that will request the HTML page from the board, and return it to the client.

You’ll need to change “” by the IP address of your board.

Let’s copy both files to the board…

… go back to the serial console, connect in station mode, and run the sample:

Type or copy/paste the URL in the last line into a web browser, and you should get the output below.

ESP32 Bluetooth with MicroPython

There’s no Bluetooth support in the official MicroPython documentation, because it’s work in progress, and for the most adventurous MrSulry released an alpha version  a few days ago. The Bluetooth API is also in flux, but the basic code to enable Bluetooth should look like:

I’ll update that section once Bluetooth makes it to the stable release, and/or when I’m sure the API is frozen.

Other ESP32 (Micro)Python Resources

I’ve just covered a few things that can be done with MicroPyhon on ESP32, and beside the official documentation, you can also check the various MicroPython ESP32 tutoral on techtutorialsx blog. Loboris also made another MicroPython ESP32 firmware that supports pSRAM as MicroPython may use a lot of RAM. If you’re interested in Python for ESP32, but Zerynth is another option for Python on ESP32 that works with an IDE/GUI available for Windows, Linux and MAC OS X. [Update: Yet other options are Pumbaa a port of MicroPython running on top of Simba, and Pycom version of MicroPython]

Review of Sonoff B1 Smart RGB Light Bulb – Part 2: Sonoff-Tasmota Firmware

October 5th, 2017 1 comment

I’ve already reviewed Sonoff B1 light bulb using the stock firmware combined eWelink app for Android, and as promised in the first part of the review, I’ve also tested the ESP8285 based WiFi light bulb with Sonoff-Tasmota open source firmware, and report my findings in this new post.

Before we can play with the new firmware, we need to install it, and I’ve just explained how to upgrade Sonoff devices to Sonoff-Tasmota firmware either using some soldering skills and a USB to serial board, or some network configuration skills and perform an OTA update using ITEAD Studio/eWelink original firmware update mechanism.

So for this part of the review, I’ll assume we have just freshly update the light bulb with Sonoff-Tasmota using the binary images released by the developer. First, you’ll need to find the IP address of the light bulb with your router or tools like nmap or arp, and access the web interface in your web browser with for example You’ll probably want to setup a fixed IP address for easier access later on. By default the firmware is set to use Sonoff Basic, but we can go to Configuration->Configure Module, to change that to Sonoff B1, and click Save.

Click to Enlarge

This will reboot the light bulb with Sonoff B1 configuration, and you should be able to turn on the light bulb by adjusting the Color or Brightness sliders, or pressing the Toggle button.

It works with some lag, one or two seconds, just like on the eWelink app. What you don’t get in the current web interface is the ability to adjust RGB values, so only the white lights can be controlled easily. More on RGB control later. You’ll also lose timer and schedule ability from the web interface, because that’s more of a task for your home automation server using either MQTT or Domoticz whose options are available in the Configuration menu as shown below.

Configuration, MQTT, and Domoticz – Click to Enlarge

I won’t explain how to use those in details, as Karl’s has already written a tutorial using MQTT it with his home automation project with Sonoff-Tasmota (aka arendst’s firmware), and one my side, I have published instructions to setup MQTT and Domoticz with ESPurna open source firmware for a Sonoff POW switch.

Click to Enlarge

Other menus in the configuration include reset/backup/restore configuration, logging parameters, and other parameters such as Belkin Wemo or Hue Bridge emulation. If we go back the back to the main menu, we have some more buttons beside Toggle and Configuration such as access to the console, which you can use to monitor the output log, and send various commands, including ones to control the RGB lights. For example, I could set to the light to green with the command “Color 00FF000000”, since for Sonoff B1 they use hexadecimal values for Red, Green, Blue, Warm White, and Cold White. You can also use those commands over serial, MQTT, and a web API. For the latter the command

will set the color to red, and return:

Other options include Information with a complete overview of most parameters…

Click to Enlarge

Firmware Upgrade to do so either from an update server, or a local file, and Restart to reboot the device.

Click to Enlarge

Sonoff B1 with ITEAD Studio’s stock firmware and eWelink app is pretty much plug and play, and you can control multiple lights from one app, configuring the white and RGB lights, and setting timers and schedules, all right from your smartphone. The downsides are that it requires the Internet to communicate with the cloud service, the firmware and app are both fully closed source so you can’t add features or easily integrate it with your home automation system using standard protocols such as MQTT or a REST API. It does integrate with Amazon Alexa or Google Home however.

Going the open source firmware route is more a hack-flash-configure-get confused-setup-learn-and-play solution. Once you have overcome the steps to upgrade firmware to Sonoff-Tasmota, it’s not at all convenient to control your devices from the built-in web interface, especially if you have many. The firmware has really been designed to use with an home automation gateway like Domoticz, where you can manage with your lights or switches from a single web interface. So you’d have to setup your gateway, and you’ll likely get an Android app with it to do something like eWelink app, except you’ll have much more flexibility. You can get a bunch of lights to change colors in sync with your music (likely with a short delay), turn them on when motion and low light conditions are detected, or when specific persons are detected using face detection, etc.. The limit is only your imagination, and willingness to learn new skills.

I’d like to thank ITEAD Studio for sending a review sample. If you are interested, you can purchase the light bulb directly from them for $18 plus shipping. It can also be found on sites like Amazon US or Banggood.

Upgrading Sonoff Stock Firmware to Sonoff-Tasmota – USB to Serial, and OTA Update Methods

October 4th, 2017 7 comments

This post was initially supposed to be part 2 of Sonoff B1 light bulb review, where I would have explained how easy it was to use OTA mechanism to update to Sonoff-Tasmota open source firmware, and shortly show about its features and capabilities. However, it took me over 10 hours to make that work, mostly due to misunderstand in the documentation, and time spent to configure routers. I also failed the first time with Sonoff B1, so I used the serial console method, and instead managed to use SonOTA method with Sonoff POW switching from stock firmware to Sonoff-Tasmota without having to solder or tear down anything.

Updating software with a USB to Serial Board

Using a USB to serial board is the most common method to switch from stock firmware to open source firmware such as ESPurna or Sonoff-Tasmota in Sonoff devices or other ESP8266 based devices. It’s quite straightforward with Sonoff switches like Sonoff TH16.

Click to Enlarge

You just need to solder a 4-pin 2.54mm pitch header, connect the board, and use esptool to flash the image. One it’s done you can simply remove the wire, leave the header in place, and put the case back in place. But with Sonoff B1 light bulb, it’s quite as easy. First there are no through holes in the board, and you need to solder up to 6 wires on small solder pads.

Click to Enlarge

The GND, Tx, Rx, and 3.3V must be soldered and connected to the USB to serial board, while GPIO0 must be shorted to enter programming mode, so I also added two more wires for GPIO0, and an extra GND pin.

Click to Enlarge

Important warning: Never connect the serial board and AC/mains at the same time. Your equipment and life may be at risk.

Now we can download the latest version of the firmware, install esptool, connect the USB to serial board to your computer – which will also provide powered to the board -, and run esptool to flash the firmware:

That’s pretty straightforward, and the output should look as below if everything runs normally:

Most products on the market defaults to access point mode when they are first booted, but Sonoff-Tasmota’s developer have instead decided to provide pre-built image in client mode connecting to a default access point with SSID: indebuurt1 ; password: VnsqrtnrsddbrN. That’s a bit of a pain, as you need to configure another router with those credentials, before changing it to your home router. An alternative way is to build some source, and change the default AP settings, so the device can connect right away after flashing. Still, I’d wish an image that default to AP mode would be nice. It’s actually not a problem for most Sonoff devices, as you can switch to AP mode with the button (4 short presses), but Sonoff B1 does not have one.

Now imagine you have a dozen or more of Sonoff B1 light bulbs that need to be update to Sonoff-Tasmota. That would be a real pain to solder and unsolder the required wires for each bulbs. One solution is to create a jig with pogo pins for firmware update, as the one shown below specifically designed for AI Light. You just need to pop out the bulb, click the jig, flash over serial, remove the jib, refit the bulb, and you’re done.

I don’t know if one exists for Sonoff B1, but the jig above could certainly be customized to work with it.

SonOTA – Sonoff OTA Firmware Update Method

However, in an ideal world you’d prefer not to mess with the hardware at all. If only ITEAD Studio provided a way to upload custom firmware with their stock firmware that’d be ideal, but it’s not the case right now. Luckily, the OTA mechanism was reverse-engineered, and SonOTA is an (experimental) implementation that allow to flash alternative firmware to Sonoff devices without altering the hardware or needing special jigs.

The method on Sonoff-Tasmota wiki does not work on Sonoff B1 because there SSID is not advertised in pairing mode, but somebody in github had managed to update one light bulb using DNS spoofing. Since I used the first method with Sonoff B1, but only partially managed to make it work, I switched to Sonoff POW, and succesfully tested the DNS spoofing method.  Several items are required, so I’ve drawn a diagram showing how those interact.

  1. The Home Router is just the WiFi router you’d normally use to access the Internet
  2. The smartphone with eWelink is requirement to configure WiFI on the Sonoff device, and update it to the latest stock firmware version. It can also be used to easily check access points.
  3. The WiFi laptop runs SonOTA, and will act as ITEAD Studio firmware update server located at (for example,, etc…)
  4. “Temporary” Router with DNS spoofing will make sure redirect to your laptop/computer running SonOTA, so it takes over when Sonoff device tries to update the firmware. It still needs to be connected to the Internet.
  5. Sonoff device – The device we want to update

Potentially, you could combine the router, router with DNS spoofing, and WiFi laptop into one device, if you have a Debian based router, but I still separate all three in my case, since home router does not support DNS spoofing, and I failed to install SonOTA on the temporary router.

The very first step is to pair the Sonoff device with eWelink app, connect it to your home router, and update the firmware to the latest version, in my case 2.0.4.

Click to Enlarge

Now you can configure your temporary router to use DNS spoofing. I did not have any spare router with such feature, so I instead used VS-RK3399 board with Debian, and configured it as a router with hostapd, and isc-dhcp-server using those instructions. This part will heavily depend on your router, and whether you use Debian, or other Linux distributions. For reference, here are some of the main configuration files I used:

  • /etc/hostapd/hostapd.conf

  • /etc/network/interfaces

  • /etc/dhcp/dhcpd.conf

The next step was to configure DNS spoofing. I first went with dnsmasq, and I could successfully confirm it worked with dig, but for whatever reason Sonoff B1/POW would still connect the ITEAD server. Finally I tried with dnsspoof, and it worked OK.  Installation in Debian:

/etc/dnsspoof.conf configuration file to redirect traffic to ITEAD / eWelink update servers to my WiFi laptop:

You can run it as follows:

DNS spoofing took me the most time, as beside restarting service in the router itself, you have to restart the devices connected to it to reflects the changes. I also messed with /etc/hosts file in the router and laptop, but it should not be necessary, as the important is to fool the Sonoff device.

Let’s switch the WiFi laptop configuration. It should work with both Linux and Windows, but mine is running Ubuntu 16.04, so that’s what I used. Let’s create a working directory, get SonOTA code, and install all required libraries and tools.

Now we’re ready for the update. Launch SonOTA script in legacy and no provision modes:

This will first ask you to select the WiFi interface, and enter your SSID and password, and start probing for the Sonoff device:

Delete your Sonoff device in eWelink app, and restart pairing, this time connecting it to your temporary router with DNS spoofing enabled, and shortly after the SonOTA script should start to transfer the image to the device:

Now you should be able to use your smartphone or the laptop to connect to FinalStage access point, start a browser to access You should see the interface below, click on scan for Wifi network, and select the one you want to replace indebuurt1 SSID, in order to connect to your “home router”.

Click to Enlarge

Click on the button Save on the bottom of that page, and after a while you should be able to access Sonoff web interface into your home network

Output log of script for that last step:

Success! Finally… Now you can configure Sonoff-Tasmota to use your actual device – in my case Sonoff POW – instead of Sonoff Basic. I’ll show a bit more about that while testing Sonoff B1 with Sonoff-Tasmota in an upcoming post. Whether you choose between the serial or OTA method will depend on the number of devices you have to update, and/or whether you prefer soldering or messing around with network settings. If you are after maximum efficiency for a large number of Sonoff B1 light bulbs, then a jig with pogo pins should be by far the fastest way to reflash them all.

Checking Out Debian and Linux SDK for VideoStrong VS-RD-RK3399 Board

September 25th, 2017 32 comments

VideoStrong VS-RD-RK3399 (aka VS-RK3399) is a features-packed development board powered by Rockchip RK3399 hexa core core processor which offers an alternative to Firefly-RK3399 board. The company sent me a development kit for evaluation, and I’ve already looked into VS-RD-RK3399 hardware and SDK in the first part of the review. Today, after shortly looking into the pre-installed Android 7.1 OS to make sure the board boots fine, I’ll report my experience with Debian 9, and building it from source.

Click to Enlarge

A Quick Look at Android 7.1

I connected the board to my HDMI TV, added an Ethernet cable, and after powering it, VS-RK3399 promptly booted into Android 7.1 with the following launched.

Click to Enlarge

It just has a few apps pre-installed, and lack Google Play store, but as I’ve seen in the new version of the SDK, a patch for Google Play store is provided, if that’s something you need for your use case.

Click to Enlarge

The version I had pre-installed was built on August 14, 2017 with Android 7.1.2 OS running on top of Linux 4.4.55 kernel.

The storage section shows plenty of space left out of the 29.12GB flash partition, and the NTFS and EXT-4 partitions of my USB drives were mounted properly.

However, Explorer app would keep on reporting all USB partitions were NOT mounted. I had to use my smartphone to transfer the screenshots over Bluetooth. Adb would have been another option. Anyway, the Android version I had on my board was pretty rough, but I can see they’ve released another Android image in VS3399 board’s MEGA folder. I have not tried it, since I’ve spent enough time playing with Android on RK3399 with TV boxes such as Yundoo Y8 and Vorke Z3.

Installing Debian

So instead I went to the aforelinked MEGA folder, and downloaded VS-RD-RK3399-linuxSDK, which not only have the SDK like last month, but also a Debian image.

So I downloaded debia_linux_20170905.rar, and the rar file in linux_update_tools, but the latter actually contains (outdated versions of) Windows based Rockchip’s AndroidTool & DriverAssistant, but since I’m using Ubuntu, I went with upgrade_tool instead just like I did for Rock64 board quick start guide.

We’ll need to enter recovery mode to flash the Debian image. While the board is running keep pressing the recovery button, press the reset button shortly, count to 2 or 3, and release the recovery button. When you connect the USB type C to USB 3.0 cable between the board and your computer, you should see the board in the kernel log (dmesg):

How we can extract the Debian firmware, and flash it with upgrade_tool:

if successful the procedure is successful, the output should like the four lines below:

and the board should have automatically rebooted to Debian 9.

Testing Debian 9 on VS-RK3399 Board

Now that the installation is complete, we can start to play with the Debian on the board. Or can’t we? There’s no menu available at all, and only the Trash icon on the desktop. If I right click I get some more menus…

So I went into Desktop Preferences, enabled some other icons, and change the right click behavior.

Now I can launch some apps such as the terminal emulator and Chromium web browser, but they don’t show on the desktop at all, despite clearly running “somewhere”…

I then noticed I can move the mouse cursor beyond he left side of the HDMI TV, so I’d assumed there must be another display enabled. I tried to connect Dodocool DC30S hub to the USB type C port since it supports DisplayPort, but I get no signal on my other monitor, so the extra display must be connected via eDP or MIPI DSI, and the company sent me neither.

I could see the image is based on Linaro ALIP rootfs, so I connected to the board via SSH, hoping that linaro/linaro username and password would work, and they did:

The image runs Debian 9 with Linux 4.4.55, and we have a 29GB rootfs, and 3877 MB memory in total.

We can get some more details about the CPU with 2 Cortex A72 cores clocked at up to 1.8 GHz, and 4 Cortex A53 cores clocked at up to 1.416 GHz:

The Gigabit Ethernet port and WiFi module are both detected:

I could not find Bluetooth however using “communication”, and the list of buses or bridges only showed USB ports, no PCI(e) interfaces:

lspci did not return anything either.

Build a Debian Image from Source

Since the image is not really usable with LCD display, I won’t perform more tests on Debian firmware, and instead will work with the SDK, trying to build my own image from source. We can extract the Linux SDK we’ve gotten from the MEGA link:

…and follow / adapt the instructions in VS-RK3399 Linux SDK Compile and build (EN).pdf document found in VS-RD software datasheet folder.

The company recommends a build machine running Ubuntu 14.04 / 16.04 64-bit, and I installed some dependencies on my Ubuntu 16.04 computer:

as well as ARM/ARM64 GCC toolchain and other tools and libraries:

We can now build u-boot:

It should only take a few seconds, and we can make sure the build went fine:

Next up is the the Linux kernel:

We have to choose an image to build with the dts file of our choice:

The -edp image is with eDP LCD display, -mipi is for MIPI LCD display, and the -dulelcd must be for both (“dual LCD”). So there’s no option for no LCD at all right now, and I’m not sure why there’s a need for three DTS files for the board, as surely this should be possible to select/configure the LCD outputs are runtime (TBC). But let’s use the MIPI LCD one:

I did not go that well, as the build failed:

I tried with rk3399-videostrong-board-edp.img again, and same error, but I noticed more details by scrolling up:

We can see gsl3673.c file is missing:

So I renamed the c-old file to c, and could complete the build:

Now we can build the complete firmware from source using buildroot:

The build all script will take a long while as it downloads and builds all packages. It took over 2 hours on my machine. I ended with:

It looks OK, except for the script failed to remove one file/directory. Let’s try to create the firmware file:

Sadly that part failed too because of conflicts with a patch:

That failures means the rootfs was not built, and the script is so bad did not stop during mpp build failure, and continued building other libs:

I have not tried to fix the issue, as I don’t know how many other issues are hidden in that big piles of code. VideoStrong should look into and provide an SDK that actually builds.. In case the build works, we should get rootfs.img file that can be flashed with AndroidTool if we follow the instructions in the PDF file.

However, you’ll also be able to flash the files one by one using upgrade_tool in Linux, no need to have a Windows machine for any part of the process.

It’s hard to recommend VS-RD-RK3399 if you are an individual who want a platform for development since software support and documentation are rather poor, but if you are a company that plans to order in quantity, you should have direct support from the company, and you can contact them via Alibaba’s VideoStrong page. If you have a good skills, and are ready to work to solve whatever issues, you can also purchase the board for $168.32 (2GB/16GB) or $213.29 (4GB/32GB) on GearBest where it is sold under the MECOOL brand (Coupon GBCNA will give a 14% discount), or Aliexpress. For reference, Firefly-RK3399 in equivalent memory/storage configuration sells for $179 and $219 on Aliexpress. It’s also listed on Amazon US for $149.99/$199.99.

How to Remove Watermarks & Timestamps from Photos with GIMP

September 12th, 2017 5 comments

Watermarks can be seen on some photographs for copyright reasons, but in some cases even people or companies who clearly don’t own copyrights add watermarks, such as online resellers who add watermarks on top of photos provided by manufacturers, and some camera adds date & time automatically to photos if you’ve used the  settings to enable it. I’ve recently read a blog post on Google Research about making watermarks more effective, as some computer algorithm could remove watermarks automatically. Since I often waste time while searching for watermark-free version of the photo, I decided to check if I could find such program running in Linux. I did not but I found a somewhat old blog post explaining how to use GIMP to perform the task with three different methods:

  1. Crop, if the watermark is on the edges… Easiest method, but for most case this won’t do…
  2. Content-aware filling using resynthetiser plugin. Automatic and easy, but results will depend on source since it will use adjacent pixels around the zone to “heal”.
  3. Manual removal. Works most of the time, but is time consuming

I tried the second method with the instructions provided, but the plugin failed to install. Eventually, I realized installation is even easier today in Ubuntu 16.04:

The last package will install resynthesizer and extra filters. We can now load the photo with watermarks, select the marker mark with the rectangle, ellipse, or free select tools, and apply the filter with Filters->Enhance->Heal selection…

Click to Enlarge

The following window with show up. The context sampling width set the number of pixels outside the selected zone you want to use. You can then select samples from all four edges, left and right sides, or above and below. The option will depend on the image, as for example for a watermark covering the white and black zone of the left sided of the phone, I had to select “Above and below”.

Finally, the Filling order allows to randomize the filter, or use inwards towards center, or outwards from center. You can experiment with options to find the one that works best with your source image. As you can see from the image below, the results are not quite perfect on the images I used, but still better than me using the smudge tool. Results will be better when the watermark is on a homogeneous zone with no sharp lines or large differences in colors.

Before (left) vs After (right)

I also tried with some photos since it’s likely to work better, starting with a scan of an old photo with some rather pale timestamp watermark on the bottom right side on top of water.

I selected two zones before applying “Heal selection” filter, and it worked very well as shown in the watermark free photo below.

I took two photo with a point and shoot camera with timestamp enable for further testing. In the first I make sure the timestamp was on top of tree leaves.

Click for Full Size

I applied the filter with default settings and the results are impressive. Even if you download the full size picture, and zoom in you may not be able to sport the filtered zone that easily.

Click for Full Size

The filter is bound not to work as well on the last photo since the timestamp is placed on top of a mixture of water and plants.

Click for Full Size

And indeed the result is not perfect, but it may not be that noticeable unless your focus on the filtered area.

Click for Full Size


Categories: Graphics, Ubuntu Tags: gimp, how-to

Getting Started with Espruino & JavaScript on ESP32 with ESPino32 Board

September 11th, 2017 No comments

Venus Supply Co., Ltd, better known as ThaiEasyElec, is a company based in Thailand, selling embedded systems and development board, as well as providing development services based in Thailand. The company sent me their latest board called ESPino32 powered by Espressif ESP-WROOM-32 WiFi and Bluetooth module for evaluation. While the board is supported in Arduino-esp32, I’ve already tested Arduino with ESP32-Bit module & ESP32-T board, so after checking out the hardware, I’ll load it with something different: Espruino, a firmware allowing for JavaScript programming over the serial console, or a Web based IDE.

ESPino32 Unboxing and Soldering

The board shipped with four female headers, and I/O stickers.

Click to Enlarge

The board includes ESP-WROOM-32, exposes I/Os through four 10-pin headers, features CP2104 chip for serial to USB debugging via micro USB port, two buttons (reset and program), a user LED connected to IO16, and a jumper to select between regulated power supply (micro USB or Vin), or battery power (Vbat).

Click to Enlarge

If you’re going to integrate your board in a project, you may want to use it asif without header to save on space, but for prototyping and use with a breadboard, we should start by soldering the four female headers. It’s even a little easier than with other headers, since you can simply place the board on top of the headers to do the soldering.

Click to Enlarge

Once we’re done, we can apply the stickers on all four headers, which will make it easier to play with while connecting the jumper cables.

Now we can insert the board into a breadboard, connect an external 5V LED through pin 16, and connect a micro USB cable to a computer to get power and access the board.

Click to Enlarge

A board with female headers has the advantage of providing two usable rows on each side of the board. With male-only you’d lose that extra row, unless you use a narrower board such as  ESP32 Pico Core board.

That’s the output I get when connecting the board to my Linux computer:

Quick Start Guide for Espruino on ESP32

Espruino has a page about ESP32 support that explains what is working:

  • onewire
  • hardware SPI
  • hardware I2C
  • DAC
  • ADC
  • Serial
  • WIFI – as a client and access point

and what is not (yet):

  • Over-The-Air (OTA) firmware updates.
  • Bluetooth and BLE

So we can’t play with Bluetooth, but WiFi and GPIO should work. There are also some instructions in that page which I will follow and adapt (since some are not working/out of date) below.

First we need to download the latest version of Espruino, in my case Espruino 1.94.

Espruino Firmware for various board – Click to Enlarge

The zip file includes firmware for all supported platforms include the company’s own Espruino boards & Puck.js, Micro::bit, OlimeXino, Raspberry Pi, STM32 discovery boards, and more..

For our use, we need to get into espruino_1v94_espruino, where we’ll find 3 binary files (bootloader.bin, espruino_esp32.bin, and partitions_espruino.bin), as well as README_flash.txt that explains how to do the update in Windows with, or in Linux with from the ESP-IDF SDK. I’m running Ubuntu 16.04, so I’ll go with the later, but since most people won’t need to install the ESP-IDF SDK, you can instead get esptool from pip for Python 2.7 or 3.4 or newer:

if you’ve used esptool previously for other esp32/esp8266 board(s) before, you can upgrade esptool with:

In my case, I had installed an older version of esptool (v0.4.6) with apt when I played with NodeMCU board, so I removed it:

Now that we have the latest esptool utility installed, we can flash the image we’ve  just extracted:

It worked the first time. Log of successful installation:

At this point, in theory, you can install Espruino Web IDE chrome extension,  click on the connect icon on the left top corner, select /dev/ttyUSB0 port, and program away.

Click to Enlarge

Espruino Web IDE will also show in Ubuntu 16.04 dash. But in practise, there’s a known issue that the first time you won’t be able to connect through the Web IDE, and indeed I could not.. The work around is to first connect using screen or minicom in a terminal window:

We can then run an hello world sample:

That “=undefined” is a little confusing, but Espruino developers explain that is expected :

This is normal and it indicates the result of the last operation, which in this case is the return value of console.log, which is always undefined.

The next step is to configure a WiFi connection to your access point:

Replace “YOUR_SSID” and “YOUR_SSID_PASSWORD” with the value for your WiFi router. If this is successful, you should  see a message like shortly after:

The line will make sure the WiFi connection is permanent, so the board will reconnect to the router automatically after each reboot.

We can now go back to Espruino Web IDE, click on the Setup icon on the top right corner, go to Communications tab, and input the IP address ( in my case) in the field “Connect over TCP Address“.

Click to Enlarge

You don’t even need to connect the board to your computer at this stage, if you be powered by a battery, or a USB power adapter. If we click on the Connect icon again, we’ll have the option to select TCP/IP:

Click to Enlarge

I wrote a simply LED blink demo in the right part of the window, and clicked on he Upload button (third button in the middle) to upload and start the program:

Click to Enlarge

D16 is connected both the board’s IO16 LED and the LED on the board. IO16 will be turned on when D16 is low, and my LED when D16 is high every half second. I’ve shot a quick demo below.

However, if you reboot or power cycle the board, your program will not automatically start. So if you want the program to be “permanent”, add save command at the end of your code:

The output from the console should look like when you click on Upload button.

I could turn off and on the board, the LED demo resumed automatically without having to upload the code from the IDE.

Note that at this stage, I started to have some strange issues, like failure to connect to the board, and sometimes it would should “module http not found” or “module wiki not found”, as I wrote code for a web server.

It could be you need include the code for a permanent WiFi connection, before running the save command. It was still working sometimes, but I decided to connect through micro USB cable via Espruino Web IDE (it worked at this stage) to carry on with my tests more reliably.

In case you want to use ESPino32 board as small webserver, you can do so by creating a access point, and returning a simple “hello world” with the following code:

I click on Upload button, and I could access web server from Firefox.

The main advantage of Espruino over the Arduino IDE is that it’s much faster to try your code on the target, since there’s no need to compile a binary, upload to the board, and flash to storage during development. Another advantage depends on your skill set, as if you’re a seasoned web developer with a good knowledge of JavaScript, you won’t need to learn C programming used in Arduino IDE.

For other interface (SPI, I2C, ADC…) and more advanced tasks, you may check Espruino ESP32 page, but be forewarned, as the blink and web server samples did not work for me (unknown variable and missing semi-colon) by default. So you may want to read through the API reference in case the samples do not work. The company behind Espruino, Pur3 Ltd, is likely focusing most of the development efforts of their own hardware platforms like Puck.js and Espruino boards, and there’s more activity for those in the forums. So if you are interested in JavaScript on micro-controllers, but don’t want too many issues, ESP32 may not be best platform to learn, but if you like challenges, go ahead! 🙂

I’d like to thank ThaiEasyElec for sending an ESPino32 board sample. The company sells the board locally and globally for respectively 590 THB / ~$16 plus shipping on their website, where you’ll also find some documentation in English and Thai language. If you are based in Thailand, you can get further discount and free shipping if you purchase through LINE app.

Orange Pi 2G IoT Board Can Now Boot Linux from NAND Flash

September 4th, 2017 2 comments

Orange Pi 2G IoT is a $10 development board with a 2G cellular modem that was launched last March. The board is based on RDA Micro RDA8810PL processor designed for cheap Android phones, but Linux support was also promoted, and an RDA8810 Android SDK was released in April. It was the first time RDA8810 was used in a development board, and unsurprisingly it was, and still is, a challenge to use such board, as software support is on-going… So people who purchased the board has troubles with controlling GPIOs, or booting Linux from the SoC’s built-in NAND flash, instead reverting to booting from a micro SD card. Luckily, Orange Pi forum’s user surfero75 worked on the latter, found a solution, and posted instructions in Spanish.

He wrote those instructions leveraging the work done by Aib user, and I summarized the main steps below explaining how install and boot from NAND flash (Warning: This could potentially brick your board if something goes wrong):

  1. Get opi2g-utils tools
  2. Set the boot selection to NAND flash/ Android boot, and put the board in USB-OTG mode with the switches set as follows: 1-4 ON and 5-8 OFF
  3. Use serves to extract the files from Android NAND package in case you want to restore Android?
  4. Build u-boot with OrangePiIoT2GBuildSystem utility
  5. Flash the resulting u-boot.rda file to the board:
  6. If you boot Linux from a micro SD card, it should now find the NAND flash:
  7. Edit boot.cmd file to force boot from NAND flash:
  8. Compile the boot.cmd to create boot.scr binary to copy to the root of the micro SD card:
  9. Prepare, format, and mount the NAND flash
  10. There should be an extra step to copy the bootloader and rootfs content, but this step is not detailed in the blog post. I may have missed something…

Anyway, you can also ask question on Orange Pi Forum or on his blog post, if you have question. The video below shows Orange Pi 2G IoT booting DietPi from the NAND flash.

[Update: Surfero75 has now provided an image to try it out without having to go through all instructions above]

Save Power, Hibernate Your Embedded Linux System

August 30th, 2017 4 comments

This is a guest post by Tharma Rajan G, Project Lead, e-con Sytems.

What is the best way to save power consumption of your embedded Linux system? Is there any way to save max power and resume operation ? Yes. It is ‘hibernate’ mode, one of the Power Modes in Linux. This article talks about how we utilized this ‘hibernate mode’ in our Reference Platform Kit Meissa-I with eSOMiMX6-micro SOM.

Click to Enlarge

Meissa-I is a dual board solution that features eSOMiMX6-micro Computer on Module & carrier board. Meissa-I development board runs Linux and Android Marshmallow (under development). eSOMiMX6-micro is based on Dual/Quad core ARM CortexTM-A9 based CPU @ 800MHz/Core. It has 1GB LPDDR2 and 4GB eMMC FLASH (expandable upto 32GB). The eSOMiMX6-micro module also has the Wireless LAN and Bluetooth module.

Linux Power Modes

Power Management is a key feature in embedded Linux system and there are two types for implementing the power management on x86 platforms:

  1. Advanced Power Management (APM)
  2. Advanced Configuration and Power Interface (ACPI)

ACPI is the newer of the two technologies and puts power management in the hands of the operating system, allowing for more intelligent power management than is possible with BIOS controlled APM.

For ARM based systems however, APM/ACPI is not used. Instead power management in ARM Linux System, is implemented using sysfs entries. Following are sysfs entries for power management.

SI.No Sysfs Entry Purpose Notes
1 /sys/power/state
  1. To get supported system sleep states
  2. To set one of the supported system sleep states
Comparing to ACPI, this entry handles System Sleep States (Sx)
2 /sys/devices/system/cpu/cpu0/cpufreq/
  1. To get supported cpufreq governors and current governor for DVFS
  2. To set one of the supported cpufreq governors as current governor
Comparing to ACPI, this entry handles Processor low-power states (Px)
3 /sys/devices/system/cpu/cpuN/online
  1. To check whether CPUN is turned on in SMP (or multi core) system. Here N is not 0 (i.e boot core)
  2. To turn CPUN on/off in SMP (or multi core) system. Here N is not 0 (i.e boot core)
Comparing to ACPI, this entry handles CPU states (Cx)
4 /sys/devices/…/power/wakeup
  1. To set this device as wake up source for waking up the system from one of sleep states.
  2. To check whether this device is wakeup source or not
A wake up source device can not be put in low power states. Other non wake up source devices can be in low-power states.For example,

  1. Debug Serial port as wake up source

2. Ethernet LAN receive data as wake up source

3. RTC alarm as wake up source

5 /sys/class/thermal/thermal_zone0/temp 1. To get the CPU temperature current CPU temp in milli-celcius.
6 /sys/class/thermal/thermal_zone0/trip_point_1_temp 1. To get critical temperature value2. To set critical temperature value when the measured on die temperature exceeds the critical threshold → reboot the system (protection mechanism to prevent damage).
7 /sys/class/thermal/thermal_zone0/trip_point_0_temp 1. To get passive temperature value2. To set passive temperature value The passive trip point is a preventative measure before reaching critical that does things to lower temperature such as reducing cpu/gpu frequencies. The thermal driver works with CPU Freq mechanism

The power management subsystem provides a unified sysfs interface to userspace, regardless of what architecture or platform one is running. Generally sysfs filesystem is mounted in /sys directory and one can see that power management related entries in /sys/power path.

Using the entry /sys/power/state, one can get supported power states (or power modes) of the embedded system. And also one can put that embedded system in one of those supported power states.

System Sleeping States and Description




Alternative name



Will freeze user space process and put all I/O Devices into low-power state.

Make the processors to spend more time in idle state.




Addition to freeze power mode features , nonboot cpus are put into offline and all low-level system functions are suspended during transition into this state.

None of the operating state is lost ( i.e the cpu retains power ), so the system easily starts up again where it left off.

Power-On Suspend



Offer more power savings as everything in the system is put into low power state except RAM, and RAM will be working in self refresh mode to retains its contents.

This mode also supports standby power mode.

Suspend-to-RAM or STR



Take a snapshot of current system state and save it into a disk ( i.e swap space ) . While resuming , snapshot image is read and memory is restored to its pre-suspend state.

STD will put the system to the lowest power state.

Suspend-to-Disk or STD or Hibernate

Swap Memory for Hibernate Power Mode

Swap memory

Swap memory is the area on disk that is reserved to be used as extra RAM when your system needs more RAM than what is available. When your embedded Linux system runs out of free memory, then kernel can move some of the inactive pages into swap partition to make free room for active pages in RAM memory. If you plan to use hibernation in your embedded Linux systems, then you swap space have to be at least twice the RAM capacity.

Kernel support for swap memory

Enable swap support in Linux kernel

Click to Enlarge

Test swap memory

  1. To test swap memory, we created a simple test application test_swap_mem which will allocate memory infinitely using malloc() API and fill that allocated memory using memset() API. Let’s have a look at the source code
  2. Before creating swap space, Check whether swap space is enabled using free command
    Here swap total , used and free space is marked as 0 which means swap space in not enabled yet.
  3. Run test_swap_mem application as discussed below

    Let us wait till the application reaches OOM.

    Click to Enlarge

    From the above image, you can observe test_swap_mem allocates maximum of 799MB, after that it reaches OOM and also you can confirm swap space is not used by observing Free swap and Total swap is marked as 0 kB and no swap pages are used

  4. Now let we create a swap memory region and test with the same application. Once you decided about the partition block to be used as swap space , you have to mark that partition block as swap partition.
  5. After marking that specific partition as swap partition , you have to prepare it using mkswap tool
  6. Now your swap space is ready to use , then activate swap partition.
  7. First notice how much swap memory is available and then run test_swap_mem application.
    Here 892892 bytes of swap memory region is available. Try to explore how much swap space is used and when OOM will be reached.

    Click to Enlarge

    Yes , swap memory is utilized. As there is no free memory (including swap) available for allocation, kernel throws OOM error hence kills that test application.

Hibernate – Power Mode

Hibernation power mode saves the system state (i.e all the pages created in RAM memory) to swap space and put the system power down.When the system is powered on, the state is restored (i.e pages are moved from swap to RAM memory). To write the system state to swap space, a mechanism called ‘swsusp’ (Swap Suspend ) is used.

Kernel Configuration for Hibernate mode

Click to Enlarge

Now we will prepare the Swap Space to hold the Hibernation Image.

Setup the swap area,

Enable partition for swapping

Run a process, to verify restoring the hibernation image.

Entering into Hibernate

  1. Enter into hibernation state by executing below command.

Resume from Hibernate

Before starting to resume from hibernate state, append resume=/pathto/swapspace command line parameter to read back hibernate image from that specific swap partition. Let us change the bootargs for hibernate resume state , and run the bootcmd.

Click to Enlarge

Now you will observe, hibernate image is read from swap partition and resumed.

Click to Enlarge


Power Measurement Analysis

The power data is obtained by computing the product of voltage and current measured.