2016-12-29

Flash ESP8266-12/12E

Steps to flash new firmware:
  1. (optional) Backup flash
    esptool.py --port port-of-esp8266 --baud 115200 read_flash 0x000 4194304 fw_backup.bin
  2. Erase flash
    esptool.py --port port-of-esp8266 --baud 115200 erase_flash
  3. Write esp init data (see SDK Init Data)
    esptool.py --port port-of-esp8266 --baud 115200 write_flash 0x3fc000 esp_init_data_default.bin
  4. Write firmware
    esptool.py --port port-of-esp8266 --baud 115200 write_flash 0x0000 fw.bin

2016-04-10

ESP-01 + DHT22: Send data to influxdb

My first ESP-01 "system" is running now. It measures temperature and humidity using a DHT22 every 20 seconds and send the data to an influxdb database.


The influxdb is then used by a Grafana instance where I define a panel for the temperature and humidity. Here are the first measurements:


Looks like there where a glitch at about 12:30 - I will have a look how often this happen.
And here is the corresponding ESP code:

2016-04-07

First Steps with ESP-01 on OS X El Capitan - Part 2

In part 1 I described how I setup my my environment. In this part I will show my first lua programming steps with the ESP8266 using the Lua based NodeMCU firmware.

First I create an init script (init.lua). This will be loaded by the firmware after each boot/restart.
As last step in the boot/restart process the firmware loads and executes the script init.lua (you can see a corresponding error message in the last screenshot in part 1).
It is recommended to provide an opportunity to interrupt the execution of init.lua to be able to change anything. Otherwise it may happen e.g. if your code contains a fatal error which cause a reboot that you are unable to deactivate/fix the code - and finally have to reflash the firmware to be break the loop.

I'm looking around an found a post about Methods of Interrupting init.lua during boot. My init.lua code based mainly on the ideas described there. But here it is:
  1. it calls firmwareInfo() to output information about the firmware. For the moment it just inform if it is a FLOAT or INTEGER version
  2. after a delay of BootTimeout ms (to give the NodeMCU some time to initialize it self) init() is called
  3. in init() the serial port is initialized and configured to watch for a transmitted ENTER key
  4. if an ENTER is received the function abort() is called, which set the abortFlag to true.
  5. After AbortTimeoutms startup() is called. There the abortFlag is checked and the startup is canceled or executed by trying to load and execute 'user.lua'
The output of such a run without interrupt is shown below:


Next step was to wrote a script to read out a DHT22 sensor. The user_dht22.lua script shown below reads temperature and humidity every 2 sec and prints both values. Depending on the used firmware the output is generated using different format and in case of integer also further values.

Output running the script

2016-03-29

First Steps with ESP-01 on OS X El Capitan

Environment: MacBook Pro Mid 2010, OS X El Capitan 10.11.4
ESP-01 Module + Simple DIY Dev Board (based on this)

  1. Install esptool to backup/change/update ESP8266 firmware
    1. Clone git repository https://github.com/themadinventor/esptool
      $ git clone https://github.com/themadinventor/esptool.git
      Cloning into 'esptool'...
      ...
      
    2. cd esptool
    3. run install routine
      $ sudo python setup.py install
      Password:
      running install
      ...
      Installing esptool.py script to /usr/local/bin
      
  2. Connect ESP8266 ESP-01 Board via CH340G Converter to MBP
    1. Install CH340G driver (WCH provides a signed driver)
    2. Identify the tty port
      $ ls /dev/tty.w*
      /dev/tty.wchusbserial410
    3. activate ESP boot loader (needs to be repeat before each esptool command) by reset ESP and pull GPIO 0 to GND meanwhile.
    4. Check communication
      $ esptool.py --port /dev/tty.wchusbserial410 --baud 115200 flash_id
      Connecting...
      Manufacturer: c8
      Device: 4013
      
      $ esptool.py --port /dev/tty.wchusbserial410 --baud 115200 chip_id
      Connecting...
      Chip ID: 0x009b82bc
      
      
  3. (optional) make a backup of the original firmware - takes about 48sec
    $ time esptool.py --port /dev/tty.wchusbserial410 --baud 115200 
    read_flash 0x000 524288 fw_backup.bin
    Connecting...
    Please wait...
    
    real 0m47.721s
    user 0m0.762s
    sys 0m0.344s
    
    (Note: ESP12-E has a bigger flash - 4MB = 4194304)
  4. Flash alternative firmware - I want to give NodeMCU firmware a try
    1. Use standard NodeMCU firmware (download from github) or
    2. Config your own customized NodeMCU firmware 
    3. Get the download links (integer and float version) about 2min later (you can also use the preconfigured
    4. Flash it to the ESP-01 (I start with the integer version)
      $ time esptool.py --port /dev/tty.wchusbserial410 --baud 115200 
      write_flash 0x00000 nodemcu-master-9-modules-2016-03-29-19-22-38-integer.bin
      Connecting...
      Erasing flash...
      Took 1.22s to erase flash block
      Wrote 403456 bytes at 0x00000000 in 48.2 seconds (66.9 kbit/s)...
      
      Leaving...
      
      real 0m50.195s
      user 0m0.383s
      sys 0m0.126s
      
  5. Connect to ESP. I use SerialTools (AppStore Link) - Note: Baud Rate is 76800

2016-03-10

2016-01-10

Setup/Configuration for another Magic Mirror

Note: Unfortunately, a glitch from the TV, which sometimes occurred before, seems now to be manifested. The TV doesn't power on anymore, neither using remote control nor buttons. I couldn't find a faulty component on TV circuit board. I will/have to stop this project. However, I have learned a lot, so it was not wasted time. 

General setup

  • Raspberry PI 2
  • SEG ArtColor TV 
  • PIR module (GPIO 17, 18), IR transmitter (GPIO 4)
The PIR module will detect motion. If a motion is sense the TV will be switched on via the IR transmitter (simulation of IR remote). After a predefined timeout periode without further motion the TV will switched off (to standby).

Install and enable lirc

  • install lirc
    sudo apt-get install lirc
  • enable lirc module - edit /boot/config.txt
    dtoverlay=lirc-rpi,gpio_out_pin=4,gpio_in_pin=22
  • configure lirc - edit /etc/lirc/hardware.conf
    LIRCD_ARGS=""
    ...
    DRIVER="default"
    DEVICE="/dev/lirc0"
    MODULES="lirc_rpi"
    

Setup IR command to power on/off the TV

  • learn IR command
    irrecord -d /dev/lirc0 ~/lircd.conf
  • copy new file
    sudo cp ~/lircd.conf /etc/lirc/lircd.conf
  • edit the name parameter in /etc/lirc/lircd.conf I choose magicmirror
  • start lirc
    pi@mamomami /etc/lirc $ sudo /etc/init.d/lirc start
    [ ok ] Loading LIRC modules:.
    [ ok ] Starting remote control daemon(s) : LIRC :.
  • check if IR command is available
    pi@mamomami /etc/lirc $ irsend LIST "magicmirror" ""
    irsend: 00000000000043bc KEY_POWER
    
  • run lirc service on start up
    sudo update-rc.d lirc defaults

2016-01-08

Ansible: using numbered backreference followed by digit in lineinfile

While playing around with Ansible I've stumbled over a problem with backreferences followed by a digit.

The problem

I've want to modify some lines in a file like this:
# an example
something=xxxx
Lets assume I want to update the xxxx with some values.

A possible ansible playbook may look as follows:
---
- hosts: localhost
  tasks:
  - name: create file
    copy: src=./demo dest=/tmp/demo

  - name: update xxxx
    lineinfile:
      dest: /tmp/demo
      regexp: '^(.*)xxxx'
      line:   '\1{{ansible_date_time.year}}'
      backrefs: yes
      state: present

The update task "update xxxx" should inspect the file, search for the line with "xxxx" and replace the "xxxx" while keeping the part in front of it.
But the result is:
# an example
P16

The problem is that the backreference \1 is not resolved as expected but merged with (some) of the year digits. This results in the "P".

Solution

To solve it you have to use named groups. A named group is defined by (?P<name>pattern) and can than be reference with \g<1> or \g<name>

The following playbook shows all three variants.
---
- hosts: localhost
  tasks:
  - name: create file
    copy: src=./demo dest=/tmp/demo

  # not working as expected
  - name: update xxxx
    lineinfile:
      dest: /tmp/demo
      regexp: '^(.*)xxxx'
      line:   '\1{{ansible_date_time.year}}'
      backrefs: yes
      state: present

  - name: update yyyy
    lineinfile:
      dest: /tmp/demo
      regexp: '^(?P.*)yyyy'
      line:   '\g<1>{{ansible_date_time.year}}'
      backrefs: yes
      state: present

  - name: update zzzz
    lineinfile:
      dest: /tmp/demo
      regexp: '^(?P.*)zzzz'
      line:   '\g{{ansible_date_time.year}}'
      backrefs: yes
      state: present
For the example file
# an example
simple backref=xxxx
group backref with number=yyyy
group backref with name=zzzz
the generated output is:
# an example
P16
group backref with number=2016
group backref with name=2016