Closed nadrog closed 2 years ago
Based on your description, the sensor library you're using is probably performing the read operation in a blocking fashion. If each read operation takes, say, 500 ms, and you're blocking the program execution for that duration, then it's quite obvious that you're not going to be able to read more than a couple of sensors per second.
See if you can read the sensor or the library in a continuous or async mode. That would resolve your problem.
Also: SystemHz works exactly as intended in this case.
Thanks Matti, I understand it now.
Could you please help me with how the code should look like? I understand I have two options:
bme680.readTemperature()
and embedd them like described in example async_repeat_sensor.cppbme680.beginReading()
and then take values from bme680 using bme680.temperature
after reading (which takes cca 200ms) is doneI was trying to follow example in async_repeat_sensor.cpp but failed. This is what I came up with:
auto read_temperature_callback = [](RepeatSensor<float>* sensor) {
app.onDelay( 0, [sensor]() { sensor->emit(bme680.readTemperature() + 273.15); });
};
auto* bme680_temperature = new RepeatSensor<float>(read_interval, read_temperature_callback);
bme680_temperature->connect_to(new SKOutputFloat("sensorDevice.SailorHat.bme680.temperature","","K"));
but I have the same issue.
Help appreciated. Thanks!
You can't use sync calls unless you're calling them in separate FreeRTOS Tasks, but that's a much more complex topic. All ReactESP reactions are still in the same thread, so if you're making a blocking call anywhere, it'll block the whole program execution. But you're already close with your code. Something like this should work:
auto read_temperature_callback = [](RepeatSensor<float>* sensor) {
bme680.beginReading();
app.onDelay(300, [sensor]() { sensor->emit(bme680.temperature + 273.15); });
};
auto* bme680_temperature = new RepeatSensor<float>(read_interval, read_temperature_callback);
bme680_temperature->connect_to(new SKOutputFloat("sensorDevice.SailorHat.bme680.temperature","","K"));
What happens there is that RepeatSensor calls the callback function every read_interval
seconds. The callback first triggers the reading and then fires off a delay reaction, calling sensor->emit(...)
after a 300 ms delay. All individual calls should return quickly, so you should be still getting good performance.
Thanks for the clarification! At the end, my code looks like this:
auto read_temperature_callback = [](RepeatSensor<float>* sensor) {
bme680.beginReading();
app.onDelay(2 * bme680.remainingReadingMillis(), [sensor]() {
bme680.endReading();
sensor->emit(bme680.temperature + 273.15);
});
};
auto* bme680_temperature = new RepeatSensor<float>(read_interval, read_temperature_callback);
bme680_temperature->connect_to(new SKOutputFloat("sensorDevice.SailorHat.bme680.temperature","","K"));
and systemHz is cca 160k with 4 sensors.
Since all 4 values in the physical sensor are read at the same time, would you have any suggestion for improvement so that I could call begin/endReading just once and then somehow emit 4 separate values?
Since all 4 values in the physical sensor are read at the same time, would you have any suggestion for improvement so that I could call begin/endReading just once and then somehow emit 4 separate values?
Yes, that can be done. Instead of using RepeatSensor, use an onRepeat reaction to trigger the readings and write the results to ObservableValues. Here's an example with two values:
// either instantiate these outside of `setup()` or on the heap (with `new`)
ObservableValue<float> temp1;
ObservableValue<float> temp2;
app.onRepeat(read_interval, []() {
bme680.beginReading();
app.onDelay(2 * bme680.remainingReadingMillis(), [sensor]() {
bme680.endReading();
temp1 = bme680.temperature + 273.15;
temp2 = bme680.temperature2 + 273.15;
});
};
temp1->connect_to(new SKOutputFloat("sensorDevice.SailorHat.bme680.temperature1","","K"));
temp2->connect_to(new SKOutputFloat("sensorDevice.SailorHat.bme680.temperature2","","K"));
Not sure how you'd actually read multiple values with the BME680 library, but you get the point.
Since the original misunderstanding got cleared out, I'm closing this issue. If you have further questions on how to use SensESP, don't hesitate to ask on the GitHub repo discussions or on the Slack channel!
I'm running SensESP 2.1.1 on a SailorHAT that is using ESP32-WROOM-32D. According to documentation, the ESP32 "clock frequency is adjustable from 80 MHz to 240 MHz", but when I enable_system_hz_sensor(), the values I receive depend on the number of RepeatSensors and can be as low as in range from 0 to 2. Additionally and more problematically, I'm not able to use more than 3 sensors.
I'm controlling the number of sensors by commenting the code like
auto* bme680_temperature = new RepeatSensor<float>(read_interval, [](){return bme680.readTemperature() + 273.15;}); bme680_temperature->connect_to(new SKOutputFloat("sensorDevice.SailorHat.bme680.temperature","","K"));
[E][WiFiClient.cpp:485] flush(): fail on fd 63, errno: 11, "No more processes"
during attempt to initiate websocket which is after successful initial handshake with the server.I'm using Adafruit BME680 Library@^2.0.1 and signalk/SensESP@^2.1.1.
Debug output:
(connect)(C1) WSClient websocket connect attempt (state=0) (connect)(C1) Initiating websocket connection with server... (get_mdns_service)(C1) Found server 192.168.1.122 (port 3000) (connect)(C1) Signal K server has been found at address 192.168.1.122:3000 by mDNS. (connect)(C1) Websocket is connecting to Signal K server on address 192.168.1.122:3000 (test_token)(C1) Testing token with url http://192.168.1.122:3000/signalk/ (test_token)(C1) Testing resulted in http status 200 (test_token)(C1) Returned payload (length 255) is: (test_token)(C1) {"endpoints":{"v1":{"version":"1.41.0","signalk-http":"http://192.168.1.122:3000/signalk/v1/api/","signalk-ws":"ws://192.168.1.122:3000/signalk/v1/stream","signalk-tcp":"tcp://192.168.1.122:8375"}},"server":{"id":"signalk-server-node","version":"1.41.0"}} (test_token)(C1) End of payload output (test_token)(C1) Attempting to connect to Signal K Websocket... [E][WiFiClient.cpp:485] flush(): fail on fd 61, errno: 11, "No more processes"
SystemHz.zip