SHT21 on Particle Photon

Hi there,
I’m curious if there is anyone who have successfully connected a SHT21 to the Photon and get a working code?
I’ve seen that someone tried to port the Library from Arduino to the Photon but the code does not work for me. I also tried the SHT1X library but I get wrong values (I get values even if I haven’t connected the SHT21 to the Photon, which is kinda strange).
I am new to the Photon - so maybe someone can help me here :slight_smile:

Have you tried this “library”?
https://gist.github.com/PaulRB/8372742

When I compile this, I get the following error:

example.cpp: In function 'void setup()':
example.cpp:159:5: warning: 'Spark' is deprecated (declared at ../wiring/inc/spark_wiring_cloud.h:271): Spark is now Particle. [-Wdeprecated-declarations]
 void setup() {
     ^
example.cpp:160:5: warning: 'Spark' is deprecated (declared at ../wiring/inc/spark_wiring_cloud.h:271): Spark is now Particle. [-Wdeprecated-declarations]
     
     ^
In file included from ../wiring/inc/spark_wiring.h:48:0,
                 from ./inc/application.h:36,
                 from example.cpp:28:
../wiring/inc/spark_wiring_cloud.h: In instantiation of 'static bool CloudClass::variable(const char*, const T (*)[N], const CloudVariableTypeString&) [with T = char; unsigned int N = 10u]':
example.cpp:159:54:   required from here
../wiring/inc/spark_wiring_cloud.h:115:9: error: static assertion failed: 

Use Particle.variable("name", myVar, STRING); without & in front of myVar


         static_assert(sizeof(T)==0, "\n\nUse Particle.variable(\"name\", myVar, STRING); without & in front of myVar\n\n");
         ^
make[1]: *** [../build/target/user/platform-6example.o] Error 1
make: *** [user] Error 2

There are some errors in that code, but if you use this instead, you should get there

    // original NOT working
    //Spark.variable("temp2", &SHT21Temperature, STRING);
    //Spark.variable("humid", &SHT21humidity, STRING);

    // corrected but deprecated (as warning/error messages suggest)
    //Spark.variable("temp2", SHT21Temperature, STRING);
    //Spark.variable("humid", SHT21humidity, STRING);

    // correct and current way to do it
    Particle.variable("temp2", SHT21Temperature);
    Particle.variable("humid", SHT21humidity);

This actually tells you explicitly what’s wrong :wink:

1 Like

Ah, okay the errors are gone - thank you very much!
But I’m not 100% sure where to connect the SDA and SCK form the SHT21. There are mentioned D7 but nothing else - or connect to SCL/SDA D1/D0?

I2C pins are D0/D1, so they are not explicitly mentiond since the Wire object does all the pin handling for you.

And D7 is used in the code to give visual feedback via the blue onboard LED.

BTW:
Are you using the bare sensor or have you got a breakout board? If the latter, which?
If not, you’ll need to add pull-up resistors to the I2C lines.

Okay, got it. Thank you!

I have a self-made board with pull-ups (5kOhm).

Okay I flashed the application but the Photon breathes green after few seconds - I guess it’s because the code can’t be executed right?
Any tips how to debug the problem?

Edit:
And the blue onboard LED also does not flash - just the regular multicolor LED.

Edit2:
If I comment out these lines:

sprintf(SHT21humidity, "%.1f%%", SHT2x.GetHumidity());
sprintf(SHT21Temperature, "%.1fC", SHT2x.GetTemperature());

I see the blue LED blinking…so I guess the error is somewhere in the functions.

There used to be an issue with the impkementation of Wire which could lead to what you are seeing.
Could you check if you are targeting 0.4.9 system version?

To debug you could add some Serial.print() statements inside the library code

e.g. inside SHT2x.cpp this function might give you headaches

uint16_t SHT2xClass::readSensor(uint8_t command)
{
    uint16_t result;

    Wire.beginTransmission(eSHT2xAddress);	//begin
    Wire.write(command);					//send the pointer location
    delay(100);
    Wire.endTransmission();               	//end

    Wire.requestFrom(eSHT2xAddress, 3);
  
    uint32_t ms = millis(); // only for debugging
    while(Wire.available() < 3) {
      Particle.process(); // add this to keep the cloud alive if I2C hangs
      if(millis() - ms > 100)
      { // every 100ms print
        ms = millis(); 
        Serial.println(Wire.available()); // give some feedback
      }
    }

    //Store the result
    result = ((Wire.read()) << 8);
    result += Wire.read();
    result &= ~0x0003;   // clear two low bits (status bits)
    return result;
}

I guess you mean Devices->Build with Firmware, right. It says Default(0.4.9)

The application works until this line of code:

while(Wire.available() < 3) {
      ; //wait
    }

After that the LED breathing green.

Edit:
No matter if the SHT21 is connected or not.

Have you seen my edit above?

If there is no difference, recheck your wiring and also the pull-ups.
Are you pulling to 3.3V or 5V?

Yes. I get a lot of “0” in the Serial - which I think is the result of Serial.println(Wire.available()); right?!

I pull up SCL/SDA to 3.3V and measure exactly 3.3V on both lines.

Have you got a logic analyser or oszillograph to check what’s going on on the lines?

You might also need to check if your sensor has 0x80, 0x40 or any other address and set eSHT2xAddress accordingly in the header file.

To scan for the I2C address you could use this

// --------------------------------------
// i2c_scanner
//
// http://playground.arduino.cc/Main/I2cScanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// 
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//

#include "application.h"

void setup()
{
  Wire.begin();

  Serial.begin(9600);
  while(!Serial.available()) Particle.process();  // Hit a key to start
  Serial.println("\nI2C Scanner");
}


void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknow error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}
1 Like

Ha, I love you :kissing_heart:
It works after I set the correct address as you mentioned.

Thank you very much!

Now I want to post the values to a REST API - so I have to look how I can archive this.

Check out the HTTP library for that, or even webhooks :slight_smile:

1 Like

My pleasure! Glad it works :+1:

Particle.publish() is another key term to look into :wink:

Ok, as I understand it correct, Particle.publish() would publish the values (Temperature and Humidity) to the Particle Cloud and IFTTT it to the Rest API. Yes, I could do that but I want to POST the values direct to the REST API.

So, I tried the REST Client Library https://github.com/llad/spark-restclient but I get some errors while compiling the POST Example. And with the HTTP Library I can’t get it work because I don’t know how I exactly change request to fit my needs.

Here is an example in Python how I have to create the POST call:

T_Home = 25

def Update_Value (item, value):
        headers = {'content-type': 'text/plain'}
        requests.put("http://192.168.0.13:8080/rest/items/" + item + "/state", value, headers=headers)
        print requests.put

Update_Value("Temperature", T_Home)

I have no luck converting it to get no errors and beside that I don’t know where exactly put the information :confused:

I am afraid I have to ask again for help.

Quoting the error messages would possibly help giving you pointers about what you could try, without the need for us to import and build the library to just find out what you already saw.


Have you had a look at this library present for Web IDE?
https://build.particle.io/libs/53dde39bc0caf29ff2000278

Ok, I have the following code:

#include "HttpClient/HttpClient.h"
#include "application.h"

HttpClient http;
int temp = 25;
unsigned int nextTime = 0;    // Next time to contact the server

// Headers currently need to be set at init, useful for API keys etc.
http_header_t headers[] = {
    { "Content-Type", "text/plain" },
    { NULL, NULL } // NOTE: Always terminate headers will NULL
};

http_request_t request;
http_response_t response;

void setup() {
    pinMode(A0, INPUT);
    request.hostname = "http://192.168.0.13";
    request.port = 8080;
    request.path = "/rest/items/Photon_T/";
    Serial.begin(9600);
}

void loop() {
    if (nextTime > millis()) {
        return;
    }
    // Read sensor value
    lightLevel = analogRead(A0);

    Serial.println("Sending data ...");

    request.body = "{\"state\"," + String(temp) + "}";

    // Post request
    http.post(request, response, headers);
    Serial.println(response.status);
    Serial.println(response.body);

    nextTime = millis() + 1000;
    
    delay(5000);
}

I see the following on the Serial line:

Sending data ...
-1

And the item state doesn’t change in the application.

Edit:
Yes I’ve seen that but don’t want to run a WebServer on the Photon itself.

@larusso, you may want to use request.ip = IPAddress{192,168,0,13}; instead of your request.hostname line as the httpClient library will try to resolve the hostname to an IP. :wink:

1 Like

Awesome, that did the trick!

Additional I had to change the request.body but it works now!
Thank you very much!

1 Like