Orange Pi PC, Armbian and SDR

A few weeks ago I’ve bought an SDR RTL2832U+R820T2 dongle to do some tests with Software Defined radio. Despite of being able to catch some signals with the provided antenna, I have a huge interference problem originated from my desktop PC. Using the SDR dongle connected to my laptop and with the desktop PC off, most part of those interferences disappear. Still reception was poor due to the antenna quality and my office location.

So one solution for the above issues is to remotely put the SDR dongle in a better location and with a better antenna and connect the SDR software running on my desktop PC to this remote SDR dongle by using the rtl_tcp program.

Since I didn’t want to shell out a lot of money again for a RPi or Odroid C1/C2, I’ve decided to by an Orange Pi PC from Aliexpress for about 16.5€, postage included.

The Orange PI PC
The Orange PI PC is a small form computer like the Raspberry Pi and Odroid C1/C2 for example. It has a quad-core Allwinner processor that runs at 1.2GHz (under Armbian), with 1GB of memory, 3 USB2 ports and HDMI.
The Orange Pi provided operating system seems to overclock the CPU to 1.6GHz which brings a lot of stability and heat issues to the device.
The Armbian version seems to not suffer from such issues and works out of the box, including HDMI video output and apparently video acceleration (Haven’t tested it yet).
I’ve also bought, separately the acrylic box and a 2A 5V charger with the correct plug to connect to the Orange PI. The Orange PI, box and power supply took less than 3 weeks to arrive.

Starting up
The Orange PI needs an small form micro SD card to have the operating system installed and space for the file system. The recommend cards are Sandisk UHS-1 or Samsung UHS-1, but I’ve bought a Toshiba micro SD Exceria UHS-1 card, that works fine.
The card comes with a standard SD card adapter to be used when connected to a card reader.

After copying the Armbian operating system to the card on my desktop computer, and putting it the micro SD card slot on the Orange PI, I’ve just connected the network, HDMI and power.

The initial power up sequence can take several minutes, since it will expand the file-system on the SD card and probably sets up other things.

At the end there was a RED led steadily lit and a blinking GREEN led, with the Armbian desktop on my monitor.

Setting up
The following steps can be done through the desktop environment or through ssh. I’ve done all these steps through ssh:

– Change the root password from the default 1234 to a secure password.
– Change the Time Zone to my time zone: dpkg-reconfigure tzdata
– Change the hostname: vi /etc/hostname
– Add a working user: adduser opi
– Add the opi user to the sudo group: usermod -aG sudo opi
– Change the password of the opi user: passwd opi
– Move the network from DHCP to a fixed IP: vi /etc/network/interfaces

# Wired adapter #1
auto eth0
#iface eth0 inet dhcp
iface eth0 inet static
address 192.168.1.5
netmask 255.255.255.0
gateway 192.168.1.254

– Update the software: apt-get update and apt-get upgrade
– Install the rtl sdr software: apt-get install rtl-sdr gqrx-sdr librtlsdr-dev libusb-1.0-0-dev
– Blacklist the dvb modules so that the RTL software can load: vi /etc/modprobe.d/rtl-sdr-blacklist.conf

# This system has librtlsdr0 installed in order to
# use digital video broadcast receivers as generic
# software defined radios.
blacklist dvb_usb
blacklist dvb_core
blacklist dvb_usb_rtl2832u
blacklist dvb_usb_rtl28xxu
blacklist e4000
blacklist rtl2832

And finally we can reboot and connect our RTL SDR dongle.

Some final notes:
The SD card speed with the Toshiba Exceria card is:

hdparm -Tt /dev/mmcblk0p1

/dev/mmcblk0p1:
 Timing cached reads:   856 MB in  2.00 seconds = 427.67 MB/sec
 Timing buffered disk reads:  58 MB in  3.03 seconds =  19.12 MB/sec

About 40% slower than my Odroid emmc disk.

To allow the remote Gqrx SDR software to connect we need to run:

 rtl_tcp -a 192.168.1.5

And configure Gqrx as following:

Gqrx Device Config

and start using GQRX.

The Orange Pi CPU and temperatures with rtl_tcp running and connected never rouse above 7/8% CPU and 43ºC, so it looks good!

Gqrx tunning
Just one final note regarding GQRX:

On the Orange Pi, the rtl_tcp program was outputting a lot of ll+:### where ### is an increasing number, and I had several seconds of lag between the change of frequency on the Gqrx aplication.

After checking the rtl_tcp code source, these messages are related to buffering issues, so I’ve changed the Gqrx connection string to:

rtl_tcp=192.168.1.5:1234,buffers=384,psize=65536

and all ll+ messages where eliminated never rising above 5.

MQTT Mosquitto broker with SSL/TLS transport security

Just a quick note in setting up transport layer security on the MQTT Mosquitto broker for both supported protocols: MQTT and WebSockets.

There are several posts on the web regarding this, namely:

SSL Client certs to secure mqtt and Mosquitto websocket support

Those posts explain more or less what is needed to be done to have TLS/SSL transport security. These are just my notes:

Generating the server certificates:
This can be quite easily accomplished by using the following script: https://github.com/owntracks/tools/blob/master/TLS/generate-CA.sh.
This script will generate a self signed certificate to be used by Mosquito for providing TLS for the MQTT and WebSocket protocol. All that is needed to run the script is to have openssl installed on your Linux machine.

If the script is called without parameters, it will generate a self signed certificate for the hostname where the script is running. Otherwise a we can pass a hostname as the first parameter to the script.

After running the script, the following files are generated:

  1. ca.crt – The CA (Certificate Authority, who published the host certificate) public certificate.
  2. hostname.crt – The hostname, that will run the mosquitto broker, public certificate.
  3. hostname.key – The hostname private key.

After having these files, we need to configure the Mosquitto Broker to use them.

Mosquitto configuration:
To configure the Mosquito broker we need first to copy the certificates and key files to a known directory. We will create a certs directory under /etc/mosquitto:

sudo -s
mkdir -p /etc/mosquitto/certs
cp ca.crt /etc/mosquitto/certs
cp hostname.* /etc/mosquitto/certs

After this we can modify the mosquitto configuration file. One important thing to keep in mind is that lines must be following each other without blank lines after the listener directive.

So:

# Plain MQTT protocol
listener 1883

# End of plain MQTT configuration

# MQTT over TLS/SSL
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/hostname.crt
keyfile /etc/mosquitto/certs/hostname.key

# End of MQTT over TLS/SLL configuration

# Plain WebSockets configuration
listener 9001
protocol websockets

# End of plain Websockets configuration

# WebSockets over TLS/SSL
listener 9883
protocol websockets
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/hostname.crt
keyfile /etc/mosquitto/certs/hostname.key

We will make one more change, but restart mosquitto broker now and do some testing.

Testing MQTT TLS/SSL configuration
We can use Mqtt-Spy to subscribe to our defined test topic: test. We can use plain MQTT or use MQTT over TLS/SSL:

MQTT Spy simple TLS configuration

MQTT Spy simple TLS configuration

We can use then the MQTT spy tool to publish or subscribe MQTT topics.

By command line, the mosquitto_sub and mosquitto_pub only worked if the port number for MQTTS is provided, otherwise it gives a TLS error:

mosquitto_pub --cafile /etc/mosquitto/certs/ca.crt -h localhost -t "test" -m "message" -p 8883

mosquitto_sub -t \$SYS/broker/bytes/\# -v --cafile /etc/mosquitto/certs/ca.crt -p 8883

This should work without any issues.

Testing MQTT websockets over TLS/SSL configuration
The issue with this testing is that we are using a self signed certificate, so only useful for local, restricted, testing.
Before we can use the MQTT websockets with TLS/SSL enabled we need to use the browser and visit the following URL:

  https://MQTT_BROKER_IP_OR_HOSTNAME:9883/mqtt

Note that we are using HTTPS. When connecting to the above URL, the browser should complain about the insecure connection, due to the self signed certificate, and we need to add an exception and always accept that certificate. After that the error should be something like connection reset or failed to load page. This is normal, since the browser won’t upgrade the connection to a web socket.
We can now use the Hive MQTT Websockets Client to test our connection, and it should work fine (Note the connected green icon and SSL is selected):
Hive MQTT WebSocket client

Forcing TLSv1.2
All this work of enabling TLS/SSL on the Mosquitto Broker is needed, since most IoT clouds that have MQTT interface need that the connection is over TLS/SSL. More specifically AWS IoT cloud needs the connection to be protected by TLS/SSL, but that connection must be only on version 1.2 of the TLS protocol. AWS IoT cloud also requires client authentication through client certificates, but we are not dealing with this part on this post.

So we are now configuring our Mosquitto broker to only accept TLSv1.2 connections. To do that we modify the mosquitto.conf file and add the following line:

# MQTT over TLS/SSL
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/hostname.crt
keyfile /etc/mosquitto/certs/hostname.key
tls_version tlsv1.2

# WebSockets over TLS/SSL
listener 9883
protocol websockets
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/hostname.crt
keyfile /etc/mosquitto/certs/hostname.key
tls_version tlsv1.2

and restart the broker.

Testing TLS V1.2
We can specify the TLS version on the mosquitto command line utils:

[pcortex@pcortex:~]$ mosquitto_pub --cafile ./ca.crt --tls-version tlsv1.2 -h localhost -t "test" -m "mes" -p 8883 -d
Client mosqpub/26994-pcortex sending CONNECT
Client mosqpub/26994-pcortex received CONNACK
Client mosqpub/26994-pcortex sending PUBLISH (d0, q0, r0, m1, 'test', ... (3 bytes))
Client mosqpub/26994-pcortex sending DISCONNECT
[pcortex@pcortex:~]$ mosquitto_pub --cafile ./ca.crt --tls-version tlsv1.1 -h localhost -t "test" -m "m3224" -p 8883 
Error: A TLS error occurred.

As we can see the lower versions of the TLS protocol are now not accepted.
The Websockets client should work without any issues.

Conclusion:
This configuration only solves the transport security, not the authentication security. The later can be accomplished by using the username/password process or using client certificates, which is the process that Amazon AWS IoT cloud uses. But those are topics for other posts. Edit: Follow-up at: Client authentication

ODroid – Mosquitto MQTT Broker install

Just for a quick reference, the following instructions detail how to install the latest Mosquitto MQTT broker with Websockets enabled on the ODroid C1+ running (L)Ubuntu release. The instructions are probably also valid for other platforms, but not tested.

1. Install the prerequisites
As the root user, install the following libraries:

apt-get update
apt-get install uuid-dev libwebsockets-dev

Probably the SSL libraries, and a few others are also needed, but in my case they where already installed.

2. Mosquitto install
Download and compile the Mosquitto broker:

mkdir ~/mosq
cd ~/mosq
wget http://mosquitto.org/files/source/mosquitto-1.4.5.tar.gz
tar xvzf mosquitto-1.4.5.tar.gz
cd mosquitto-1.4.5/

Edit the config.mk file to enable the websockets support:

# Build with websockets support on the broker.
WITH_WEBSOCKETS:=yes

and compile and install:

make
make install

3. Configuration
Copy the file mosquitto.conf to /usr/local/etc, and edit the file:

cp mosquitto.conf /usr/local/etc
cd /usr/local/etc

Add at least the following lines to mosquitto.conf file to enable websockets support.

# Port to use for the default listener.
#port 1883
listener 1883
listener 9001
protocol websockets

Add an operating system runtime user for the Mosquitto daemon:

useradd -lm mosquitto
cd /usr/local/etc
chown mosquitto mosquitto.conf

If needed, or wanted, change also on the configuration file the logging level and destination.
For example:

# Note that if the broker is running as a Windows service it will default to
# "log_dest none" and neither stdout nor stderr logging is available.
# Use "log_dest none" if you wish to disable logging.
log_dest file /var/log/mosquitto.log

# If using syslog logging (not on Windows), messages will be logged to the
# "daemon" facility by default. Use the log_facility option to choose which of
# local0 to local7 to log to instead. The option value should be an integer
# value, e.g. "log_facility 5" to use local5.
#log_facility

# Types of messages to log. Use multiple log_type lines for logging
# multiple types of messages.
# Possible types are: debug, error, warning, notice, information, 
# none, subscribe, unsubscribe, websockets, all.
# Note that debug type messages are for decoding the incoming/outgoing
# network packets. They are not logged in "topics".
log_type error
log_type warning
log_type notice
log_type information

# Change the websockets logging level. This is a global option, it is not
# possible to set per listener. This is an integer that is interpreted by
# libwebsockets as a bit mask for its lws_log_levels enum. See the
# libwebsockets documentation for more details. "log_type websockets" must also
# be enabled.
websockets_log_level 0

# If set to true, client connection and disconnection messages will be included
# in the log.
connection_messages true

# If set to true, add a timestamp value to each log message.
log_timestamp true

4. Automatic start
The easiest way is to add the following file to the init.d directory and link it to the current runlevel:

Create the file named mosquitto under /etc/init.d

#!/bin/bash

case "$1" in
    start)
        echo "Starting Mosquitto MQTT Broker"
        touch /var/log/mosquitto.log
        chown mosquitto /var/log/mosquitto.log
        su - mosquitto -c "/usr/local/sbin/mosquitto -c /usr/local/etc/mosquitto.conf" & > /dev/null 2>/dev/null
        ;;
    stop)
        echo "Stopping Mosquitto MQTT Broker"
        killall mosquitto
        ;;
    *)
        echo "Usage: /etc/init.d/mosquitto start|stop"
        exit 1
        ;;
esac

exit 0

Find out the current run level. On Odroid it seems that is level 2:

root@odroid:/etc/init.d# runlevel
N 2
root@odroid:/etc/init.d# 

And link the automatic start for Mosquitto broker at run level 2:

cd /etc/rc2.d
ln -s  /etc/init.d/mosquitto S97mosquitto

And that’s it.

We can start manually the broker with the command /etc/init.d/mosquitto start, and stop it with the mosquitto stop command.

Simple Dashboard for HomeLab

I’ve found by chance a great source for alternative software for common applications on Reddit: Self Hosted. It’s a “sub” where people discuss, ask or report alternatives to things like Dropbox, online editors, and so on.

One of the posts that caught my attention was a discussion of Simple Dashboards for things like basic URL links to access common applications and so on. Nothing fancy.

Still the basic dashboard is very useful, it allowed me to centralize all links and information on a web page without depending on my browser bookmarks, avoiding the need to sync all the bookmarks across all devices.

Anyway, one of the striking examples is this one: Dashboard example. The discussion is here.

Another example is on this post: from where I used the code at with a mix of the above JsFiddle example for weather data.

So, some fiddling around HTML code is needed, but a simple and effective dashboard can be set on a web server running on Rpi, for example (mine is running on Odroid C1+), to centralize links, information and what ever our imagination allows to, on a web page. As I said, nothing revolutionary here 🙂

ESP8266 – Sming Framework, issues and tips.

So some issues and tips regarding the Sming framework for programming the ESP8266:

The Arduino Json library on Sming master branch
Version 4.0 of the Arduino Json Library is present, at least at today’s date (12/2015) on the Master branch of the Sming framework.
The develop branch of the framework uses the version 5.0 of the Arduino Json library.

To do any useful work with JSON on the Sming framework we should use the develop branch and not the master branch.

It might be related, or not, didn’t investigated too much, but I had huge memory leaks that exhausted my heap very rapidly when using the master branch when processing JSON data. When using the development branch, with the same code base (just a HTTP client and Json decoding) those issues where gone.

Other issues with version 4.0 of the Arduino Json Library included the processing of double/float values that had no floating point, which is a great problem on this version. For example (double)15 evaluates as zero, while (double)15.0 evaluates correctly. So it is really important to upgrade and use the version 5 of the JSON library.

So instead of just cloning the master branch, clone the development branch: git clone -b develop https://github.com/SmingHub/Sming.git

Building images
On the master branch I had no trouble creating and flashing the resulting images to the ESP8266, but on the development brach I had serious problems. The issue is solved now, and it is related to the esptool.py tool that is unable to generate the image files to be flashed. The latest version of the esptool.py available on the Github repository complains regarding the errno definition, also something that is related, to the Json Library.

Anyway, the latest commits on the development branch uses the esptool2, just clone the repository onto somewhere (in my case /opt):

[pcortex@pcortex: opt]$ git clone https://github.com/raburton/esp8266
[pcortex@pcortex: opt]$ cd esp8266/esptool2
[pcortex@pcortex: esptool2]$ make

And make sure that the esptool2 binary is on the path, or change the Makefile-project.mk located, in my case, in /opt/Sming/Sming:

From

# esptool2 path
ESPTOOL2 ?= esptool2

to

# esptool2 path
ESPTOOL2 ?= /opt/esp8266/esptool2/esptool2

After this, the usual cycle of make and make flash should work. If we already have a project we should first run make clean just that the esptool2 can create the new image files.
Note that the esptool.py tool is still used for the flashing process.

So the final conclusion is, despite its bleeding edge status, to use the development brach, and not the master branch as of today. The issues that are solved on the development branch are important to the make the framework useful.

Dropbox doesn’t start (Linux)

So a quick note regarding Dropbox running on ArchLinux with Nvidia drivers. Since I use KDE Plasma 5 that doesn’t show system tray icons of some applications that have not migrated to the new system tray protocol, I didn’t notice that after upgrading Dropbox it stopped working.

A quick investigation, I’ve found out that starting Dropbox from the command line did nothing. It started and stopped. Something is going on…

So I’ve used the strace command to see if I could catch something meaningful:

[pcortex@pcortex:~]$ cd .dropbox-dist/dropbox-lnx.x86_64-3.10.8/
[pcortex@pcortex:dropbox-lnx.x86_64-3.10.8]$ strace ./dropbox 2> stracedump.txt

And sure enough in the stracedump.txt I had the following error:

open("/usr/lib/dri/tls/swrast_dri.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/dri/swrast_dri.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0} ---
rt_sigaction(SIGSEGV, {0x7f09e1dea010, [SEGV], SA_RESTORER|SA_RESTART, 0x7f09e1a88d60}, NULL, 8) = 0
write(4, "Fatal Python error: ", 20)    = 20
write(4, "Segmentation fault", 18)      = 18
write(4, "\n\n", 2)                     = 2
write(4, "Traceback (most recent call firs"..., 36) = 36
write(4, "  File ", 7)                  = 7
write(4, "\"", 1)                       = 1
write(4, "d", 1)                        = 1

So the error is related to the Software Raster library, that I don’t have because I’m running Nvidia proprietary drivers.

The confirmation came with the following command:

[pcortex@pcortex:dropbox-lnx.x86_64-3.10.8]$ LIBGL_DEBUG=verbose ./dropbox
libGL: OpenDriver: trying /usr/lib/dri/tls/swrast_dri.so
libGL: OpenDriver: trying /usr/lib/dri/swrast_dri.so
libGL error: dlopen /usr/lib/dri/swrast_dri.so failed (/usr/lib/dri/swrast_dri.so: cannot open shared object file: No such file or directory)
libGL error: unable to load driver: swrast_dri.so
libGL error: reverting to indirect rendering

The solution?
Quite simple, just remove (backup) the libGL.so.1 library that exists on the Dropbox directory.
After the removal, Dropbox starts just fine.

ESP8266 Sming – How to start

After dumping Lua Nodemcu for doing any useful work/tinkering on the ESP8266(it works fine for simple things and that’s it), from the available options for programming the ESP8266, native C/C++ SDK programming, Arduino, Sming, Smart.js and Espruino, I’ve selected Sming. One of the main reasons for selecting Sming is the huge range of working examples comprising HTTP clients, servers, AJAX, sensors, MQTT, you name it. Also I can use Netbeans IDE to build the ESP8266 applications and since Netbeans offers code completion, It can help a lot with the apparent lack of API documentation.

Netbeans Sming Code Compltetion

Netbeans Sming Code Compltetion

Another advantage that is not stated enough is the SPIFFS file system support. Install spiffy and under your project directory, create a files sub-directory, put the files there, and those files are flashed onto the ESP8266 as the SPIFFS file system…

How to start
Install first the esp-open-sdk and then Sming. The Sming instructions are pretty clear, in my opinion, on the GitHub site. Also if using Netbeans instructions are here: Setting up Sming with Netbeans. Make sure that the include paths are configured. It will enable code completion and get rid of the “errors” on the IDE.

After that we can export the variables ESP_HOME and SMING_HOME with the esp-open-sdk and Sming paths, or change the Makefile-user.mk of each project to point to the correct locations.

Installing and configuring Spiffy.

The following instructions are deprecated! -> See below how to install from SmingHub.
As usual, download spiffy from Github, compile, and make Sming aware of its location:

[pcortex@dune:opt]$ git clone https://github.com/alonewolfx2/spiffy
Cloning into 'spiffy'...
remote: Counting objects: 101, done.
remote: Total 101 (delta 0), reused 0 (delta 0), pack-reused 101
Receiving objects: 100% (101/101), 78.41 KiB | 0 bytes/s, done.
Resolving deltas: 100% (54/54), done.
Checking connectivity... done.
[pcortex@dune:opt] cd spiffy
[pcortex@dune:spiffy master]$ mkdir build
mkdir: created directory ‘build’
[pcortex@dune:spiffy master]$ make

Under the directory build should be now a binary named spiffs.

Goto now to the Sming/Sming subdirectory and edit the Makefile-project.mk and edit the SPIFFY ?= spiffy line to include the full path of spiffy. In my case:

# Full path spiffy command, if not in path.
SPIFFY ?= /opt/spiffy/build/spiffy

With this change when we clone one of the available projects we can just create a files subdirectory under the project directory to enable files that are put there to be flashed onto the ESP8266. Just make sure that you add to the project Makefile-user.mk file the line: SPIFF_FILES = files

Spiffy from SmingHub

The latest version of Sming that is available from Sming Hub already has spiffy available. We just need to build it.

[pcortex@dune:opt] cd /opt/Sming/Sming/spiffy
[pcortex@dune:spiffy] make

And that’s it, spiffy binary is now available.
Another way to build is just to make spiffy at the /opt/Sming/Sming directory.

First project
For first project I recommend to clone/copy one of the provided examples to a directory OUT of the Sming folders. Why? Because in this case we won’t have any conflicts when doing a git pull to update the Sming framework, and we keep the original projects intact, so we can use them as reference.

After copying the project we can see that the file structure is simple, and coding isn’t that hard ( but it’s needed to have some C and C++ proficiency ) to build applications. Coding on Sming framework is very similar to programming for an Arduino function and library wise, but with some differences, namely the callback “way” of programming and the nonexistence of the setup()/loop() paradigm (it doesn’t makes sense on a callback way of programming).

The code folder structure should mimic the example projects, namely a root folder where the make files reside, and under this folder the app folder for application files (.cpp, .c), the include folder for include files, and a files folder (optional) for holding files for the spiff file system.
Still these folders can be changed by modifying the Makefile-user.mk file at the root directory, namely the MODULES entry and the SPIFF_FILES entry:

Makefile-user-mk:
#Add your source directories here separated by space
# Sources under the ./app and ./libcode1 and ./libcode2
MODULES = app libcode1 libcode2

## MacOS / Linux:
ESP_HOME = /opt/esp-open-sdk

# MacOS / Linux
SMING_HOME = /opt/Sming/Sming

# MacOS / Linux:
# COM_PORT = /dev/ttyUSB0

# Com port speed
COM_SPEED	= 115200

# SPIFFs files Location
SPIFF_FILES = web

Programming

All Sming framework based programs must provide a init() function, that is called at ESP8266 startup. There is no setup() or loop() functions. The later function doesn’t make sense since for programming the ESP8266 we register a function for an event, and that function is called when the event triggers. No need for pooling and/or looping. So no loop() function. The Arduino sketch setup() function is in our Sming framework our init() function…

On the init() function we can setup a lot of things like, pin modes, serial port, and of course Wifi connectivity. Programming with an IDE that offers code completion allows us to see the available API and guess some of the functionality even without documentation ( note that most of the API is identical/similar to the Arduino).

So for programming with the Sming framework these are some of my notes that might be helpful:

Serial port
The always helpful serial port… allows the output of data and debugging information and keyboard input, at least when the device is connected to the computer.
The serial port usage from a coding stand point is identical to the Arduino library, but ESP8266 outputs some debugging information also for the serial port:

Serial.systemDebugOutput( flag ) - Enables/disables framework debugging.

When the value of the input parameter flag is true, we can see a lot of information, including HTTP headers, and so on. Quite verbose, which means that our output might be lost in the middle of this debugging information.
Still with the above flag set as false we can still see some debug output that can be almost completely shut off with the following instruction: system_set_os_print(0);.

So a standard init function would be something like:

void init() {
        system_set_os_print(0);  // Zero to disable, 1 to enable. Disable SDK output to serial 
  	Serial.begin(SERIAL_BAUD_RATE); // 115200 by default. SERIAL_BAUD_RATE constant is defined in include/user_config.h
	Serial.systemDebugOutput(false); // Disable debug output to serial
   
        Serial.println("Starting up!...");
        //....

}

A final note regarding printing to the serial port and debugging, we can use the higher level Serial output instructions, but with Sming we also can use/mix the standard SDK instructions: this means that we can also use the functions debugf and os_printf.

System ready
We can on the init function register a callback for when the system is ready:

void systemIsReady() {
   // do stuff.
   // Start servers
   // Note that wifi connection here is not assured. 

}

void init() {
        system_set_os_print(0);  // Zero to disable, 1 to enable. Disable SDK output to serial
  	Serial.begin(SERIAL_BAUD_RATE); // 115200 by default. SERIAL_BAUD_RATE constant is defined in include/user_config.h
	Serial.systemDebugOutput(false); // Disable SMING debug output to serial
   
        Serial.println("Starting up!...");
        //....

        System.onReady(systemIsReady);
}

Wifi Connection
Almost all the examples have the setting up of a wifi connection, some as a client, others as access point.
The important thing is that the all the callback functionality either on success or failure is already implemented, and so it’s quite easy to check for success or failure.

// Will be called when WiFi station was connected to AP
void connectOk()
{
        String devIP;
        String mac;
	Serial.println("I'm CONNECTED");

        devIP = WifiStation.getIP().toString();
        
        Serial.println("Device IP : " + devIP );

        mac = WifiStation.getMAC();
        mac.toUpperCase();
        Serial.println("Mac addrs: " + mac );
        ...
}

// Will be called when WiFi station timeout was reached
void connectFail()
{
	Serial.println("I'm NOT CONNECTED. Need help :(");

        WifiStation.waitConnection(connectOk, 20, connectFail); // We recommend 20+ seconds for connection timeout at start
}

void init() {

    // ....
	WifiStation.config(WIFI_SSID, WIFI_PWD);
	WifiStation.enable(true);
	WifiAccessPoint.enable(false);

	// Run our method when station was connected to AP (or not connected)
	WifiStation.waitConnection(connectOk, 20, connectFail); // We recommend 20+ seconds for connection timeout at start

    //....

}

Note that is way easier than Nodemcu Lua where we need to implement the connection check by ourselfs by doing a timer based pooling.
With Sming is quite easy, connectOK() is called when a successful connection is made, and connectFail() is called if the timeout (the second parameter) is reached and a connection isn’t made.

On connectFail() we can just again repeat the same instruction or list the available networks and try to connect to some of them.

Still, in my opinion, we should set up the WIFI parameters and connection initiation under the system ready callback.

Some code snippets
List the available wifi networks:

// callback function for WifiStation.startScan(networkScanCompleted);
void networkScanCompleted(bool succeeded, BssList list)
{

	if (!succeeded)
	{
		Serial.println("Failed to scan networks");
		return;
	}

	for (int i = 0; i < list.count(); i++)
	{
		Serial.print("\tWiFi: ");
		Serial.print(list[i].ssid);
		Serial.print(", ");
		Serial.print(list[i].getAuthorizationMethodName());
		if (list[i].hidden) Serial.print(" (hidden)");
		Serial.println();
	}
}

void init() {
    //...
    WifiStation.startScan(networkScanCompleted);
    //...
}

List system info.

void ShowInfo() {
    Serial.printf("\r\nSDK: v%s\r\n", system_get_sdk_version());
    Serial.printf("Free Heap: %d\r\n", system_get_free_heap_size());
    Serial.printf("CPU Frequency: %d MHz\r\n", system_get_cpu_freq());
    Serial.printf("System Chip ID: 0x%x\r\n", system_get_chip_id());
    Serial.printf("SPI Flash ID: 0x%x\r\n", spi_flash_get_id());
    Serial.printf("SPI Flash Size: %d\r\n", (1 <> 16) & 0xff)));
}

The above snippet was kind of important because it shows how to get the system or chip id that can used to identify the device, for example, in MQTT device names.

Just a final note, that all the above code and snippets are collected from several sources:

– Sming Examples
– ESP8266.Com forum
– GitHub: https://github.com/dmarkey/smarthome_esp8266RCcontroller_sming.git and mainly https://github.com/gernoteger/DobbyESP