Tasmota: Difference between revisions

From Leo's Notes
This page was last edited on 15 February 2022, at 07:23.
No edit summary
Line 204: Line 204:
====Displays====
====Displays====
All supported displays can be found at https://tasmota.github.io/docs/Displays/#supported-displays. You may need to tweak the Tasmota compile options and rebuild a firmware file for your particular display. Once Tasmota is able to see your display, you should be able to draw or write text to it using the common display commands that are included in Tasmota.
All supported displays can be found at https://tasmota.github.io/docs/Displays/#supported-displays. You may need to tweak the Tasmota compile options and rebuild a firmware file for your particular display. Once Tasmota is able to see your display, you should be able to draw or write text to it using the common display commands that are included in Tasmota.
See also: https://github.com/tasmota/docs/blob/master/docs/Displays.md


===== SSD1306 =====
===== SSD1306 =====
Line 239: Line 241:
Save and restart Tasmota (with <code>Restart 1</code>) and then confirm that the display is working by running <code>Displaytext [zl1c1]hello</code>.
Save and restart Tasmota (with <code>Restart 1</code>) and then confirm that the display is working by running <code>Displaytext [zl1c1]hello</code>.


===== 16x02 LCD display via i2c =====
===== HD44780 LCD display via i2c =====
The 1602 LCD i2c adapter works similarly. Just enable <code>USE_I2C</code>, <code>USE_DISPLAY</code>. Once Tasmota is running, configure it with the following commands.{{Highlight
The HD44780 family of LCD displays, which includes the 1602 LCD display, can be interfaced using a i2c adapter. After connecting the adapter to Tasmota via the i2c bus, you should be able to start drawing text to the display using the Displaytext command.
 
To get started, use the display Tasmotao firmware or compile Tasmota with <code>USE_I2C</code>, <code>USE_DISPLAY</code> options. Configure the display with the following commands:{{Highlight
| code = DisplayAddress 0x27    # the address discovered by i2cscan
| code = DisplayAddress 0x27    # the address discovered by i2cscan
DisplayModel 1          # for LCD display
DisplayModel 1          # for LCD display
Line 248: Line 252:
DisplayMode 0          # enter text mode
DisplayMode 0          # enter text mode
| lang = text
| lang = text
}}
}}The special characters that are available to the HD44780 can be written to by escaping the hex code with tilda. Eg. ~e4 to write the character 0xe4.
 
=====Displaytext commands=====
=====Displaytext commands=====
All text is drawn using the Displaytext command.
All text is drawn using the Displaytext command.
You may have noticed that there are some letters in square brackets passed to the <code>Displaytext</code> command. These are options that control the behavior of where and how the text should be drawn and can control the font size and location of the text. For example, to print "Hello World" across two separate lines, we write hello on line 1 column 1 (<code>l1c1</code>) and world on line 2 column 1 (<code>l2c1</code>):{{Highlight
You may have noticed that there are some letters in square brackets passed to the <code>Displaytext</code> command. These are options that control the behavior of where and how the text should be drawn and can control the font size and location of the text. For example, to print "Hello World" across two separate lines, we write hello on line 1 column 1 (<code>l1c1</code>) and world on line 2 column 1 (<code>l2c1</code>):{{Highlight
| code = Displaytext [l1c1]hello
| code = Displaytext [l1c1]hello
Displaytext [l2c1]world!
Displaytext [l2c1]world!
| lang = terminal
| lang = terminal
}}There are many other parameters which can be found at: https://tasmota.github.io/docs/Displays/#displaytext-use. The most important ones you should know are listed below. You may chain any number of these together and they will run in the order they appear. Eg. <code>[zl1c1f0s1]Hello</code> would clear, then write the world <code>Hello</code> in the smallest font on line 1 column 1 after clearing the screen.
}}There are many other parameters which can be found at: https://tasmota.github.io/docs/Displays/#displaytext-use. The most important ones you should know are listed below. You may chain any number of these together and they will run in the order they appear. Eg. <code>[zl1c1f0s1]Hello</code> would clear, then write the world <code>Hello</code> in the smallest font on line 1 column 1.
{| class="wikitable"
{| class="wikitable"
!Command/parameter
!Command/parameter

Revision as of 07:23, 15 February 2022

Tasmota is an open source firmware for the ESP8266 and ESP32. It is mostly used for home automation devices, but can also be loaded on any other ESP device. It comes with support for a wide range of peripherals 'out of the box' and makes interacting with sensors via WiFi extremely easy as a result.

Flashing Tasmota

Obtain ESPTool and the latest Tasmota binary. Use ESPTool.py to erase and load Tasmota via serial.

ESP8266 (Wemos D1)

Here is what I did to flash a Wemos D1, for example.

$ python -m esptool --port /dev/ttyUSB0  erase_flash                                                                                                                                                                                                                          
esptool.py v3.0                                                                                                                                                                                                                                                                 
Serial port /dev/ttyUSB0                                                                                                                                                                                                                                                        
Connecting....                                                                                                                                                                                                                                                                  
Detecting chip type... ESP8266                                                                                                                                                                                                                                                  
Chip is ESP8266EX                                                                                                                                                                                                                                                               
Features: WiFi                                                                                                                                                                                                                                                                  
Crystal is 26MHz                                                                                                                                                                                                                                                                
MAC: 50:02:91:fe:9d:a4                                                                                                                                                                                                                                                          
Uploading stub...                                                                                                                                                                                                                                                               
Running stub...                                                                                                                                                                                                                                                                 
Stub running...                                                                                                                                                                                                                                                                 
Erasing flash (this may take a while)...                                                                                                                                                                                                                                        
Chip erase completed successfully in 8.6s                                                                                                                                                                                                                                       
Hard resetting via RTS pin...                                                                                                                                                                                                                                                   


$ python -m esptool --port /dev/ttyUSB0 write_flash -fs 1MB -fm dout 0x0 tasmota.bin            
esptool.py v3.0 
Serial port /dev/ttyUSB0  
Connecting....  
Detecting chip type... ESP8266          
Chip is ESP8266EX         
Features: WiFi  
Crystal is 26MHz
MAC: 50:02:91:fe:9d:a4    
Uploading stub...         
Running stub... 
Stub running... 
Configuring flash size... 
Compressed 613568 bytes to 438208...      
Wrote 613568 bytes (438208 compressed) at 0x00000000 in 38.7 seconds (effective 126.8 kbit/s)...      
Hash of data verified.    

Leaving...      
Hard resetting via RTS pin...

ESP32

Download the ESP32 bootloader files from https://github.com/arendst/Tasmota-firmware/tree/main/static/esp32, the latest Tasmota firmware file, and then run:

# esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset \
  write_flash -z --flash_mode dout --flash_freq 40m --flash_size detect \
   0x1000 bootloader_dout_40m.bin \
   0x8000 partitions.bin \
   0xe000 boot_app0.bin \
   0x10000 tasmota32.bin
esptool.py v3.2
Serial port /dev/ttyUSB0
Connecting.....
Chip is ESP32-D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: f0:08:d1:d4:04:48
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Flash will be erased from 0x00001000 to 0x00004fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x0000e000 to 0x0000ffff...
Flash will be erased from 0x00010000 to 0x0015ffff...
Compressed 15536 bytes to 10862...
Wrote 15536 bytes (10862 compressed) at 0x00001000 in 0.3 seconds (effective 397.7 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 129...
Wrote 3072 bytes (129 compressed) at 0x00008000 in 0.0 seconds (effective 588.8 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 47...
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.1 seconds (effective 751.8 kbit/s)...
Hash of data verified.
Compressed 1372432 bytes to 964850...
Wrote 1372432 bytes (964850 compressed) at 0x00010000 in 14.3 seconds (effective 766.9 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

Configuration

After a factory reset, you will need to configure its WiFi settings manually by connecting to the WifiManager created access point. After it connects to the proper network, connect to it again through a web browser.

The following section applies to my own network and setup. For my own network, because the IoT devices are all in its own isolated network, I need to do a SSH tunnel in order to access the web interface. This is done by running: ssh -L 8080:192.168.1.x:80 root@iot-router and then connecting to localhost:8080 in a web browser. In the web interface, there are a few things that needs to be configured in order for it to work properly with the NodeRED/MQTT service outside of the IoT network.

  1. Setup the device template. Remember to check off 'activate' or else the template won't get applied.
  2. Configure MQTT. Set the host as mqtt, port as 1883, topic as the device name, and the prefix as tasmota/%topic%/. The mqtt hostname resolves to the MQTT server and the IoT router allows MQTT traffic on port 1883 to leave the network to this server.

MQTT and hostname

When configuring the Tasmota hostname and MQTT strings, you may substitute variable names. This table outlines what you can use.

Description What you type What you get
%06X 0353C0
last 4 digits of mac %04d
hostname %s
MQTT prefix %prefix% One of: cmnd, stat, tele
MQTT topic %topic% User defined. Eg: WP5-1

Rules

Rules are sets of commands that should run when a specific condition is met. They are a way to program user defined behaviors to Tasmota without requiring a recompile. The ability to write rules allow for interesting behaviors between sensors and peripherals, such as updating an attached display when sensor values change.

Rules are defined within a rule set. Tasmota out of the box has 3 rule sets called rule1, rule2, and rule3. Any number of rules can be placed in each set (though, limited by the device's memory, but the documentation says at least 1000 bytes). Rule sets can be enabled or disabled, which also enables or disables any rules within. This allows for entire behaviors to be enabled or disabled simply by enabling or disabling a rule set.

Quick start with rules

Frequently, we want to do something with a sensor reading. In the case of a CO2 monitor, we could possibly want to update a display when the PPM value changes.

Rule1
  on MHZ19B#CarbonDioxide do DisplayText [zc1l1]%value%ppm endon

Rules are always defined within a rule set and always begin with 'on' and end with 'endon'. In this example, the rule is defined within rule1 and would run DisplayText whenever the sensor's CarbonDioxide metric changes. We can add additional rules within rule1 by appending additional rules as a list. In another example with the INA219, we could write the following rules which will write the voltage, current, and wattage value to a display:

Rule1
  on INA219#Voltage do DisplayText [c1l1]V %value% V endon
  on INA219#Current do DisplayText [c1l2]I %value% A endon
  on INA219#Power do DisplayText [c1l3]P %value% W endon

For the rules to take effect, enable the rule set:

rule1 1

For more complex rules that need to run multiple commands, chain them together with the backlog command. Rules can also enable or disable entire rule sets to enable or disable some behavior. Case in point, from one of my other projects, we could enable and later disable the screen from updating when a button is pressed:

Rule2
  ON button1#state=3 do backlog power1 1; rule1 1 endon
  ON button1#state=10 do backlog rule1 1; power1 1; delay 500; power1 0; rule1 0 endon

Creating a timed auto-off switch

Using rules, we can easily create a switch that will automatically turn itself off after a some time. We can even extend this behavior by having different on-durations based on the number of button presses. The following rules were used to set up a switch that automatically turned the bathroom fan off using the Gosund KS602 smart switch.

rule1
 on button1#state=3 do backlog power1 on; ruletimer1 0; rule1 0; rule2 1 endon
 on button1#State=10 do backlog power1 on; ruletimer1 1800;  rule1 0; rule2 1; delay 10; ledpower1 off; ledstate 1; endon
 on button1#state=11 do backlog power1 on; ruletimer1 3600; rule1 0; rule2 1; delay 10; ledpower1 off; ledpower1 on; ledpower1 off; ledstate 1; endon
 on button1#state=12 do backlog power1 on; ruletimer1 7200; rule1 0; rule2 1; delay 10; ledpower1 off; ledpower1 on; ledpower1 off; ledpower1 on; ledpower1 off; ledstate 1; endon
 on button1#state=13 do backlog power1 on; ruletimer1 14400; rule1 0; rule2 1; delay 10; ledpower1 off; ledpower1 on; ledpower1 off; ledpower1 on; ledpower1 off; ledpower1 on; ledpower1 off; ledstate 1; endon

rule2
 on Rules#Timer=1 do backlog power1 off; rule2 0; rule1 1 endon
 on button1#state do backlog power1 off; ruletimer1 0; rule2 0; rule1 1 endon

rule3
 on system#boot do backlog SetOption73 1; SetOption32 20; switchmode 8 endon

To simplify the logic, I use a simple state machine where rule1 is the off state and rule2 is the on state. When the switch is off, it accepts different number of button presses to select the duration of the on state. The button states are: 3 is for hold, 10 for 1 press, 11 for 2 presses, and so on up to 4 presses. The RuleTimer1 is used to trigger Rule2's timer=1 rule that turns the switch off after a set number of seconds. At the end of each rule, I added a series of LED flashes to show what mode was selected.

Rule3 is used to enforce certain SetOptions on boot (though it should be saved to flash). SwitchMode 8 is required so that only these rules toggle the state of the relay.

Configuring peripherals

There are a different set of supported peripherals out of the box depending on which Tasmota build you used. Refer to the BUILDS page at https://github.com/arendst/Tasmota/blob/development/BUILDS.md to determine if a particular feature is enabled. If it isn't, you will need to compile Tasmota with the desired feature enabled using the users_config_override.h file placed in the Tasmota source directory.

Setting up I2C

Tasmota I2C GPIO Configuration
Tasmota I2C GPIO Configuration for a ESP8266

Some sensors and displays use the I2C protocol which requires 2 wires for data and clock.

The ESP8266 uses GPIO 4 and GPIO 5 while the ESP32 uses GPIO 21 and GPIO 22 for SDA and SCL, respectively. You can set these under the 'Configure Module' page on the web interface.

Save and activate the template. If configured properly, the i2cscan command should return a list of addresses that was found on the I2C bus.

CMD: i2cscan
MQT: tasmota/device/RESULT = {"I2CScan":"Device(s) found at 0x3c 0x40"}

Displays

All supported displays can be found at https://tasmota.github.io/docs/Displays/#supported-displays. You may need to tweak the Tasmota compile options and rebuild a firmware file for your particular display. Once Tasmota is able to see your display, you should be able to draw or write text to it using the common display commands that are included in Tasmota.

See also: https://github.com/tasmota/docs/blob/master/docs/Displays.md

SSD1306

The SSD1306 is an OLED display that comes in various sizes. These displays use I2C. The Wemos D1 OLED module is one such device with a screen size of 64x48. Tasmota supports this display through the tasmota-displays.bin image or you may compile support in by creating a user_config_override.h file with:

#ifndef USE_I2C
#define USE_I2C
#endif

#ifndef USE_DISPLAY
#define USE_DISPLAY
#endif

#ifndef USE_DISPLAY_SSD1306
#define USE_DISPLAY_SSD1306
#endif

After flashing Tasmota with the proper peripheral support, attach the display to the ESP8266 via I2C (GPIOs 4 and 5 for SDA/SCL on the ESP8266, or GPIOs 21 and 22 for SDA/SCL on the ESP32). Once connected, running i2cscan on the console should return the display device at address 0x3c.

05:26:20.151 CMD: i2cscan
05:26:20.173 MQT: tasmota/D1-2/RESULT = {"I2CScan":"Device(s) found at 0x3c"}

Next, configure the display in Tasmota by running:

DisplayAddress 0x3c     # the address discovered by i2cscan
DisplayModel 2          # for SSD1306
DisplayWidth 64         # the display resolution
DisplayHeight 48
DisplayDimmer 100       # turn the display on
DisplayMode 0           # enter text mode

Save and restart Tasmota (with Restart 1) and then confirm that the display is working by running Displaytext [zl1c1]hello.

HD44780 LCD display via i2c

The HD44780 family of LCD displays, which includes the 1602 LCD display, can be interfaced using a i2c adapter. After connecting the adapter to Tasmota via the i2c bus, you should be able to start drawing text to the display using the Displaytext command.

To get started, use the display Tasmotao firmware or compile Tasmota with USE_I2C, USE_DISPLAY options. Configure the display with the following commands:

DisplayAddress 0x27     # the address discovered by i2cscan
DisplayModel 1          # for LCD display
DisplayWidth 16         # the display resolution
DisplayHeight 2
DisplayDimmer 100       # turn the display on
DisplayMode 0           # enter text mode

The special characters that are available to the HD44780 can be written to by escaping the hex code with tilda. Eg. ~e4 to write the character 0xe4.

Displaytext commands

All text is drawn using the Displaytext command.

You may have noticed that there are some letters in square brackets passed to the Displaytext command. These are options that control the behavior of where and how the text should be drawn and can control the font size and location of the text. For example, to print "Hello World" across two separate lines, we write hello on line 1 column 1 (l1c1) and world on line 2 column 1 (l2c1):

Displaytext [l1c1]hello
Displaytext [l2c1]world!

There are many other parameters which can be found at: https://tasmota.github.io/docs/Displays/#displaytext-use. The most important ones you should know are listed below. You may chain any number of these together and they will run in the order they appear. Eg. [zl1c1f0s1]Hello would clear, then write the world Hello in the smallest font on line 1 column 1.

Command/parameter Result Example
l# line (1..) l1
c# column (1..) c1
f# font size (0..) f0
s# font scaling (1..) s1
z clears screen
o / O turns off / on the display

With the power of Tasmota rules, we can trigger text to be written when a state changes. In the case of a CO2 monitor, we can create the following rule which clears and prints the PPM value on the first line of the display whenever the value changes.

Rule1 on MHZ19B#CarbonDioxide do DisplayText [zc1l1]%value%ppm endon
Rule1 1

This rule would print "400ppm" if the CO2 reading was at 400, for example.

For more information, see the rules section above.

INA219

Compile Tasmota with the INA219 sensor enabled by defining the following in the user_config_override.h file:

#ifndef USE_I2C
#define USE_I2C
#endif

#ifndef USE_INA219
#define USE_INA219
#endif

Configure the GPIO pins for I2C as usual. If everything is working, Tasmota should being reporting the read voltage and current from the INA219 in the telemetry messages in addition to it being displayed on the web page. If no values are being reported, run i2cscan and confirm whether the device shows up on the bus and recheck wiring and the I2C GPIO pin configuration.

For my INA219 monitoring board, I also have a SSD1306 display. I use the following rules to show the values on the display. A button is also used to optionally turn the display on temporarily.

Rule1
  on INA219#Voltage do DisplayText [c1l1]V %value% V endon
  on INA219#Current do DisplayText [c1l2]I %value% A endon
  on INA219#Power do DisplayText [c1l3]P %value% W endon
  on ANALOG#A0 do Backlog scale1 %value%, 0, 1024, 0, 5.65; DisplayText [c1l4]B %var1% V endon
Rule1 1

Rule2
  ON button1#state=3 do backlog power1 1; rule1 1 endon
  ON button1#state=10 do backlog rule1 1; power1 1; delay 500;delay 500;delay 500;delay 500;delay 500;delay 500; power1 0; rule1 0 endon
Rule2 1

Rule3
  ON system#boot DO DisplayMode 0; DisplayDimmer 100 endon
Rule3 1

Backlog VoltRes 2; WattRes 2
Backlog ButtonTopic 0;  SetOption73 1; SetOption32 20
Adjusting the shunt resistor to measure higher currents

The INA219 can be adjusted to measure higher currents by changing the shunt resistor. The shunt resistor value can be defined by setting the value to Sensor13 (see: https://github.com/arendst/Tasmota/pull/7803).

To increase the range of the INA219 from the default 3.2A to 6.4A, we could add an additional 0.1Ω resistor in parallel to the existing one which would effectively halve the resistance to 0.05Ω. Update the resistance value in Tasmota by running Sensor13 51. This should automatically save to flash and reboot.

Light Dependent Resistors (LDR) / photoresistors to the ADC input

I had a protoboard with a LDR connected to the ADC. The input range is supposed to be 3.3v (in full darkness) to 0.0v (in full brightness). When selecting the ADC input to ADC Light, the light reading is inverted.

There are 4 values: The type (3 for light), resistor constant, lux scalar, and lux exponent. Out of sheer laziness, I opted to just change the values until I got a value that was reasonable and increases with more light. While doing so, I noticed that the bridge resistor value adjusts the magnitude of the lux reading, the lux scalar adjusts the offset, and the lux exponent adjusts the weight of the input reading.

What seemed to work for me was the ADC param values: adcparam 3,3,10,1.

Compiling

Compile instructions are available at https://tasmota.github.io/docs/Compile-your-build/. The simplest way for me was to use their Docker image which uses platform.io to do the builds. To get started, run:

$ git clone https://github.com/tasmota/docker-tasmota
$ cd docker-tasmota
$ docker build -t docker-tasmota .

$ git clone https://github.com/arendst/Tasmota.git
$ docker run -ti --rm -v $(pwd)/Tasmota:/tasmota -u $UID:$GID docker-tasmota -e tasmota

What you want to build is controlled by the environment (provided by the -e option). A list of all available environments can be found in the platformio.ini file. By default, if no environment is specified, it will build everything for you. For a standard Tasmota firmware, use the tasmota environment.

To include additional drivers (like displays, sensors, etc), edit the tasmota/my_user_config.h file and uncomment (to add) or comment out (to remove) each feature as desired. Be aware that Tasmota groups features together and you may need to enable an entire group of features (eg. displays, power monitoring) for a specific feature to become included.

To compile a ESP32 version, pass in -e tasmota32.

Once the compile is complete, you'll find your firmware under the build_output directory.

Project structure

Peripherals are prefixed in the source tree with xdrv (driver), xdsp (display), xlgt (lights), xnrg (energy), xsns (sensors).

Creating a new sensor driver

See: https://tasmota.github.io/docs/Sensor-API/

After creating the sensor driver file, edit the configurations header file and recompile: