1. December 2016

ESP8266 WiFiManager gotchas

Thanks to PlatformIO it is very easy to add further functionality from libraries to the code for ESP8266. When you need to install library, just start Library Manager from ide and type:

pio lib install WiFiManager

PlatformIO will resolve dependencies and download all necessary stuff. Even better option is to add dependency to platformio.ini file:

[env:d1_mini]
platform = espressif8266
board = d1_mini
framework = arduino
lib_deps =
  ArduinoJson
  esp8266_mdns
  PubSubClient
  WiFiManager

PlatformIO will manage the installation after you save the file. That is very neat.

Then new problems occurred when I started with integration of WiFiManager. Do not take me wrong. WiFiManager is very handy library, but you may experience some tricky issues.

The first problem that I hit was that WiFiManager interface was not visible at 192.168.4.1 port 80. ESP was apparently running in AP mode for configuration, but there was no web interface. This issue was caused by this line in my code:

ESP8266WebServer server(80);

I had web server in the main code before I merged the code from WiFiManager. Web server was serving simple REST API for controlling relay. Unfortunately this construct blocked the port so the AutoConnect web server. The server was not able to bind the port. Solution was simple. It was sufficient to instantiate web server after WiFi was working.

The second problem was that AutoConnect from WiFiManager was always turning in AP mode. I was hunting the problem for several hours without any result. One idea was that WiFiManager is not saving the password. That was not true. Other idea was that the memory is corrupted and reformat would help. Unfortunately it didn’t. I gave up.

That solved the problem. Seriously. I gave up and that solved the problem. I let the device running and then ding. It was online. For some strange reason ESP8266 was not able to establish connection with particular WiFi router at first shot. Then it turned on AP mode and after timeout of Config Portal it connected to the WiFi network. Remedy? Just shorten ConfigPortalTimeout:

wifiManager.setConfigPortalTimeout(60);

The third problem was that Config Portal was not displaying information stored as extra custom parameters. I stored there host name of MQTT broker and other options so they won’t be hardcoded. The problem was caused by WiFiManagerParameter constructed in global scope. Issue was similar the first problem with web server.

Solution was to move construction of WiFiManagerParameter to the method after loading configuration values from file config.json stored on file system.

File configFile = SPIFFS.open("/config.json", "r");
...
WiFiManagerParameter custom_mqtt_host("mqtt_host", "MQTT host", configMqttHost, 40);

After resolving these issues WiFiManager is working and it is possible to set values for configuration via Config Portal and there is no need to hardcode them anymore.

Original code is stored at GitHub – LampESP branch v0.1. The new version is at Github – LampESP branch master. I made also small refactoring and the functionality was divided into smaller files which resembles modules for better code maintenance.

1. October 2016

Siriel 03 – Instantiate Prefab from C# in Unity

I was playing with idea to extend the game functionality by adding multi-player support early on. There is very nice tutorial Unite 2014 – New Unity Networking in 5.x., but I was missing one detail. How was Sean Riley able to instantiate game object from prefab. I always ended with some kind of exception or failure.

After several attempts to determine the root cause of my problem I stumbled upon this video “28.Unity Prefabs, Instantiate – Unity C# Scripting Tutorial Beginners” – from Charger Games. I was watching very closely and replayed the sequence several times to find the trick.

Here is whole process in slow motion.

1. Create Prefab from some game object. In my case I will focus on instantiating a pear.

2016-10-01-01-prefab

2. Create Empty Game Object and add component Script in C#.

2016-10-01-02-new-game-object

3. Open the script in editor.

using UnityEngine;
using System.Collections;

public class LevelControllerScript : MonoBehaviour {

    void Start () {
        
    }
	
    void Update () {

    }
}

4. Define public GameObject, save the code.

using UnityEngine;
using System.Collections;

public class LevelControllerScript : MonoBehaviour {

    public GameObject pear;

    void Start () {
        
    }
	
    void Update () {

    }
}

5. Go back to Unity Editor and watch the magic. :-)

2016-10-01-03-new-attribute

6. Unity parsed the code and updated fields in Inspector panel. Drag you prefab and drop it into the new slot.

2016-10-01-04-drag-and-drop

7. Go back to the code and instantiate it.

using UnityEngine;
using System.Collections;

public class LevelControllerScript : MonoBehaviour {

    public GameObject pear;

    void Start () {
        Instantiate(pear);
    }

    void Update () {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Instantiate(pear);
        }
    }
}

That’s all. It reminds me of Xcode when you had to drag some stuff into sockets to bind it with code.

Here you can test updated version of Siriel.

During publishing this post I discovered issue with Unity that some assets are not properly loaded when switching between build for Desktop and WebGL. Read more at Unity forum about workaround.

23. November 2013

Cppcheck – How to open source code at problematic line in Vim

Cppcheck is useful tool for assesment of C++ code quality. It can diagnose many potential problems.

It’s quite easy to configure Cppcheck to open files at problematic location in your favorite editor.

Here is example how to connect Cppcheck and Vim.

Open Edit – Preferences, select Applications tab, click Add

cppcheck-vim-01

Fill following form.

Name: gvim

Executable (point it to your installation of Vim): C:\Program Files (x86)\Vim\vim74\gvim.exe

Parameters: -f +(line) (file)

Click Ok.

cppcheck-vim-02

Set gvim as default application. Select gvim line and click Set as default.

cppcheck-vim-03

Double click any warning or error message and Vim should open at problematic line.

cppcheck-vim-04

17. November 2013

How to build sample applications from Adobe Illustrator SDK CC by Microsoft Visual Studio 2013 Express

Let’s try to build sample applications from Adobe Illustrator SDK CC with Express version of Visual Studio.

Adobe Illustrator SDK is available at: http://www.adobe.com/devnet/illustrator/sdk.html

In readme file Adobe explicitly states requirement that you should use Microsoft Visual C++ 10 (Visual Studio 2010 SP1). Hm.

Unzip directory with SDK and go to samples directory. Let’s start with LiveDropShadow sample.

Double click LiveDropShadow.vcxproj to open project in Visual Studio 2013. Hit F7 to build the project.

You’ll get error message:

Error 1 error MSB8020: The build tools for Visual Studio 2010 (Platform Toolset = ‘v100’) cannot be found. To build using the v100 build tools, please install Visual Studio 2010 build tools.  Alternatively, you may upgrade to the current Visual Studio tools by selecting the Project menu or right-click the solution, and then selecting “Upgrade Solution…”. C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.Cpp.Platform.targets

illustrator-wrong-target

Go to menu Project and select Retarget solution:

illustrator-retarget-project

This action converts project into project for VS 2013. Hit F7 for build.

After several seconds compilation fails and you’ll get another error message:

Error 20 error RC1015: cannot open include file ‘afxres.h’. C:\idea\Adobe Illustrator CC SDK\samplecode\LiveDropShadow\Resources\LiveDropShadow.rc 26 1 LiveDropShadow

illustrator-visualstudio

Double click error message and you’ll see problematic code.

illustrator-problematic-code-01

Problematic is include of afxres.h. It is reference to MFC library which is not part of Visual Studio Express 2013 edition. MFC is available only in Professional version. Do not worry. For many plugins you do not need MFC.

You can disable this include. There is also another problem few lines below with language code. We can disable this line of code for time being.

illustrator-problematic-code-02Hit F7. You’ll get error message that points into VersionInfo.rc file. There are several defines referencing MFC. You can disable those line for time being. (FILEFLAGMASK, FILEOS, FILETYPE, FILESUBTYPE)

illustrator-problematic-code-03

Hit F7 and now you’ll get AIP package :)

illustrator-visualstudio-success-build

Open Illustrator and configure path to Additional Plug-ins folder. Click Edit – Preferences – Plug-ins & Scratch Disks and set path to the folder where Visual Studio produced that aip file. It will be in directory Adobe Illustrator CC SDK\samplecode\output\win….

illustrator-preferences

Click OK, restart Illustrator.

Tadaaa, plug-in is working:

illustrator-working-01

Result:

illustrator-working-02

For more information about plug-ins read getting-started-guide.pdf document in SDK directory docs\guides. :-)

 

15. December 2011

How to define C++ macro with string content and pass it to MSbuild

Imagine that we have C++ project e.g. for Visual Studio 2008. It is possible to build this project just by msbuild command:

msbuild MyProject.vcproj /p:Configuration="Release"

Let say that we want to use #define in the source code. It is necessary to define it in Configuration Properties > C++ > Command Line:

/DSIMPLE_DEFINE

This just pass SIMPLE_DEFINE as flag.

How to deal with string define which should behave like string? E.g.:

#define URL "https://georgik.rocks"

The trick is in escaping quotes. We can add following define to Command Line:

/DURL=\"https://georgik.rocks\"

It will transform into .vcproj file:

AdditionalOptions="/DURL=\"https://georgik.rocks\""

Let’s make one more step.

How to acquire such a define from environment variable? E.g. with following build.bat file:

set URL="https://georgik.rocks"
msbuild MyProject.vcproj /p:Configuration="Release"

It requires only small modification of .vcproj file:

AdditionalOptions="/DURL=\"$(URL)\""

;-)

Small recap of flow: set env variable – pass it to XML – pass it compiler – pass it to code