Skip to content

Commit 81fe32c

Browse files
author
Michael Ruettgers
committed
Merge branch 'release/2.1.4'
2 parents 9c43944 + 7ccd6c6 commit 81fe32c

File tree

11 files changed

+168
-44
lines changed

11 files changed

+168
-44
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
## [2.1.4] - 2020-07-24
10+
### Changed
11+
- Worked on the docs
12+
- Added LED based feedback for SML data recognition
13+
914
## [2.1.3] - 2020-04-17
1015
### Changed
1116
- Added hint to change AP password to the docs

README.md

Lines changed: 137 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -38,74 +38,130 @@ The phototransistor has been fixed with hot glue within the housing.
3838

3939
## Getting started
4040

41-
### Configuration
41+
To get started, the software must first somehow get onto the device.
42+
This can be done in several ways.
43+
44+
### Uploading a precompiled binary
45+
46+
A precompiled binary for the Wemos D1 and configured to have a sensor attached to pin D2 can be downloaded from the releases page on GitHub:
47+
48+
[https://github.com/mruettgers/SMLReader/releases](https://github.com/mruettgers/SMLReader/releases)
49+
50+
#### Flashing
51+
52+
This precompiled binary can be flashed to the device with the help of [esptool.py](https://github.com/espressif/esptool).
53+
Other tools should also work, as long as you have configured them to match the specs of your ESP8266.
54+
55+
```bash
56+
esptool.py --port /dev/ttyUSB0 write_flash -fm dout 0x00000 path/to/smlreader.bin
57+
```
58+
59+
As a docker enthusiast I prefer to utilize a dockerized version of esptool.py by bind-mounting the current working directory to `/src` and assuming that `smlreader.bin` is existing in the current working directory:
60+
```bash
61+
docker run -it --device /dev/ttyUSB0 -v $(pwd):/src --rm mruettgers/esptool --port /dev/ttyUSB0 write_flash -fm dout 0x00000 /src/smlreader.bin
62+
```
63+
64+
The device path and the path to the binary have to be adjusted to fit your needs.
65+
66+
67+
##### Example
68+
69+
```bash
70+
nb-ubuntu ➜ ~/Downloads ls SMLReader_D1mini_v2.1.3.bin
71+
SMLReader_D1mini_v2.1.3.bin
72+
73+
nb-ubuntu ➜ ~/Downloads docker run -it --device=/dev/ttyUSB0 -v $(pwd):/src --rm mruettgers/esptool --port /dev/ttyUSB0 write_flash -fm dout 0x00000 /src/SMLReader_D1mini_v2.1.3.bin
74+
esptool.py v2.8
75+
Serial port /dev/ttyUSB0
76+
Connecting....
77+
Detecting chip type... ESP8266
78+
Chip is ESP8266EX
79+
Features: WiFi
80+
Crystal is 26MHz
81+
MAC: d8:f1:5b:07:0d:eb
82+
Uploading stub...
83+
Running stub...
84+
Stub running...
85+
Configuring flash size...
86+
Auto-detected Flash size: 4MB
87+
Flash params set to 0x0340
88+
Compressed 378528 bytes to 266738...
89+
Wrote 378528 bytes (266738 compressed) at 0x00000000 in 23.6 seconds (effective 128.1 kbit/s)...
90+
Hash of data verified.
91+
92+
Leaving...
93+
Hard resetting via RTS pin...
94+
```
95+
96+
---
97+
98+
### Using your IDE for building and flashing
99+
100+
You should be able to use your preferred IDE to build and flash SMLReader if you take care of the dependencies and the build flags configured in the `platform.io` file.
101+
I strongly recommend using PlatformIO as it takes care of that itself.
102+
103+
#### Configuration
42104

43105
The configuration of the reading heads is done by editing `src/config.h` and adjusting `SENSOR_CONFIGS` (see below).
44106

45107
```c++
46108
static const SensorConfig SENSOR_CONFIGS[] = {
47-
{.pin = D2, // GPIO Pin
109+
{.pin = D2, // GPIO pin of the phototransistor
48110
.name = "1", // Sensor name used in MQTT topic
49-
.numeric_only = false // If "true", only numeric values are being published via MQTT
111+
.numeric_only = false, // If "true", only numeric values are being published via MQTT
112+
.status_led_enabled = true, // Flash status LED (3 times) when an SML start sequence has been found
113+
.status_led_inverted = true, // Some LEDs (like the ESP8266 builtin LED) require an inverted output signal
114+
.status_led_pin = LED_BUILTIN // GPIO pin used for sensor status LED
50115
},
51116
{.pin = D5,
52117
.name = "2",
53-
.numeric_only = false
118+
.numeric_only = false,
119+
.status_led_enabled = true,
120+
.status_led_inverted = true,
121+
.status_led_pin = LED_BUILTIN
54122
},
55123
{.pin = D6,
56-
.name = "3",
57-
.numeric_only = false
124+
.name = "3",
125+
.numeric_only = false,
126+
.status_led_enabled = true,
127+
.status_led_inverted = true,
128+
.status_led_pin = LED_BUILTIN
58129
}
59130
};
60131
```
61132
*Attention: Multi-sensor support is experimental and has not been tested due to the lack of multiple meters. For testing purposes I connected one reading head to multiple GPIO pins of my WeMos D1 mini.*
62133

63-
WiFi and MQTT are configured via the web interface provided by [IotWebConf](https://github.com/prampec/IotWebConf) and which can be reached after joining the WiFi network named SMLReader and heading to http://192.168.4.1.
64-
If the device has already been configured, the web interface can be reached via the IP address obtained from your local network's DHCP server.
65-
66-
*Attention: You have to change the AP Password (empty by default), otherwise SMLReader won't work.*
67-
68-
---
69-
70-
### Flashing
71-
72-
There are several ways to flash SMLReader to your ESP8266.
73-
I personally prefer the docker way using my dockerized version of esptool.py.
74134

75-
#### IDE
135+
#### Building
76136

77-
You should be able to use your preferred IDE to build and flash SMLReader if you take care of the dependencies and the build flags configured in the `platform.io` file.
78-
I strongly recommend using PlatformIO as it takes care of that itself.
137+
Building SMLReader in PlatformIO is straight forward and can be done by executing the build task matching your environment (i.e. `d1_mini`).
79138

80-
#### esptool.py
139+
In case you get the following error, it is time to install a Git client (https://git-scm.com/downloads) and to make sure that the path to `git` is covered by the PATH variable and `git` is thus executable from everywhere.
81140

82-
###### Flashing
83-
```bash
84-
docker run -it --device /dev/ttyUSB0 -v $(pwd):/src --rm mruettgers/esptool ash -c "esptool --port /dev/ttyUSB0 write_flash -fm dout 0x00000 /src/smlreader.bin"
141+
```
142+
UserSideException: Please install Git client from https://git-scm.com/downloads:
143+
File "/home/monty/.platformio/penv/lib/python3.8/site-packages/platformio/builder/main.py", line 168:
144+
env.SConscript("$BUILD_SCRIPT")
85145
```
86146

87-
Of couse you can flash the image without the use of docker by directily utilizing your local copy of esptool.py:
147+
![Building with PlatformIO](doc/screenshots/screenshot_platformio_build.png)
88148

89-
```bash
90-
esptool.py --port /dev/ttyUSB0 write_flash -fm dout 0x00000 ./smlreader.bin
91-
```
92149

93-
###### Flashing with serial port monitor
94-
```bash
95-
docker run -it --device /dev/ttyUSB0 -v $(pwd):/src --rm mruettgers/esptool ash -c "esptool --port /dev/ttyUSB0 write_flash -fm dout 0x00000 /src/smlreader.bin && miniterm.py /dev/ttyUSB0 115200"
96-
```
150+
#### Flashing
97151

98-
###### Serial port monitor
99-
```bash
100-
docker run -it --device /dev/ttyUSB0 -v $(pwd):/src --rm mruettgers/esptool ash -c "miniterm.py /dev/ttyUSB0 115200"
101-
```
152+
![Flashing with PlatformIO](doc/screenshots/screenshot_platformio_upload.png)
102153

103154
---
104155

105156

106157
### Running
107158

108-
If everything is configured properly and running with a sensor in place, SMLReader will publish the metrics and values received from the meter to the configured MQTT broker:
159+
WiFi and MQTT are configured via the web interface provided by [IotWebConf](https://github.com/prampec/IotWebConf) and which can be reached after joining the WiFi network named SMLReader and heading to http://192.168.4.1.
160+
If the device has already been configured, the web interface can be reached via the IP address obtained from your local network's DHCP server.
161+
162+
*Attention: You have to change the AP Password (empty by default), otherwise SMLReader won't work.*
163+
164+
If everything is configured properly and running with a sensor in place, SMLReader will publish the metrics and values received from the meter to the configured MQTT broker:
109165

110166
```
111167
MB-Monty ➜ ~ mosquitto_sub -h 10.4.32.103 -v -t smartmeter/mains/#
@@ -140,7 +196,49 @@ smartmeter/mains/sensor/3/obis/1-0:16.7.0*255/value 451.2
140196

141197
### Debugging
142198

143-
Verbose serial logging can be enabled by setting `SERIAL_DEBUG_VERBOSE=true` in the `platformio.ini` file.
199+
Serial logging can be enabled by setting `SERIAL_DEBUG=true` in the `platformio.ini` file before building.
200+
To increase the log level and to get the raw SML data, also set `SERIAL_DEBUG_VERBOSE=true`.
201+
202+
#### Serial port monitor
203+
204+
A serial port monitor can be attached using the corresponding function of your IDE or by invoking a terminal client like `miniterm` which comes shipped with `python-serial`.
205+
The serial port settings are `115200,8,N,1`.
206+
207+
##### miniterm.py
208+
209+
```bash
210+
miniterm /dev/ttyUSB0 115200
211+
```
212+
213+
###### Example
214+
215+
```bash
216+
nb-ubuntu ➜ ~/Downloads miniterm /dev/ttyUSB0 115200
217+
--- Miniterm on /dev/ttyUSB0 115200,8,N,1 ---
218+
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
219+
Config size: 685
220+
Wrong config version.
221+
AP password was not set in configuration
222+
State changing from: 0 to 1
223+
Setting up AP: SMLReader
224+
With default password: <hidden>
225+
AP IP address: 192.168.4.1
226+
State changed from: 0 to 1
227+
...
228+
```
229+
230+
Or the dockerized way:
231+
232+
```bash
233+
docker run -it --device /dev/ttyUSB0 -v $(pwd):/src --rm mruettgers/esptool ash -c "miniterm.py /dev/ttyUSB0 115200"
234+
```
235+
236+
237+
238+
##### PlatformIO
239+
240+
![PlatformIO Monitor](doc/screenshots/screenshot_platformio_upload_and_monitor.png)
241+
144242

145243

146244
---
@@ -153,6 +251,7 @@ Verbose serial logging can be enabled by setting `SERIAL_DEBUG_VERBOSE=true` in
153251
* [MicroDebug](https://github.com/rlogiacco/MicroDebug)
154252
* [MQTT](https://github.com/256dpi/arduino-mqtt)
155253
* [libSML](https://github.com/volkszaehler/libsml)
254+
* [JLed](https://github.com/jandelgado/jled)
156255

157256
### Links
158257

doc/assets/SMLReader_Schema.png

-9.2 KB
Loading
190 KB
Loading
199 KB
Loading
237 KB
Loading

doc/src/SMLReader.fzz

1.9 KB
Binary file not shown.

platformio.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ lib_deps =
1616
MicroDebug
1717
IotWebConf
1818
MQTT
19+
jled
1920

2021
env_default = d1_mini
2122
build_flags =

src/Sensor.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define SENSOR_H
33

44
#include <SoftwareSerial.h>
5+
#include <jled.h>
56
#include "debug.h"
67

78
// SML constants
@@ -26,6 +27,9 @@ class SensorConfig
2627
const uint8_t pin;
2728
const char *name;
2829
const bool numeric_only;
30+
const bool status_led_enabled;
31+
const bool status_led_inverted;
32+
const uint8_t status_led_pin;
2933
};
3034

3135
class Sensor
@@ -43,13 +47,24 @@ class Sensor
4347
this->serial->enableRx(true);
4448
DEBUG("Initialized sensor %s.", this->config->name);
4549

50+
if (this->config->status_led_enabled) {
51+
this->status_led = new JLed(this->config->status_led_pin);
52+
if (this->config->status_led_inverted) {
53+
this->status_led->LowActive();
54+
}
55+
}
56+
4657
this->init_state();
4758
}
4859

4960
void loop()
5061
{
5162
this->run_current_state();
5263
yield();
64+
if (this->config->status_led_enabled) {
65+
this->status_led->Update();
66+
yield();
67+
}
5368
}
5469

5570
private:
@@ -61,6 +76,7 @@ class Sensor
6176
uint8_t loop_counter = 0;
6277
State state = INIT;
6378
void (*callback)(byte *buffer, size_t len, Sensor *sensor) = NULL;
79+
JLed *status_led;
6480

6581
void run_current_state()
6682
{
@@ -101,6 +117,7 @@ class Sensor
101117
return this->serial->read();
102118
}
103119

120+
104121
// Set state
105122
void set_state(State new_state)
106123
{
@@ -155,6 +172,9 @@ class Sensor
155172
{
156173
// Start sequence has been found
157174
DEBUG("Start sequence found.");
175+
if (this->config->status_led_enabled) {
176+
this->status_led->Blink(50,50).Repeat(3);
177+
}
158178
this->set_state(READ_MESSAGE);
159179
return;
160180
}

src/config.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,22 @@
44
#include "Arduino.h"
55
#include "Sensor.h"
66

7-
const char *VERSION = "2.1.3";
7+
const char *VERSION = "2.1.4";
88

99
// Modifying the config version will probably cause a loss of the existig configuration.
1010
// Be careful!
1111
const char *CONFIG_VERSION = "1.0.2";
1212

13-
const uint8_t STATUS_PIN = LED_BUILTIN;
14-
1513
const char *WIFI_AP_SSID = "SMLReader";
1614
const char *WIFI_AP_DEFAULT_PASSWORD = "";
1715

1816
static const SensorConfig SENSOR_CONFIGS[] = {
1917
{.pin = D2,
2018
.name = "1",
21-
.numeric_only = false}};
19+
.numeric_only = false,
20+
.status_led_enabled = true,
21+
.status_led_inverted = true,
22+
.status_led_pin = LED_BUILTIN}};
2223

2324
const uint8_t NUM_OF_SENSORS = sizeof(SENSOR_CONFIGS) / sizeof(SensorConfig);
2425

0 commit comments

Comments
 (0)