Passing a sensor variable to oled display

I am puzzled, I am working with the ss_oled library by Larry Bank.
I am trying to display temperature and humidity data to one of two I2c OLEDs.
The sensor data is posted on the serial monitor but not on the OLED. I have determined that the variable is not being converted correctly to be displayed.

ahtValue1 = temperature value (prefer it to be in Fahrenheit)
ahtValue2 = humidity value

[code]
   //
// Small Simple OLED library multi-display 
//
// By Larry Bank
//
#include <ss_oled.h>
#include <AHTxx.h>


// Use -1 for the Wire library default pins
// or specify the pin numbers to use with the Wire library or bit banging on any GPIO pins
// These are reversed because I did straight-through wiring for my SSD1306
// and it has the 4-pin header as GND,VCC,SCL,SDA, but the GROVE connector is
// GND,VCC,SDA,SCL
//#define GROVE_SDA_PIN 32
//#define GROVE_SCL_PIN 26
// These are the pin numbers for the M5Stack Atom default I2C
#define SDA_PIN A4
#define SCL_PIN A5
// Set this to -1 to disable or the GPIO pin number connected to the reset
// line of your display if it requires an external reset
#define RESET_PIN -1
// let ss_oled figure out the display address
//#define OLED_ADDR -1
// don't rotate the display
#define FLIP180 0
// don't invert the display
#define INVERT 0
// Bit-Bang the I2C bus
#define USE_HW_I2C 0
// Change these if you're using different OLED displays
// OLED1 address 0x3C
#define MY_OLED1 OLED_128x64
//OLED2 address 0x3D
#define MY_OLED2 OLED_128x64
// AHT21 address 0x38

float ahtValue1;    //to store Temp result
float ahtValue2;   //to store humidity result

AHTxx aht20(AHTXX_ADDRESS_X38, AHT2x_SENSOR); //sensor address, sensor type
  byte celsius = 26;
  byte fahrenheit = (celsius * 9) / 5 + 32;
  byte humidity =  ahtValue2;



// 2 copies of the SSOLED structure. Each structure is about 56 bytes
// There is no limit to the number of simultaneous displays which can be controlled by ss_oled 
SSOLED ssoled[2];

void setup() {

int rc;
// The I2C SDA/SCL pins set to -1 means to use the default Wire library
// If pins were specified, they would be bit-banged in software
// This isn't inferior to hw I2C and in fact allows you to go faster on certain CPUs
// The reset pin is optional and I've only seen it needed on larger OLEDs (2.4")
//    that can be configured as either SPI or I2C
//
// oledInit(SSOLED *, type, oled_addr, rotate180, invert, bWire, SDA_PIN, SCL_PIN, RESET_PIN, speed)

rc = oledInit(&ssoled[1], MY_OLED2, 0x3D, FLIP180, INVERT, 1, SDA_PIN, SCL_PIN, RESET_PIN, 400000L); // use standard I2C bus at 400Khz
  if (rc != OLED_NOT_FOUND)
  {
    oledFill(&ssoled[1], 0, 1);
    oledSetTextWrap(&ssoled[1], 1);
    oledWriteString(&ssoled[1], 0,9,1,(char *)"Display 2", FONT_NORMAL, 0, 1);

  }

  Serial.begin(9600);  

  Serial.println();
  
  while (aht20.begin() != true)
  {
    Serial.println(F("AHT2x not connected or fail to load calibration coefficient")); //(F()) save string to flash & keeps dynamic memory free

    delay(5000);
  }

  //Serial.println(F("AHT20 OK"));

  //Wire.setClock(400000); //experimental I2C speed! 400KHz, default 100KHz  
    
} /* setup() */

void loop() {

 ahtValue1 = aht20.readTemperature(); //read 6-bytes via I2C, takes 80 milliseconds
 int rc; 
   
rc = oledInit(&ssoled[0], MY_OLED1, 0x3C, FLIP180, INVERT, 1, SDA_PIN, SCL_PIN, RESET_PIN, 400000L); // use standard I2C bus at 400Khz
  if (rc != OLED_NOT_FOUND)
  {
    char szString1[32];
    char szString2[32];
    sprintf(szString1, fahrenheit);
    //sprintf(szString2, ahtValue2);
    sprintf(szString2, humidity);
    
    // Line one
    oledFill(&ssoled[0], 0, 1);
    oledWriteString(&ssoled[0], 0,0,0,(char *)"Helm: ", FONT_NORMAL, 0, 1);
    //oledWriteString(&ssoled[0], 0,50,0,(char *)"80F", FONT_NORMAL, 0, 1);
    oledWriteString(&ssoled[0], 0,90,0,(char *)"50%", FONT_NORMAL, 0, 1);
    oledWriteString(&ssoled[0], 0,50,0,(szString1), FONT_NORMAL, 0,1);
    //oledWriteString(&ssoled[0], 0,90,0, szString1, FONT_NORMAL, 0,1);

    // Line two
    //oledFill(&ssoled[0], 0, 1);
    oledWriteString(&ssoled[0], 0,0,2,(char *)"Pack: ", FONT_NORMAL, 0, 1);
    oledWriteString(&ssoled[0], 0,50,2,(char *)"25F", FONT_NORMAL, 0, 1);
    oledWriteString(&ssoled[0], 0,90,2,(char *)"70%", FONT_NORMAL, 0, 1);
    //oledWriteString(&ssoled[0], 0,0,4, szString, FONT_NORMAL, 0,1);

    // Line three
    //oledFill(&ssoled[0], 0, 1);
    oledWriteString(&ssoled[0], 0,0,4,(char *)"Cool: ", FONT_NORMAL, 0, 1);
    oledWriteString(&ssoled[0], 0,50,4,(char *)"ON/Off", FONT_NORMAL, 0, 1);
    //oledWriteString(&ssoled[0], 0,0,4, szString, FONT_NORMAL, 0,1);

    // Line four
    //oledFill(&ssoled[0], 0, 1);
    oledWriteString(&ssoled[0], 0,0,6,(char *)"Fan: ", FONT_NORMAL, 0, 1);
    oledWriteString(&ssoled[0], 0,50,6,(char *)"100%", FONT_NORMAL, 0, 1);
    //oledWriteString(&ssoled[0], 0,0,4, szString, FONT_NORMAL, 0,1);
 
  }
  Serial.print(F("Temperature: "));
  
  if (ahtValue1 != AHTXX_ERROR) //AHTXX_ERROR = 255, library returns 255 if error occurs
  {
    
    Serial.print(fahrenheit);
    Serial.println(F("F"));
    Serial.print(ahtValue1);
    Serial.println(F("C"));

  }
  else
  {
    printStatus(); //print temperature command status
  }

  //ahtValue2 = aht20.readHumidity(AHTXX_USE_READ_DATA); //use 6-bytes from temperature reading, takes zero milliseconds!!!
   humidity = aht20.readHumidity(AHTXX_USE_READ_DATA); //use 6-bytes from temperature reading, takes zero milliseconds!!! = aht20.readHumidity(AHTXX_USE_READ_DATA); //use 6-bytes from temperature reading, takes zero milliseconds!!!
  Serial.print(F("Humidity...: "));
  
  if (ahtValue2 != AHTXX_ERROR) //AHTXX_ERROR = 255, library returns 255 if error occurs
  {
    Serial.print(humidity);
    Serial.println(F("%"));
    Serial.println();
  }
  else
  {
    printStatus(); //print temperature command status not humidity!!! RH measurement use same 6-bytes from T measurement
  }

  delay(15000); //recomended polling frequency 8sec..30sec



} /* loop() */

void printStatus()
{
  switch (aht20.getStatus())
  {
    case AHTXX_NO_ERROR:
      Serial.println(F("no error"));
      break;

    case AHTXX_BUSY_ERROR:
      Serial.println(F("sensor busy, increase polling time"));
      break;

    case AHTXX_ACK_ERROR:
      Serial.println(F("sensor didn't return ACK, not connected, broken, long wires (reduce speed), bus locked by slave (increase stretch limit)"));
      break;

    case AHTXX_DATA_ERROR:
      Serial.println(F("received data smaller than expected, not connected, broken, long wires (reduce speed), bus locked by slave (increase stretch limit)"));
      break;

    case AHTXX_CRC8_ERROR:
      Serial.println(F("computed CRC8 not match received CRC8, this feature supported only by AHT2x sensors"));
      break;

    default:
      Serial.println(F("unknown status"));    
      break;
  }
}

[/code]

thank you

Start simple then work your way up.

Hello zefd

Welcome to the world's best Arduino forum ever.

I assume that you have written the programme by yourself, then it is quite easy to find the error.

There's a trick to figuring out why something isn't working:

Use a logic analyzer to see what happens.
Put Serial.print statements at various places in the code as diagnostic prints to see the values of variables and determine whether they meet your expectations.

Have a nice day and enjoy coding in C++.

Those have got to be the two least useful answers I have seen in a long time. Why you waste time posting something like that?

This is not how you use sprintf. Look at some examples. sprintf needs a format string. It should be at the very least:

sprintf(szString1, "%d", fahrenheit);

Please, post the pictures of your Sensor and OLED Display Unit.

You don't want to be initializing your OLED display every time through loop(). Only do that once in setup() and then just update the display inside of loop().

It also looks like you are using the hardware I2C pins but defined the library to not use them?

Can you explain how a logic analyzer would help in this particular situation? Or are you just posting boilerplate to increase your post count?

2 Likes

Delta_G, Thank you. I have done some research to understand the sprintf. I think I have it figured out.
I have updated my code and it works.

blh64, Thank you, I have updated my code to initialize the OLED display in setup. I am not sure what you mean by "looks like you are using the hardware I2C pins but defined the library not to use them" Please keep in mind, that I am new to using the ss_oled library and do not fully understand its use. Could you explain a bit more?

So from that we assume you endorse complex code for beginners.

If you are using an UNO, then the hardware I2C pins are A4 and A5 just like what you have defined

but you also define this which means to not use the hardware

which seems like you are bit-banging (using a software implementation) for I2C but doing it with the hardware pins. It will work, but why not just use the hardware?

blh64, Thank you. I have removed the bit-bang #define statement. I am using a nano and the i2c pins are the same as uno.

ZefD

No. I just prefer answers that have at least some small amount of informative content.

I hope you didn't remove it, but rather, change it to a 1

#define USE_HW_I2C 1

or maybe it defaults to that if you don't define it? I don't know since I don't have that library.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.