Skip to content

Custom sensors

You can add up to 3 user defined sensors. Insert your sensor's payload scheme in sensor.cpp. The following exampls show how to add a custom temperature and humidty sensor.

  1. Add variables or needed libraries
  2. Add sensor specific code to sensor_init in sensor.cpp
  3. Add sensor specific code to sensor_read function in sensor.cpp
  4. Add Payload functions to payload.h and payload.cpp (Optional)
  5. Use payload functions in sensor.cpp to send sensor data

Example 1: Custom Temperature and Humidity Sensor GY-21

To use a custom sensor you first have to enable the Sensor which you want to use. For this you have to edit or add HAS_SENSOR_1 in either the paxcounter.conf or the hal file of your board.

shared/paxcounter_orig.conf
#define HAS_SENSOR_1 1
shared/paxcounter_orig.conf
#define HAS_SENSOR_2 1
shared/paxcounter_orig.conf
#define HAS_SENSOR_3 1

You might also add a constant for your custom sensor in the paxcounter.conf file. This is optional but can be used to identify the sensor type.

shared/paxcounter_orig.conf
#define HAS_GY21 1 // (1)
  1. See usage of this in the example below

1. Add variables or needed libraries

If you want to use any libary for you custom sensor you have to add it to the platformio.ini file.

In this example we use the HTU2xD_SHT2x_Si70xx for the GY-21 sensor.

platformio.ini
[env:usb] # (1)
upload_protocol = esptool
lib_deps = # (2)
    ${common.lib_deps_all}
    https://github.com/enjoyneering/HTU2xD_SHT2x_Si70xx.git
  1. Selected the env you want to use. In this example we use the usb env.
  2. Add the libary to the lib_deps section.

Add the import of libary in the sensor.cpp file.

sensor.cpp
5
6
7
8
9
#if (HAS_GY21) // (1)
#include <HTU2xD_SHT2x_Si70xx.h>
HTU2xD_SHT2x_SI70xx ht2x(HTU2xD_SENSOR, HUMD_12BIT_TEMP_14BIT); // sensor type, resolution
double temperature, humidity;
#endif // HAS_GY21
  1. Define HAS_GY21 either in hal file of your board or in paxcounter.conf file.

2. Add sensor specific code to sensor_init function

src/sensor.cpp
1
2
3
4
5
6
7
8
9
#if (HAS_GY21) // (1)
if (ht2x.begin() != true) // reset sensor, set heater off, set resolution, check power
                          // (sensor doesn't operate correctly if VDD < +2.25v)
{
    ESP_LOGE(TAG, "HTU2xD/SHT2x not connected, fail or VDD < +2.25v");
} else {
    ESP_LOGE(TAG, "HTU2xD/SHT2x/GY21 found");
}
#endif // HAS_GY21
  1. Define HAS_GY21 either in hal file of your board or in paxcounter.conf file.

3. Add sensor specific code to sensor_read function

In this case we choose that our custom sensor is Sensor 3. This means the data will be sent on SENSOR3PORT which is by default 12. You can change this in the paxcounter.conf file.

src/sensor.cpp
  case 3:
    #if (HAS_GY21)
    ESP_LOGE(TAG, "Reading Sensor 3, GY21"); // (1)
    temperature =
        ht2x.readTemperature(); // accuracy +-0.3C in range 0C..60C at  14-bit
    delay(100);
    humidity =
        ht2x.readHumidity(); // accuracy +-2% in range 20%..80%/25C at 12-bit
    ESP_LOGE(TAG, "GY21: Temperature: %f", temperature); // (2)
    ESP_LOGE(TAG, "GY21: Humidity: %f", humidity); // (3)
    #endif // HAS_GY21
    break;
  1. These logs are only for debugging. You can remove them if you want.
  2. These logs are only for debugging. You can remove them if you want.
  3. These logs are only for debugging. You can remove them if you want.

4. Payload functions for a custom sensor

If you have added your custom sensor code as described before you can also add custom payload function if you need others than the provided ones. For this you have to change two files. First you have to add your payload function to the payload.h file.

src/payload.h
void addTempHum(float temperature, float humidity);

Then you have to add your payload function to the payload.cpp file. You can provide functions for all payload formates (see Payload Formats) or just add it for the one you are using.

Example for a custom temperature / humidity payload function

src/payload.cpp
void PayloadConvert::addTempHum(float temperature, float humidity) {
int16_t temperature = (int16_t)(temperature); // float -> int
uint16_t humidity = (uint16_t)(humidity);     // float -> int
buffer[cursor++] = highByte(temperature);
buffer[cursor++] = lowByte(temperature);
buffer[cursor++] = highByte(humidity);
buffer[cursor++] = lowByte(humidity);
}
src/payload.cpp
void PayloadConvert::addTempHum(float temperature, float humidity) {
writeFloat(temperature);
writeFloat(humidity);
}
src/payload.cpp
void PayloadConvert::addTempHum(float temperature, float humidity) {
// data value conversions to meet cayenne data type definition
// 0.1°C per bit => -3276,7 .. +3276,7 °C
int16_t temp = temperature * 10;
// 0.5% per bit => 0 .. 128 %C
uint16_t hum = humidity * 2;
#if (PAYLOAD_ENCODER == 3)
buffer[cursor++] = LPP_TEMPERATURE_CHANNEL;
#endif
buffer[cursor++] = LPP_TEMPERATURE; // 2 bytes 0.1 °C Signed MSB
buffer[cursor++] = highByte(temperature);
buffer[cursor++] = lowByte(temperature);
#if (PAYLOAD_ENCODER == 3)
buffer[cursor++] = LPP_HUMIDITY_CHANNEL;
#endif
buffer[cursor++] = LPP_HUMIDITY; // 1 byte 0.5 % Unsigned
buffer[cursor++] = humidity;
}

5. Sending the data

After you have added your custom sensor code and payload function you can send the data. For this you have to add the following code to the sensor.cpp file.

src/sensor.cpp
  case 3:
    #if (HAS_GY21)
    ESP_LOGE(TAG, "Reading Sensor 3, GY21");
    temperature =
        ht2x.readTemperature(); // accuracy +-0.3C in range 0C..60C at  14-bit
    delay(100);
    humidity =
        ht2x.readHumidity(); // accuracy +-2% in range 20%..80%/25C at 12-bit
    ESP_LOGE(TAG, "GY21: Temperature: %f", temperature);
    ESP_LOGE(TAG, "GY21: Humidity: %f", humidity);
    payload.addTempHum(temperature, humidity); // (1)
    #endif // HAS_GY21
    break;
  1. Add your custom payload function here.

Now you can build and upload the code to your ESP. Do not forget to erase the flash before uploading since you probably changed the paxcounter.conf file.