RobTillaart/SHT85

Demo fails to compile

Closed this issue · 23 comments

None of the demos that I tried managed to compile e.g.
examples/SHT85_demo_plotter/SHT85_demo_plotter.ino

I'm using the esp32->Lolin Wemos D1 Mini, - if I set to Arduino Uno it compiles

I tried various permutations of including Wire.h and attempting to include code from the SHT31_SW library, but nothing I tried worked.

Note ... you don't need a board to repeat this - simply setting the board type makes it fail to compile

Note that the SHT31_SW library demos fail to compile on either Arduino Uno or Lolin Wemos D1 Mini see RobTillaart/SHT31_SW#14

I'll do some research and see if I can figure out what is going on, but since I haven't used I2C (or TwoWire or Softwire) I'm not sure where to start.

/private/var/folders/h7/r6nsnp591vq9t17_q33mks_c0000gn/T/.arduinoIDE-unsaved2024820-15193-1hk34uu.tyqqf/sketch_sep20a/sketch_sep20a.ino:18:29: error: invalid conversion from 'int' to 'TwoWire*' [-fpermissive]
   18 | #define SHT85_ADDRESS       0x44
      |                             ^~~~
      |                             |
      |                             int
/private/var/folders/h7/r6nsnp591vq9t17_q33mks_c0000gn/T/.arduinoIDE-unsaved2024820-15193-1hk34uu.tyqqf/sketch_sep20a/sketch_sep20a.ino:27:11: note: in expansion of macro 'SHT85_ADDRESS'
   27 | SHT85 sht(SHT85_ADDRESS);
      |           ^~~~~~~~~~~~~
In file included from /private/var/folders/h7/r6nsnp591vq9t17_q33mks_c0000gn/T/.arduinoIDE-unsaved2024820-15193-1hk34uu.tyqqf/sketch_sep20a/sketch_sep20a.ino:16:
/Users/mitra/Documents/Arduino/libraries/SHT85/SHT85.h:184:18: note:   initializing argument 1 of 'SHT85::SHT85(TwoWire*)'
  184 |   SHT85(TwoWire *wire = &Wire);
      |         ~~~~~~~~~^~~~~~~~~~~~

exit status 1

Compilation error: invalid conversion from 'int' to 'TwoWire*' [-fpermissive]

@mitra42
This sounds like a bug I had in a few other libraries too, good you found it
The cause is that the Arduino interface differs slightly over platforms.

Will create a develop branch asap with a fix. Give me half an hour.
Can you do a verification with HW as I have no Lolin nearby.

If you patch the example sketch

#define SHT85_ADDRESS ((uint8_t)0x44)

I'm using the esp32->Lolin Wemos D1 Mini,

I do not have that one in my boards set, need to install it (takes some extra time).

Created a develop branch with a minimal patch.
Build-CI has started,
If you have time please try this develop branch.

@mitra42

/Users/mitra/Documents/Arduino/libraries/SHT85/SHT85.h:184:18: ...
184 | SHT85(TwoWire *wire = &Wire);

Which version of the library did you test with?
As my constructor definition in SHT85.h (0.6.0) does not have that version.
(Looks like 0.5.x version or earlier)

From 0.6.0 SHT85.h

class SHT85 : public SHT
{
public:
  SHT85(uint8_t address, TwoWire *wire = &Wire);

  //  catch incorrect calls with an address, only 0x44 allowed, see #19
  bool begin();

  //  EXPERIMENTAL for 0.4.1
  uint32_t GetSerialNumber();
};

@mitra42
BUild-CI was successfull - https://github.com/RobTillaart/SHT85/actions/runs/10960803780

Ran for these platforms - uno, m4, esp32, esp8266, rpipico

So please download the develop branch and check if the fixes work for you.

Sorry for slow response - we must be on opposite timezones (I'm currently in Bali). I'm not sure if it was clear but I'm using the Arduino IDE.

To add new boards - on the Arduino IDE - I've got "http://arduino.esp8266.com/stable/package_esp8266com_index.json" in Settings->Additional Board Manager

The Arduino IDE currently has v0.5.1 of SHT85, there doesn't seem to be a way to manually make it update libraries. I seem to remember it prompts me at launch when there are any needing updating - so I dont' know where in the process the 0.6.0 version is, but I think you've figured out it needs an update anyway.

Similarly - not sure how to use you dev branch - I know how to clone the repo and access that branch, I'm just not clear how to get that dev version into the Arduino IDE so I can do a meaningful test.

Anyway ... more poking around, and I realize what I was doing wrong was using your example from the current master branch of the repo with the v0.5.1 library, rather than using the demo under the "..." in the library manager.
The 0.5.1 demo uses a constructor like

SHT85 sht;

while the current master uses a constructor like

SHT85 sht(SHT85_ADDRESS);

I'm not sure if the interface has changed, or if its just now also demonstrating an ability to change the address .

I hope this wasn't a false alarm ... but I'd be glad to know if you have a quick pointer how to force it to use your 0.6.x and.or how to best test a specific branch of a library so I can be more helpful in future.

Goodmorning,
No need to apologize, I'm in the Netherlands (~9:00 AM at the moment) so indeed almost opposite time zones.

There was indeed an interface changed from 0.5.1 to 0.6.0.
The address parameter moved from begin() to the constructor, as changing addresses runtime would imply that the internal state of the SHTxx object could possibly not reflect the actual state of the device.

I'm going to do some additional tests today with the Lolin selected. So maybe the 0.6.1 version is not needed.

to be continued.

@mitra42

You stated that the library manager did not see a 0.6.0 version, so I looked into that
It appeared to be a failed update to 0.6.0 for whatever reason, so I'm gonna fix the 0.6.0 release first.

@mitra42

Released the 0.6.0 version, so it should appear in the library manager, normally within 8 hrs or so.

Ran the build-CI twice and all looks stable.

Please update an check if the LOLIN WEMOS D1 still fails. Here the examples compile for LOLIN WEMOS D1.

Let me know if there are still problems after the update, then I can look into them.

I can confirm that 0.6.0 is appearing in the IDE and compiles.

I can't test it - since my sense is a SHT30 and the demos don't compile if you just naively change the constructor.
Specifically with SHT30 sht(SHT85_ADDRESS); it complains

   41 |   uint32_t ser = sht.GetSerialNumber();
      |                      ^~~~~~~~~~~~~~~
Compilation error: 'class SHT30' has no member named 'GetSerialNumber'

If I comment out that line, then it compiles, however it generates a strange result

�������������������������SHT85_demo.ino
SHT_LIB_VERSION: 	0.6.0
FFFF
	0.19	-45.0	0.0
	0.17	-45.0	0.0

and the result is the same whether the sensor shield is plugged in or not. I have no other way to know if the sensor shield is working - its the first time I've tried it. So the problem could be my end.

Getting it compiled is a step forward,👍

  1. Only the SHT85 class implements the getSerialNumber(), the SHT3x version do not support a serial number.

  2. I have to look into the demo code to see.

Do you have a link to the sensor shield you are using?
It might be an address issue.

@mitra42
Can you run this test sketch?
It uses both the possible addresses of the SHT30

//    FILE: .ino
//  AUTHOR: Rob Tillaart
// VERSION: 0.2.0
//    DATE:
// PURPOSE:
//     URL:

#include "Arduino.h"
#include "SHT85.h"

uint32_t start;
uint32_t stop;

SHT30 sht1(0x44);
SHT30 sht2(0x45);

void setup()
{
  Serial.begin(115200);
  Serial.println();
  Serial.println(__FILE__);
  Serial.print("SHT_LIB_VERSION: \t");
  Serial.println(SHT_LIB_VERSION);

  Wire.begin();
  Wire.setClock(100000);
  sht1.begin();
  sht2.begin();

  Serial.println("\nCONNECT");
  Serial.println(sht1.isConnected());
  Serial.println(sht2.isConnected());

  Serial.println("\nSTATUS");
  uint16_t stat = sht1.readStatus();
  Serial.print(stat, HEX);
  Serial.println();
  stat = sht2.readStatus();
  Serial.print(stat, HEX);
  Serial.println();

  delay(1000);
}


void loop()
{
  start = micros();
  sht1.read();         //  default = true/fast       slow = false
  stop = micros();
  Serial.print("SHT1:\t");
  Serial.print((stop - start) * 0.001);
  Serial.print("\t");
  Serial.print(sht1.getTemperature(), 1);
  Serial.print("\t");
  Serial.println(sht1.getHumidity(), 1);
  delay(100);

  start = micros();
  sht2.read();         //  default = true/fast       slow = false
  stop = micros();
  Serial.print("SHT2:\t");
  Serial.print((stop - start) * 0.001);
  Serial.print("\t");
  Serial.print(sht2.getTemperature(), 1);
  Serial.print("\t");
  Serial.println(sht2.getHumidity(), 1);
  delay(100);
}

OK - got it - the default on the Lolin SHT30 shield is 45 - I can confirm this is working and getting sensible values for temp and humidity if I edit the demo to look like ....

#include "SHT85.h"

#define SHT85_ADDRESS         0x45 // Lolin card is on 45 (unless you solder it) 

uint32_t start;
uint32_t stop;

#define SHTXX SHT30
SHTXX sht(SHT85_ADDRESS);


void setup()
{
  Serial.begin(115200);
  delay(5000); // I find on Lolin D1 mini I need a delay of 5 seconds after serial.begin else it loses the first few lines of output. 

...

#if SHTXX == 85
uint32_t ser = sht.GetSerialNumber();
Serial.print(ser, HEX);
Serial.println();
#endif

I haven't submitted this as a patch, because some of it is specfic to this shield.-

And I confirm that the async demo works with similar changes.

OK good to hear.
As the problem seems solved you may close this issue.

Thanks again for reporting, leading to the missing release!

Thanks - will do - by the way, here is how I'm using it - in a new framework for affordable sensors to support smallholder farmers in poorer countries. https://github.com/mitra42/frugal-iot

Thanks - will do - by the way, here is how I'm using it - in a new framework for affordable sensors to support smallholder farmers in poorer countries. https://github.com/mitra42/frugal-iot

That is a nice project to work on and it is good to see my library used for such project. Feel free to use my other libraries if needed. And if you are missing a library (or functionality) for some sensor, let me know. If time and other resources permit I could write one (under MIT license).

Thanks - I'll look around. I just did some mammoth work on the adaptation of your example - made it work with an array of sensors though I have no way to test that currently (since I'm in the road and just have the one shield with me).

I'll take a look around your libraries.

Is it possible to share your "array version", could be an informative example.
How much devices are in the array?
As there are only two possible addresses by default you need to use some kind of multiplexing?

Sure - its at https://github.com/mitra42/frugal-iot/blob/main/sensor_sht85.cpp , its not a stand-alone demo as it depends on the entire framework, but it should be pretty easy to turn it into one - collapse the ifdef's etc.

One of the TODO's left is to split out the setting up of each Wire and pass an array into this routine, so that you could have 0x44 and 0x45 on each Wire (at least I presume that is possible).

I'm not sure how I2C multiplexing works - I saw you have some libraries for this, but haven't had time to check them out yet.

I'm not sure how I2C multiplexing works - I saw you have some libraries for this, but haven't had time to check them out yet.

The TCA9548 and compatibles are pretty straight forward.
This example shows how to access 3 identical temp sensors with the same address.
These could have been in an array.
The idea is to set the right channel before accessing the sensor of choice.

https://github.com/RobTillaart/TCA9548/blob/master/examples/TCA9548_demo_AM2320/TCA9548_demo_AM2320.ino

As the SHT30 has two possible addresses you can connect two sensors per channel so in total 16 sensors with one TCA9548.

Some code snippet to get the idea for SHT30 in an array with multiplexer

TCA9548 MP(0x70);

//  note the alternating addresses.
SHT30 sht[8] = { SHT30(0x44), SHT30(0x45), SHT30(0x44), SHT30(0x45), SHT30(0x44), SHT30(0x45), SHT30(0x44), SHT30(0x45) };

....

int channel = index / 2;
MP.selectChannel(channel);
SHT[index].read();

//  process read data
Serial.print(index);
Serial.print("\t");
Serial.println(SHT[index].getTemperature());
...