Howto write float sensor state to uart

Hi

I need to write sensor values to my serial port (for an usecase where not wifi is possible).

I can write test using

- uart.write: 'Hello World'

but

- uart.write: !lambda
                  return id(temperature).state;

wont work:

src/main.cpp:140:27: error: could not convert ‘temperature->esphome::sensor::Sensor::state’ from ‘float’ to ‘std::vector’

Where can I find a sprintf function or something similar to just write the float to uart.


My whole configuration:

esphome:
  name: bluetooth_tracker
  platform: ESP32
  board: nodemcu-32s

esp32_ble_tracker:
    
sensor:
  - platform: xiaomi_cgg1
    mac_address: xxxx
    temperature:
      name: "Xiaomi CGG1 Temperature"
      id: temperature
      on_value:
        - uart.write: 'Hello World'
        - uart.write: !lambda  
                          return id(temperature).state;
        - uart.write: '\r\n'
    humidity:
      name: "Xiaomi CGG1 Humidity"
    battery_level:
      name: "Xiaomi CGG1 Battery Level"
 
logger:

uart:
  baud_rate: 115200 
  tx_pin: GPIO1
  rx_pin: GPIO3

I found a solution myself

  on_value:
    - uart.write: !lambda  
                      char buf[128];
                      sprintf(buf, "Temperature: %.1f degrees \n", id(temperature).state);
                      std::string s = buf;
                      return std::vector<unsigned char>( s.begin(), s.end() );
5 Likes

@BenjaminS - thank you for this!

Helped me in a project :slight_smile:

Please help with a similar problem. I need to send a text value (not a static message). I did the following:

       - uart.write: !lambda  
            char buf[128];
            sprintf(buf, id(serial_command).state);
            std::string s = buf;
            return std::vector<unsigned char>( s.begin(), s.end() );

When I try to compile I get the following error:

Compiling /data/test1/.pioenvs/test1/src/main.cpp.o
/config/esphome/test1.yaml: In lambda function:
/config/esphome/test1.yaml:90:51: error: cannot convert 'std::string' {aka 'std::__cxx11::basic_string<char>'} to 'const char*'
   90 |         - uart.write: !lambda
      |                                                   ^    
      |                                                   |
      |                                                   std::string {aka std::__cxx11::basic_string<char>}

Sorry if it is a silly question… I have 30 years+ experience in assembler programming for critical applications, but low to zero experience with C++ or Yaml. These are very new for me :smiley:

@mitu : I think your problem is this line:
sprintf(buf, id(serial_command).state);
Second expected param should be the format of the string (as a constant), but you provided a string itself.
My opinion the right one should be:
sprintf(buf, "%s", id(serial_command).state);