Archive

Posts Tagged ‘tutorial’

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 boot.py and main.py 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 blink.py 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 blink.py to main.py, delete blink.py, and copy main.py 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 webserver.py 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 http://192.168.4.1):

 

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.

PicoWeb

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 picowebtest.py sample file that will request the HTML page from the board, and return it to the client.

You’ll need to change “192.168.0.108” 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]

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 xx-disp.coolkit.cc (for example cn-disp.coolkit.cc, eu-disp.coolkit.cc, etc…)
  4. “Temporary” Router with DNS spoofing will make sure xx-disp.coolkit.cc 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 http://192.168.4.2. 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 SonOTA.py 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.

Designing a 3D Printed Jig to Flash Firmware to ESP8266 based Light Bulbs

September 18th, 2017 6 comments

Karl here. I have to say that my favorite part of 3D printing is designing things from scratch. Recently a reader was asking about a way to flash a lot of Ai Lights on a project he was working on. I suggested 3D printing a jig that pressure fits pins. He didn’t have a printer, and we exchanged contact information and he sent me one of the lights and some pogo pins from Amazon.

Click to Enlarge

Design in Fusion 360

I started by taking a picture of the light to get my pin placement. I set a scale by measuring a known distance then printed and tested. It took about 3 iterations to get them to line up in real life. Keep in mind camera lenses distort reality and knew It would take a couple times. I would just let a few layers print then stop and line everything up. I had a mostly working prototype in a couple hours. I did have to go back and add an additional pin after I found out that 100 needed to be grounded when powering up so took a couple more tries to line that pin up. The first couple times pressing into place it is very snug. After 3 or 4 times it becomes easier to remove.

Click to Enlarge

Click to Enlarge

Click to Enlarge

First Iteration

Building the Jig

I built this thing too many times, but I finally settled a reproducible method. First print at least 2 copies of the jig. Insert pins in jig then place on 2ng jig with pins up. 2nd jig is only for alignment and to keep straight. Once aligned super glue the pins to the jig and let dry. Do not get glue inside the pins or they will get stuck. When I was first putting this together I was doing it the other way, and glue kept on seeping down to the pins and making them stick. This method of gluing worked the first time.

After gluing solder on your leads, use some shrink tube, and make sure to connect pin 100 to the ground. I thought it needed to be temporary, but I forgot to disconnect one flash. I test flashed the light about a dozen time with 100% success.

The method I used to connect is with the leads connected to PC, I press the jig in place slightly offset clockwise a couple degrees. Press in, then turn counter clockwise until you hear a click. When it clicks into the pads and PC dings it is ready to flash.

This was a fun little project and if you would like to print it you can find it here.

Click to Enlarge

 

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 flash_download_tools_v3.4.4.zip, or in Linux with esptool.py 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 wifi.save() 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 (192.168.0.112 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: 192.168.0.112.

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.

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

Sl.No

Label

Description

Alternative name

1

freeze

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.

Suspend-To-Idle

2

standby

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

3

mem

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

4

disk

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

Analysis

Power Measurement Analysis

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

Hardware and Software Used:

  1. The software version used for the measurement is
    • U-Boot 2016.03
    • Linux Kernel Version 4.1.15.
    • Yocto Krogoth X11 image.
  2. The board used for the measurement is Meissa-I with eSOMiMX6-micro SOM.
  3. The measurements were performed using Fluke 15B+ Digital Multimeter.

Power Consumption details in tested power modes.

Sl.No

Power Mode

Current

(mA)

Voltage

(V)

Power Consumption

(mW)

Description

1

Active

288

3.3

950

In active state, no peripheral is connected with the MEISSA development board except HDMI monitor , MicroSD card and a debug cable which is connected to the development system.

2

Standby

55

3.3

181.5

In standby mode, all the peripherals will be put into sleep state. ARM core and DDR will be active.

3

Suspend

10

3.3

33

In suspend state, all the peripherals along with ARM core will be put into sleep state. DDR will be put into self refreshing mode.

4

Hibernate

0

3.3

0

In hibernate mode , entire system will be put into low power state.

System Power Consumption Chart

Click to Enlarge

Active Mode Power Consumption

Power Domain

Voltage ( V )

Current Consumption (mA)

Power Calculated (mW)

VCC_SW1AB_CORE

1.3

29

37.7

VCC_SW1C_SOC

1.3

262

340.6

VCC_HIGH_IN

3.1

73

226.3

VCC_LDO5

2.4

10

24

VCC_SW3_LPDDR2

1.1

43

47.3

VCC_LDO4_1P8

1.8

1.96

3.52

VCC_SW_3P3

3.3

24

79.2

VCC_1P2

1.1

62

68.2

VCC_1P8

1.8

0.55

0.99

VCC_WIFI_VBAT

3.3

0

0

Total Power

827.81

Standby Mode Power Consumption:

Power Domain

Voltage ( V )

Current Consumption (mA)

Power Calculated ( mW )

VCC_SW1AB_CORE

1.3

13

16.9

VCC_SW1C_SOC

1.3

11

14.3

VCC_HIGH_IN

3.1

34

105.4

VCC_LDO5

2.4

0.27

0.648

VCC_SW3_LPDDR2

1.1

7

7.7

VCC_LDO4_1P8

1.8

0.38

0.684

VCC_SW_3P3

3.3

0

0

VCC_1P2

1.1

0

0

VCC_1P8

1.8

0.24

0.432

VCC_WIFI_VBAT

3.3

0

0

Total Power

146.064

Suspend Mode Power Consumption:

Power Domain

Voltage ( V )

Current Consumption (mA)

Power Calculated ( mW )

VCC_SW1AB_CORE

0.97

0

0

VCC_SW1C_SOC

0.97

3

2.91

VCC_HIGH_IN

2.9

1.64

4.756

VCC_LDO5

2.4

1

2.4

VCC_SW3_LPDDR2

1.1

6

6.6

VCC_LDO4_1P8

1.8

0.37

0.66

VCC_SW_3P3

3.3

1.32

4.35

VCC_1P2

1.1

0

0

VCC_1P8

1.8

0.85

1.53

VCC_WIFI_VBAT

3.3

0

0

Total Power

23.206

Hibernate mode Power Consumption:

Power Domain

Voltage ( V )

Current Consumption (mA)

Power Calculated ( mW )

VCC_SW1AB_CORE

0

0

0

VCC_SW1C_SOC

0

0

0

VCC_HIGH_IN

0

0

0

VCC_LDO5

0

0

0

VCC_SW3_LPDDR2

0

0

0

VCC_LDO4_1P8

0

0

0

VCC_SW_3P3

0

0

0

VCC_1P2

0

0

0

VCC_1P8

0

0

0

VCC_WIFI_VBAT

0

0

0

Total Power

0

Domain Power Consumption Chart :

Click to Enlarge

Boot Time Analysis

App launch time Measurement in Normal Boot.

We have taken our eSOMiMX6Micro SOM as reference, it takes nearly 19 secs to execute watch command which is part of rc.local script file.

Click to Enlarge

App launch time measurement in Resume Mode.

While resuming from hibernate, it takes 16.76 secs to retain and execute the same watch command process state.

Click to Enlarge

Normal Boot and Hibernation Resume Comparison Chart.

Conclusion

From the above analysis on ‘hibernate mode’, we find it to be the best choice for putting the system in low power state. Also, it consumes minimal time for ‘hibernate resuming’ as compared to normal booting time. The only downside we observed is that, manual interaction was required to resume the device from hibernate mode.
I believe, this hibernate power mode analysis will be very useful to you. We will see you next time with another interesting article.

Installing Let’s Encrypt Free SSL/TLS Certificate in 2 Minutes with Certbot, Spending Hours Making it Work with Cloudflare

August 22nd, 2017 29 comments

I’ve been using an SSL certificate to the download subdomain of this blog running ownCloud for about 2 years, but recently my free StartSSL certificate expired, and I had troubles to renew it, and I also received an email from Google telling me that “Starting October 2017, Chrome (version 62) will show a “NOT SECURE” warning when users enter text in a form on an HTTP page, and for all HTTP pages in Incognito mode”.  So I decide to use free LetsEncrypt SSL/TLS certificates to replace the one in the download subdomain, as well as this main blog. Such SSL/TLS certificates are also very useful for the IoT gateways many of use have started using, and I found it’s even simpler than install a self-signed certificate, so there’s no reason to use those anymore.

The easiest way to install Let’s Encrypt certificate is by using Certbot with instructions for various web server or hosting platforms (nginx, apache, pleask, haproxy…) and BSD & Linux based operating systems. I’m using Ubuntu 14.04 trusty with nginx, so the instructions below are for this combination, and it took me around 2 to 3 minutes in my VPS to have the SSL/TLS certificate installed, and up and running.

Cerbot installation:

Certificate installation for nginx on download.cnx-software.com subdomain:

Done! I could now go to https://download.cnx-software.com with my freshly installed certificate. That’s it for the 2-minute installation procedure, but as with such quick and easy procedure, you can always add “wasting countless hours” steps to it, and that’s what I did, by first checking out the Qualys SSL Report as recommended in the output of the terminal above.

Grade C, not good. The certificate is mostly there to protect my login credentials, as I don’t have any important private data in that server, but let’s still try to improve this. The most critical issue is that the server is vulnerable to the POODLE attack, but luckily Nginx guys have a fix: disable SSLv3.

I just had to change a single line in the server block of the domain configuration file in /etc/nginx/sites-enabled directory to only allow for TLS connections:

I then reload the configuration with:

Ran the SSL report again, and I improved to Grade B. That was easy.

After Disabling SSLv3

The second problem is about “weak Diffle Hellman (DH) key exchange parameters”, but again there are solutions.

First I had to create a dhparams.pen files with the following command line:

then edit the domain configuration file in /etc/nginx/sites-enabled/ directory by adding the following in the server block:

After reloading nginx configuration, I had a grade A with no other problems to solve.

I checked two banking websites, and they got A-, two online shops (GearBest and GeekBuying), and they achieved Grade B, so when you share your credit card info, you are at risk, albeit likely a limited risk. Considering it’s so easy to fix some of the issues, they should do it, and I informed both companies.

Let’s Encrypt certificates expires just after 90 day, so you may want to setup automatic renewal. First check renewal works with a dry run:

If there are no errors, you can setup a cron or systemd job to run the following command regularly:

I then tried with some other domains, and I got a TLS handshake failure:

The reason was Cloudflare intercepting traffic, so I had to pause Cloudflare before running certbot, and installation went just fine, and I could use my website without any problem, until I resumed Cloudflare support, and got “too many redirects”. I started to look for solutions with come fairly complicated instructions for Certbot + Apache + Cloudflare. After a few hours trying to find a solution, I discovered my assumption that if I enable an SSL certificate on my side, I should just disable SSL in Cloudflare… Big mistake! After setting Cloudflare SSL to Full (Strict) it worked again, although I eventually just to set it to Full because Let’s Encrypt wildcard SSL certificate are not yet supported, but will be in January 2018.

So the TLS connection was working, but I tried a dry run to renew the certificate, and every domain managed through Cloudflare would fail… That’s when the “complicated instructions” above came handy… So I first installed Certbot Cloudflare plugin/add-on:

Created /etc/letscrypt/cloudflare.ini file with your email, and API key in Cloudflare (Global API Key)

and generated new certificates using that plugin:

This should overwrite the two files used for the certificates previously created with nginx option: /etc/letsencrypt/live/www.domain.com/fullchain.pem
& /etc/letsencrypt/live/www.domain.com/privkey.pem.  So normally, you don’t even need to change your nginx configuration after that, but if for some reasons the path has changed, you should edit your file in /etc/nginx/sites-enabled/ and updated the paths.

Finally, I tried the dry run to update the certificate and it worked, so I created a cron job to renew the certificates every month:

If your website is also designed to be compatible with https, then your job is done, if not, then you’ll have some work to do to remove all hardcoded http calls from your websites with the help of the developer console in web browsers such as Chrome or Firefox.

How to Setup an Orange Pi Zero DIY Smart Speaker with Google Assistant SDK

July 30th, 2017 83 comments

A preview release of Google Assistant SDK working with Raspberry Pi 3 and other ARMv7 boards was released in May, and soon after, AIY Projects Voice Kit was offered for free with Raspberry Pi Magazine in order to a complete smart speaker kit working with RPi 3. I wanted to try it on one of FriendlyELEC or Shenzhen Xunlong Allwinner board, since all we need is audio input and output, and an Internet connection. Earlier this month, I came across Orange Pi Zero Set 6 Kit that had all I needed: Orange Pi Zero ARM Linux board, an expansion board with built-in microphone and audio output jack, and a cute and small case to neatly put everything together.

Orange Pi Zero Set 6 Kit Unboxing and Assembly

Shenzhen Xunlong sent me the kit so that I can try it out.

The package includes two Orange Pi packages, the plastic case, some a bag with screws and rubber pads.

One of the package comes with Orange Pi Zero board powered by Allwinner H2+ quad core processor with 512 MB RAM, micro USB for power, 10/100M Ethernet, a USB port, a WiFi antenna, and expansion headers on the top…

Click to Enlarge

.. and a micro SD card slot on the bottom, which we’ll use to boot the operating system.

The second package is for Orange Pi Zero Interface board v1.1 with two more USB port, an IR receiver, a 3.5mm audio jack, and a built-in microphone (top right).

Click to Enlarge

The next step is just to plug the interface board into Orange Pi Zero board, bending the WiFi antenna between the two boards…

Click to Enlarge

… before pushing the board from the bottom of the enclosure, tightened the cover with the 4 screws, and adding the 4 rubber pads.

Click to Enlarge

Installing Ubuntu on Orange Pi Zero & Configuring Networking and Audio Input & Output

Google Assistant SDK requires Ubuntu or Debian operating system, so I downloaded Ubuntu server legacy image on Armbian website, since the mainline image does not support XR819 WiFi module at all. I then extracted Armbian_5.30_Orangepizero_Ubuntu_xenial_default_3.4.113.7z and flashed Armbian_5.30_Orangepizero_Ubuntu_xenial_default_3.4.113.img  with Etcher on a micro SD card using my main computer.

Once it was done, I took the micro SD card to Orange Pi Zero board, connected my own speakers to the 3.5mm audio jack and USB for power, as well as a 5V/2A USB charger to power the system.

Click to Enlarge

You may notice an extra USB dongle on the picture above, but we’ll talk about that later.

I’ll use WiFi to test Google Assistant, but I also connected an Ethernet cable to make it easier for first time setup. If you don’t have Ethernet, you could also connect the board via a USB to TTL board to access the serial console.

After looking up the IP address of the board in my router, I connected with SSH using root (password: 1234):

The very first boot it will ask your to change the root password, and create a new user. You may want to create “pi” user at this stage. We should not be able to access the command, and run the following command to configure Orange Pi Zero board:

I first changed the timezone.

Then selected WiFi – Connect to wireless access point to connect to my WiFi router.

We can quit armbian-config, and optionally disconnect the Ethernet cable, and reconnect SSH over WiFi, which I did.

Back in the command line, I tested audio recording & playback with the built-in microphone and speakers using the same commands as in ReSpeaker guide:

The first command recorded my voice, and then I pressed Ctrl+C to stop, and play it back with the second command. I worked fine for me. If you wish you can adjust the playback and recording volume with:

We’ll also need to create .asoundrc file for Google Assistant to work with ALSA. For we need to note the microphone card and device number (0,0):

as well as speaker card and device number (0,0):

If you want to use your TV as speaker, you’d use Card 1, device: 0.

If you have not created a pi or other user yet, you’ll want to add one belonging to sudoers and audio groups, and go the home directory:

Now create a ~/.asoundrc with the following match the card and device for our mic and speaker:

[Update: As we’ll see below this won’t work with the built-in microphone, but as indicated in the comments below, this can be fixed by changing pcm.mic section with:

I have not changed the rest of the post, but the built-in microphone on Orange Pi Zero does work now]

Setting Up Google Assistant on Orange Pi Zero

Now that audio and networking are both setup and working, we can carry on with the instructions to install Google Assistant SDK and demo. Those are the same for all boards, and I’ll describe them below in details.

We need to configure a Google Developer Project.

Go to the Project page in Google Platform Console, and click on Create Project.

I called it Orange Pi Zero Smart Speaker, and clicked on Create.

Next, we’ll need to enable Google Assistant API for our project. Simply click on Enable on that page. The “Orange Pi Zero Smart Speaker” project was already selected in my case.

We’re then being asked to create an OAuth Client ID. I only filled my email address, and a product name before clicking on Save.

Select Other in the next page, and give another name – I used “Linux Thingy” – before clicking on Create.

You should now see an OAuth client pop-up window with your client ID and secret. You can just click OK, no need to copy or save either.

Instead we’ll download client_secret_[your_client_id].json file on the next page by clicking on the arrow circled in red.

I then copied that file to Orange Pi Zero board using scp (change [your_client_id] with your actual client ID):

Now that we have configured most options we need in Google Cloud platform, let’s install Python 3 and dependencies:

At this stage to need to make sure “Web & App Activity” with “Include Chrome browsing history and activity from websites and apps that use Google services”  checked, Device Information and Voice & Audio Activity are enabled in the Activity Controls page. All options were already enabled for me by default.

We can now install Google Assistant SDK package including library and sample code:

and the authorization tool:

Run the authorization tool:

This should show a text reading “Please visit this URL to authorize this application: https://….”. Select the URL and open it in a web browser, and copy/paste the authorization code you see in the web browser back into the terminal.

We can now start the demo

That’s the initial output

I went to say “OK Google” and “Hey Google”, and… nothing. No answer, and no info in the terminal window either. I tried several times, and also played with:

as explained in the troubleshooting section in Google Assistant documentation, incrementing the value by 6 until I reached -60, before running the demo, and no luck. So I thought maybe my “American accent” could have been the problem, so I launched Google Translate in my phone, and make it say “OK Google”. Same disappointing result. I went to Google Cloud Console, and good see some activity, but with 100% errors.

Click to Enlarge

So I did some searching on the web, I could find one person changing the .asoundrc file, but I did not work for me with the file generating plenty of sound related errors when running the demo, and another fix a similar problem by changing the microphone. Which reminded me, I had bought a cheap USB microphone on eBay for $1.45. So I connected it to Orange Pi Zero board, and that’s the extra USB dongle in the photo with the speakers higher in this guide, and check the card and device number:

We can see the USB card 2, device 0, so I update the relevant line in pcm.mic section in .asoundrc:

and ran the demo again. Success! The device would reply to make “OK Google” request, and tell me the time, my name, the weather for tomorrow, sing a song, do some calculus and so on.

This is what the output looks like when the demo works: