Using a suitable cluster and attribute for the battery voltage help (CON-1295)
I am creating an application for the ESP32-C6. One of the functions is to monitor the connected battery voltage through a GPIO pin and ADC, and update a matter attribute which can be read from a client such as chip-tool.
I am trying to use the electrical_power_measurement cluster and its voltage attribute for this as follows :
// During initializiation
electrical_power_measurement::config power_meas_config;
esp_matter::cluster_t *power_meas_cluster = electrical_power_measurement::create(endpoint, &power_meas_config, CLUSTER_FLAG_SERVER, electrical_power_measurement::feature::direct_current::get_id()
| electrical_power_measurement::feature::alternating_current::get_id());
// Then called periodically from a separate thread
void read_bat_voltage()
{
ESP_LOGI(TAG, "Reading voltage");
ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN0, &adc_raw[0][0]));
ESP_LOGI(TAG, "ADC%d Channel[%d] Raw Data: %d", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, adc_raw[0][0]);
if (do_calibration1_chan0)
{
ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_chan0_handle, adc_raw[0][0], &voltage[0][0]));
ESP_LOGI(TAG, "ADC%d Channel[%d] Calibrated Voltage: %d mV", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, voltage[0][0]);
}
esp_matter_attr_val_t voltageVal;
voltageVal.type = ESP_MATTER_VAL_TYPE_INT64;
// Dummy value to test at first
voltageVal.val.i64 = 33;
//voltageVal.val.i32 = voltage[0][0];
// This fails!!
attribute::update(light_endpoint_id,
chip::app::Clusters::ElectricalPowerMeasurement::Id,
chip::app::Clusters::ElectricalPowerMeasurement::Attributes::Voltage::Id, &voltageVal);
}
On trying to update he attribute as above, I get the following runtime error and crash. Any idea what is wrong here? Thanks in advance.
[0;32mI (2294) app_main: Reading voltage[0m
[0;32mI (2294) app_main: ADC1 Channel[2] Raw Data: 593[0m
[0;32mI (2304) app_main: ADC1 Channel[2] Calibrated Voltage: 582 mV[0m
[0;32mI (2314) chip[ZCL]: 0x421475e8 ep 1 clus 0x0000_0090 attr 0x0000_0004 not supported[0m
[0;31mE (2314) esp_matter_attribute: Error updating Endpoint 0x0001's Cluster 0x00000090's Attribute 0x00000004 to matter: 0x86[0m
[5n[6n
abort() was called at PC 0x420add5f on core 0
Core 0 register dump:
MEPC : 0x408004b4 RA : 0x4080d1ea SP : 0x4082fb70 GP : 0x408152f0
TP : 0x407ef1c8 T0 : 0x37363534 T1 : 0x7271706f T2 : 0x33323130
S0/FP : 0x4082fbac S1 : 0x4082fbac A0 : 0x4082fbac A1 : 0x4082fb8e
A2 : 0x00000000 A3 : 0x4082fbd9 A4 : 0x00000001 A5 : 0x4082b000
A6 : 0x00000000 A7 : 0x76757473 S2 : 0x4082fb90 S3 : 0x00000001
S4 : 0x4082b000 S5 : 0x00000000 S6 : 0x00000000 S7 : 0x00000000
S8 : 0x00000000 S9 : 0x00000000 S10 : 0x00000000 S11 : 0x00000000
T3 : 0x6e6d6c6b T4 : 0x6a696867 T5 : 0x66656463 T6 : 0x62613938
MSTATUS : 0x00001881 MTVEC : 0x40800001 MCAUSE : 0x00000007 MTVAL : 0x00000000
MHARTID : 0x00000000
Stack memory:
4082fb70: 0x40847ac8 0x408472c4 0x4082fbac 0x408139d0 0x4082b000 0x4082b000 0x00000000 0x20000030
4082fb90: 0x61303234 0x66356464 0x00000800 0x4081672c 0x4082fb90 0x40816748 0x4082fb8c 0x726f6261
4082fbb0: 0x20292874 0x20736177 0x6c6c6163 0x61206465 0x43502074 0x34783020 0x64613032 0x20663564
4082fbd0: 0x63206e6f 0x2065726f 0x00000030 0x00000000 0x40836054 0x4083555c 0x42143000 0x420add62
4082fbf0: 0x40836054 0x4083555c 0x4082b000 0x420add8c 0x40836054 0x4083555c 0x42143000 0x4200850a
4082fc10: 0xa5a5a5a5 0xa5a5a5a5 0x408322b0 0x408321b0 0x0000008e 0x00000000 0x00000000 0x00000000
4082fc30: 0x00000000 0x00000000 0xa5a5a5a5 0xa5a5a5a5 0x000003ce 0xa5a5a5a5 0x40845b64 0x00000000
4082fc50: 0x00190004 0x80008000 0x00000001 0x00000000 0x0000000a 0x00000032 0x00000009 0x00000c00
4082fc70: 0x0
@pavel808 two things,
- Use chip lock when you try to update the attribute.
- You cannot update the attribute before the matter starts.
@pavel808 two things,
- Use chip lock when you try to update the attribute.
- You cannot update the attribute before the matter starts.
@jadhavrohit924 Thanks for your reply.
I am updating the attribute after the Matter starts. Just before I attempt to update that Voltage attribute, I update a Temperature attribute as below and it works fine.
float tsens_value;
ESP_ERROR_CHECK(temperature_sensor_get_celsius(temp_sensor, &tsens_value));
ESP_LOGI(TAG, "Temperature value %.02f ℃", tsens_value);
esp_matter_attr_val_t valtemp;
valtemp.type = ESP_MATTER_VAL_TYPE_FLOAT;
valtemp.val.f = tsens_value;
attribute::update(light_endpoint_id,
chip::app::Clusters::TemperatureMeasurement::Id,
chip::app::Clusters::TemperatureMeasurement::Attributes::MeasuredValue::Id, &valtemp);
How to use chip lock exactly?
I have a suspicion that the power_meas_config here is not correct in my case to pass to the function to create the electrical_power_measurement cluster ?
electrical_power_measurement::config power_meas_config;
esp_matter::cluster_t *power_meas_cluster = electrical_power_measurement::create(endpoint, &power_meas_config, CLUSTER_FLAG_SERVER, electrical_power_measurement::feature::direct_current::get_id()
| electrical_power_measurement::feature::alternating_current::get_id());
@pavel808 Please provide me the backtrace of the crash in the file.
@pavel808 Please provide me the backtrace of the crash in the file.
Hi @jadhavrohit924 . Attached are my logs from the application, with multiple crashes. Thanks.
There is no backtrace in the logs!!! Please redirect the crash to either uart or partition and generate the backtrace using https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/core_dump.html.
There is no backtrace in the logs!!! Please redirect the crash to either uart or partition and generate the backtrace using https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/core_dump.html.
@jadhavrohit924 Ah yes. Attached is my core dump file. The crash was re-directed over UART. Thanks.
core-dump.log
@pavel808 The core dump you shared is encrypted. The one having ELF can only decrypt it. You can use the command idf.py coredump-info to decrypt, please take the help of the above docs.
Did you make any changes on top of any standard esp-matter example app? If you do, can you please share it with me to debug.
@pavel808 The core dump you shared is encrypted. The one having ELF can only decrypt it. You can use the command
idf.py coredump-infoto decrypt, please take the help of the above docs.Did you make any changes on top of any standard esp-matter example app? If you do, can you please share it with me to debug.
@jadhavrohit924 Apologies. Here is the decoded core dump file attached. I have made changes to an esp-matter example app. I took the light example more or less and customized it. Everything is working fine up to the point where I try to update that Voltage attribute.
I have attached my app_main.cpp file also (I had to change the extension type here as cpp files are not permitted). Thank you.
Hi @pavel808, the crash is caused by using a different thread to update the attribute. If you join the thread you can avoid the crash.
I think the problem is that you are updating the cluster attribute 0x90 (electricalpowermeasurement) with endpoint 1 (which corresponds to light). You have to use the electrical_power_measurement endpoint (I think it's 2)
It is an error when copying the example code from light, in the line:
attribute::update(light_endpoint_id,
chip::app::Clusters::ElectricalPowerMeasurement::Id,
chip::app::Clusters::ElectricalPowerMeasurement::Attributes::Voltage::Id, &voltageVal);
light_endpoint_id change to electrical_power_measurenment_endpoint_id
where electrical_power_measurenment_endpoint_id is the variable that saves the end point of the created cluster
@JoseAntonioMG If you check the app_main attached above, @pavel808 has created only one endpoint and added the ElectricalPowerMeasurement cluster on endpoint 1 only. Please correct me if I'm wrong.
Hi @pavel808, the crash is caused by using a different thread to update the attribute. If you join the thread you can avoid the crash.
Indeed you are right. The main thread wasn't waiting for the other thread :-/. The crash is no longer there. Thanks.
@JoseAntonioMG If you check the app_main attached above, @pavel808 has created only one endpoint and added the
ElectricalPowerMeasurementcluster onendpoint 1only. Please correct me if I'm wrong.
@jadhavrohit924 @JoseAntonioMG
Exactly. I am only using one endpoint here and don't want to use more.
Some code is emitted here , but basically, what i'm trying to do :
endpoint_t *endpoint = extended_color_light::create(node, &light_config, ENDPOINT_FLAG_NONE, light_handle);
uint16_t light_endpoint_id;
light_endpoint_id = endpoint::get_id(endpoint);
esp_matter::cluster_t *power_meas_cluster = electrical_power_measurement::create(endpoint, &power_meas_config, CLUSTER_FLAG_SERVER, electrical_power_measurement::feature::direct_current::get_id()
| electrical_power_measurement::feature::alternating_current::get_id());
Then from another separate thread later after things are set up :
esp_matter_attr_val_t voltageVal;
voltageVal.type = ESP_MATTER_VAL_TYPE_INT64;
// Dummy value to test
voltageVal.val.i64 = 33;
attribute::update(light_endpoint_id,
chip::app::Clusters::ElectricalPowerMeasurement::Id,
chip::app::Clusters::ElectricalPowerMeasurement::Attributes::Voltage::Id, &voltageVal);
Now I get that the attribute is not supported : ?
[0;32mI (1416922) chip[ZCL]: 0x421477fc ep 1 clus 0x0000_0090 attr 0x0000_0004 not supported[0m
[0;31mE (1416932) esp_matter_attribute: Error updating Endpoint 0x0001's Cluster 0x00000090's Attribute 0x00000004 to matter: 0x86[0m
@pavel808 Looks like you have not created a Voltage attribute. It is optional in Matter Spec so you have to create it in your application.
Also, you have used the wrong attribute_type here, the correct attribute type of Voltage is ESP_MATTER_VAL_TYPE_NULLABLE_INT64.
@pavel808 Looks like you have not created a Voltage attribute. It is optional in Matter Spec so you have to create it in your application. Also, you have used the wrong attribute_type here, the correct attribute type of Voltage is
ESP_MATTER_VAL_TYPE_NULLABLE_INT64.
Hi @jadhavrohit924 I'm not sure if I understand fully. The Voltage attribute is there in Attributes.h :
namespace ElectricalPowerMeasurement {
namespace Attributes {
//.....................................................................................
namespace Voltage {
static constexpr AttributeId Id = 0x00000004;
} // namespace Voltage
//--------------------------------------
}
}
@pavel808 The above code is from connectedhomeip, right? If you are using ESP-Matter SDK, you have to create attributes/commands/events that are optional in Matter Specification that you need in your application. ESP-Matter only creates mandatory things by default. Please take a look at esp-matter-componets for better understanding.
@pavel808 The above code is from connectedhomeip, right? If you are using ESP-Matter SDK, you have to create attributes/commands/events that are optional in Matter Specification that you need in your application. ESP-Matter only creates mandatory things by default. Please take a look at esp-matter-componets for better understanding.
@jadhavrohit924 Yes, that code was from connectedhomeip. Ah ok I understand now.
I have successfully managed to create a new attribute for the electricalpowermeasurement cluster. What i'm doing is as follows :
// On initialization
attribute_t *voltage_attribute;
static const uint32_t voltage_attribute_id = 0x50;
esp_matter::cluster_t *power_meas_cluster = electrical_power_measurement::create(endpoint, &power_meas_config, CLUSTER_FLAG_SERVER, electrical_power_measurement::feature::direct_current::get_id()
| electrical_power_measurement::feature::alternating_current::get_id());
voltage_attribute = attribute::create(power_meas_cluster, voltage_attribute_id, ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_WRITABLE, esp_matter_nullable_int32(0));
// Then later when data is getting updated
esp_matter_attr_val_t voltageVal;
voltageVal.type = ESP_MATTER_VAL_TYPE_NULLABLE_INT32;
voltageVal.val.i32 = 99; // Just a dummy value to test
attribute::update(light_endpoint_id,
chip::app::Clusters::ElectricalPowerMeasurement::Id,
voltage_attribute_id, &voltageVal);
I try to read the attribute using chip-tool as follows :
chip-tool electricalpowermeasurement read-by-id 0x50 0x7000 0x1
However, I get the following error in the response that it doesn't know how to log the attribute.
Endpoint: 1 Cluster: 0x0000_0090 Attribute 0x0000_0050 DataVersion: 1128848908
[1724957685.730063][74763:74765] CHIP:TOO: Don't know how to log atribute value
[1724957685.730148][74763:74765] CHIP:EM: <<< [E:42615i S:481 M:135825630 (Ack:86179102)] (S) Msg TX to 1:0000000000007000 [1650] [UDP:[fd09:26b8:c42f:1:e1cf:ce38:a687:97e8]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck)
I believe that I am still missing something, not sure what, but almost there. Many thanks for your help.
To create a new voltage attribute, you have to do it like this:
int64_t Voltage = 0; electrical_power_measurement::attribute::create_voltage(power_meas_cluster, Voltage);
@pavel808 Can you close this if the issue is resolved?