I think I’m the dummy. Forgot the dummy.
Some of the data:
[00:10:35][D][uart_debug:114]: <<< FE:04:02:05:04:AF:B7
[00:10:37][D][uart_debug:114]: <<< FE:04:02:04:E5:6E:6F
[00:10:54][D][uart_debug:114]: <<< FE:04:02:04:94:AE:4B
[00:11:20][D][uart_debug:114]: <<< FE:04:02:06:E2:2E:CD
etc...
1 Like
Hooray!
With your help and the reference to the previous topic with a similar question, I managed to get it working to your approach! I also used ChatGPT to explain some of the operators and figuring out which bytes did represent the PPM value (I did not see the pattern in the sensor’s datasheet before lol). I still need to check if I need the code to be more solid, but with the bare minimum it works already. E.g. logging the size of the message did not seem to work properly, but I guess it’s not reallly helpful either. I’m super thankful to you!
uart:
tx_pin: GPIO15
rx_pin: GPIO13
baud_rate: 9600
debug:
direction: RX
dummy_receiver: true
after:
delimiter: "\r\n"
sequence:
- lambda: |-
UARTDebug::log_hex(direction, bytes, ',');
if (direction == UART_DIRECTION_RX)
{
if (bytes[0] == 0xFE && bytes[1] == 0x04)
{
int ppm = (bytes[3] << 8) | bytes[4];
id(PPM_sensor).publish_state(ppm);
}
}
sensor:
- platform: template
name: "PPM"
id: PPM_sensor
device_class: carbon_dioxide
state_class: measurement
unit_of_measurement: "ppm"
1 Like
Nice one.
I think adding a check for the message length may be a good idea.
It’s possible that other messages might come through (perhaps relating to the automatic calibration etc), and not processing those might be a good idea.
You’d just want to parse ones of length= 7.
So adding in this check:
if (bytes.size() == 7) // Check number of bytes
1 Like
Fair point, I’m going to try and add this check.
The line for checking the size in your example did not seem to work though. It only returned %d in the logs. I was expecting it to return the actual size.
ESP_LOGD("custom", "Bytes size: %d", bytes.size());
Hmm right. Not sure what’s going on there from top of head and no longer easy for me to check.
I think the size check probably works ok even if there’s something wrong with the logging statement.
1 Like
Right now I’m not using the ESP_LOGD line, only checking if (bytes.size() == 7), and that works! When I make it another number, data comes in, but doesn’t get published to the sensor. Again, thank you so much for your help!
Relevant code for reference:
logger:
baud_rate: 0
uart:
tx_pin: GPIO15
rx_pin: GPIO13
baud_rate: 9600
debug:
direction: RX
dummy_receiver: true
after:
delimiter: "\r\n"
sequence:
- lambda: |-
UARTDebug::log_hex(direction, bytes, ',');
if (direction == UART_DIRECTION_RX)
{
if (bytes.size() == 7)
{
if (bytes[0] == 0xFE && bytes[1] == 0x04)
{
int ppm = (bytes[3] << 8) | bytes[4];
id(PPM_sensor).publish_state(ppm);
}
}
}
sensor:
- platform: template
name: "PPM"
id: PPM_sensor
device_class: carbon_dioxide
state_class: measurement
accuracy_decimals: 0
unit_of_measurement: "ppm"
update_interval: 3s
1 Like
As a small clean-up you shouldn’t need the tx pin there now…
1 Like
Hehe true. It kept flooding the logs with a warning though, hence why it is there. But indeed, it may leave now.
A bit off topic, is there a similar ‘workaround’ to listen only on a I²C line that you know of?
1 Like
Not that I’m aware of. I have a bit more experience with uart.
1 Like