I've been doing simple tests with my new Arduino Oplà.
The code assist in VisualStudioCode revealed there was a units parameter for the getTemperature function.
So, I made a simple sketch that attempted to get the temperature in C and F and write out both on each loop with a delay 1000 on the loop.
The result was that the code would stop executing after the first getTemperature attempt. It didn't matter if I got the temperature in F or C first, it wouldn't do a second attempt at getTemperature.
On a whim, I decided to try adding a delay before I called getTemperature the second time and that actually seemed to work.
Through trial and error I ended up with a minimum delay of 30.
So, part of this post is to point out that calling getTemperature requires delay(30) between subsequent calls in the same loop. Presumably the sensor has to recharge or something along those lines. If this is by design then it should be noted in documentation.
This is a minimal script for testing Env that I was playing with.
If you comment out the line with delay(30) you'll see that the output stops after the farenheit display.
#include <Arduino_MKRIoTCarrier.h>
/** For Arduino Oplà or kits using MKRIoTCarrier
* Minimal sketch to test that Env is working.
*/
MKRIoTCarrier carrier;
void setup()
{
Serial.begin(9600);
carrier.begin();
}
void loop()
{
displayEnvInfo();
delay(1000); // 1 second delay
}
void displayEnvInfo() {
float humidity = carrier.Env.readHumidity();
float temperatureF = carrier.Env.readTemperature(FAHRENHEIT);
Serial.println("Humidity:"+ String(humidity,4)+"%");
Serial.println("Temperature (deg Fahrenheit):"+ String(temperatureF,2));
delay(30);
float temperatureC = carrier.Env.readTemperature(CELSIUS);
Serial.println("Temperature (deg Celsius):"+ String(temperatureC,2));
}
The problem with the delay is that technically there is a F and C value for two different readings rather than the same reading.
I'd recommend a change to the code for Env that allows getting the temperature in celsius (like it does by default) and then provide a function like:
float toFarenheit(float celsiusTemp) { return (1.8 * celsiusTemp) + 32; }
so:
// This is not a current capability
float temperatureC = carrier.Env.readTemperature(); // celsius
float temperatureF = carrier.Env.toFarenheit(temperatureC); // new function
// now temperatureC and temperatureF would reflect the same reading.
I would encourage starting from celsius and converting to farenheit as it is multiplication and addition and should be more performant than division and subtraction required for the reverse operation
Neither the MkrIoTCarrier reference nor ArduinoHTS221 reference nor the ArduinoHTS221.readTemperature pages mention that you can't call the readTemperature function more than once in 30ms. So, at the minimum that should be corrected. If it is in the the HTS221 specification pdf it is too technically dense for me to want to find it in there; and if you are trying to get younger enthusiasts into coding for Arduino this needs to be easier to find.
Alternatively, there could be a polling function that could be called per loop that would check the time vs last polltime and if lastPollTime + 30ms < time grab new values for the temperature and humidity. Then the readTemperature and readHumidity functions could retrieve from the last read values and do any conversions on the fly. That would prevent the crash and it would be harmless to make multiple calls to the read functions.
It should also be noted that rather than simply not working, current behavior causes a silent crash; those are never fun to diagnose.