Giter Site home page Giter Site logo

scd30's Introduction

paulvha SCD30 library

===========================================================

An extended SCD30 library based on the SparkFun SCD30 CO2 Sensor Library, see information below

Versioning

October 2023

  • tested on UNO R4 WiFI with Wire (5V): Works correct unmodified.
  • tested on UNO R4 WIFI with QWICC/Wire1 (3v3) : WORKS but needs more time to warm up /get stable

Modified July 2022

  • added option autoCalibrate to begin() to enable disable auto calibration (contribution of jhengstermann)
  • begin(TwoWire &wirePort = Wire, bool m_begin = true, boolean autoCalibrate = true);
  • wirePort : I2C channel to use. Wire by default.
  • m_begin : if true will start measurement every 2 seconds. True / start by default.
  • autoCalibrate : if true will enable or false disable autocalibrate at begin. True / Enable ASC by default.

Modified by Paulvha version November 2020

  • solved a conflict with ByteToFloat when using SPS30 at the same time

Modified by Paulvha version October 2020

  • Update in readmeasurement to translate byte to float. It did not work on Arduino. Tested on Uno, Artemis Apollo3, ESP32
  • added example4 to manual input temperature offset and see impact.
  • SECOND UPDATE IN OCTOBER
  • Added example5 to work with Sparkfun LCD
  • update to example4 to set and calibrate temperature offset

Modified by Paulvha version August 2020:

Changes based on Datasheet May 2020

  • added functions : getForceRecalibration, getMeasurementInterval, getTemperatureOffset, getAltitudeCompensation, getFirmwareLevel
  • updated the keywords.txt file
  • added example14 to demonstrate the new functions
  • A number of library enhancements
  • updated sketches and library where needed

Modified by Paulvha version February 2019

Changes:

  • Added option in examples 10 and 13 to set BME280 I2C address. (some use 0x76 instead of 0x77)
  • Added SoftWire (a port of the ESP8266 I2C library) for ESP32 (which does NOT support clockstretching)
  • Removed StartSingleMeasurement as that is not working in the SCD30 as it should.
  • Added option to begin() to disable starting measurement. (needed in case one wants to read serial number)
  • updated the keywords.txt file
  • updated sketches and library where needed

Modified by paulvha version 10 August, 2018

Changes:

  • Added ESP8266 board detection in begin() to support the ESP8266 clockstretching
  • Added setting debug messages
  • Added obtaining serial number of SCD30
  • Added StopMeasurement
  • Added StartSingleMeasurement (removed February 2019 as it IS unstable)
  • Added GetTemperature in Fahrenheit
  • Added CRC checks on different places in de driver
  • Updated existing sketches fom Sparkfun to new library
  • Added new sketches : Example 10: combined read with BME280 Example 11: Set ESP8266 as Access Point and read SCD30 in browser Example 12: Set ESP8266 as WIFI server and read SCD30 in browser

More work to be follow on connecting / comparing with other sensors and document the learnings.

check for updated datasheet and information on Sensirion

============= ORIGINAL INFORMATION FROM SPARKFUN ===========================

SparkFun SCD30 CO2 Sensor Library

SparkFun SCD30 CO2 Sensor

SparkX CO₂ Humidity and Temperature Sensor - SCD30 (SPX-14751)

The SCD30 from Sensirion is a high quality NDIR based CO₂ sensor capable of detecting 400 to 10000ppm with an accuracy of ±(30ppm+3%). In order to improve accuracy the SCD30 has temperature and humidity sensing built-in, as well as commands to set the current altitude.

We've written an Arduino library to make reading the CO₂, humidity, and temperature very easy. It can be downloaded through the Arduino Library manager: search for 'SparkFun SCD30'. We recommend using a Qwiic Breadboard Cable to connect the SCD30 to a Qwiic compatible board. The YeLLow wire goes in the SCL pin. The SCD30 also supports a serial interface but we haven't worked with it.

The CO₂ sensor works very well and for additional accuracy the SCD30 accepts ambient pressure readings. We recommend using the SCD30 in conjunction with the Qwiic Pressure Sensor - MS5637 or the Qwiic Environmental Sensor - BME680 to obtain the current barometric pressure.

Note: The SCD30 has an automatic self-calibration routine. Sensirion recommends 7 days of continuous readings with at least 1 hour a day of 'fresh air' for self-calibration to complete.

Library written by Nathan Seidle (SparkFun).

Repository Contents

  • /examples - Example sketches for the library (.ino). Run these from the Arduino IDE.
  • /src - Source files for the library (.cpp, .h).
  • keywords.txt - Keywords from this library that will be highlighted in the Arduino IDE.
  • library.properties - General library properties for the Arduino package manager.

Documentation

License Information

This product is open source!

Various bits of the code have different licenses applied. Anything SparkFun wrote is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round!

Please use, reuse, and modify these files as you see fit. Please maintain attribution to SparkFun Electronics and release anything derivative under the same license.

Distributed as-is; no warranty is given.

  • Your friends at SparkFun.

scd30's People

Contributors

paulvha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

scd30's Issues

Disable ASC (Auto Self Calibration) per default

Hi, just as an idea to be more accurate towards Sensirions information:

According to the documentation (chapter 1.3.6) ASC is disabled by default in the sensor.

I think it could be very misleading, when the library will turn it on by default.
When not specifying anything else, it should behave like documented by the manufacturer.

Merge back with Adafruit Library?

Would be nice, if your could open a merge request in the Adafruit Library. So everything is in one place and bugs must not be fixed twice aso. This would really be great.

Thanks for your work btw., works really well on my Wemos D1 mini.

ESP32 Not getting ACK.

Thank you for your work on this library. It is exactly what I was looking for. Unfortunately I can't get it to work. I'm not sure what I am doing wrong. I've confirmed the SCD30 is working by hooking it up to an Uno and using the sparkfun library. But with the ESP32 it doesn't seem to be able to communicate. In the examples there is a section that says:

//////////////////////////////////////////////////////////////////////////
// SELECT THE WIRE INTERFACE //
//////////////////////////////////////////////////////////////////////////
#define SCD30WIRE Wire

But there is only that one option. Reading I think I need to select SoftWire? But then looking at the library code it seems it should be set automatically? Basically my questions is there anything special I need to do for it to work on an ESP32?

Esp32 compatibility

Hi. Thanks for sharing your library. Will this library work with a esp32? Thanks.

ESP32: Using Two I2C devices causing an compilation error

I'm facing a compilation error always when I'm compiling paulbha_SDC30.h and all of the BME280 I2C library I tested so far. As far I understand the issue than because of the multiple use of wire.h. lib. Is there a chance getting a lib based on HW wire? working with multiple I2C devices? I understood there is a clock_streching issue with ESP32.
Thx.

No values from the SDC30

Hi,
I used an Arduino and and SDC30 to make a CO2 measuring device. I used the Sparfun library and got it to work, but I couldnt really change the measuring interval. The sensor stops always working.
With your library this seemed to work without any problems. I used your examples to change all kind of things.
The only thing which didn'twork anymore? I didn't get values for the CO2, temperature or humidity. The ony thing I got was "0" or "NAN"
I am new to this and don't really know how the libraries work, I opend yous and replaced some lines from the SparkFun_SCD30_Arduino_Library.ccp (line 189 to 278) in your ***.ccp. After I have done this I got values for the temparature and the humidity but not for CO2.
Any idea why I am not getting anything with you library?

-Dirk Scheumann

SCD-30 Sensor + OLED

Hi @paulvha , I am trying to integrate an OLED with a scd30 sensor over esp32, but I am getting some TwoWire errors.
My code is:
#include <Wire.h>
#include <WiFi.h>
#include <esp_wpa2.h>
#include <FirebaseESP32.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include "paulvha_SCD30.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define EAP_ANONYMOUS_IDENTITY "[email protected]"
#define EAP_IDENTITY "[email protected]"
#define EAP_PASSWORD "epreslab@iitd"
const char* ssid = "IITD_WIFI";
int counter = 0;
WiFiClient client;
int rssi;
String notif_wifi, notif_sensor;

#define FIREBASE_HOST "labindividuallight.firebaseio.com"
#define FIREBASE_AUTH "tQNM1JXaHbrkpyVdavuwayNLnnzi0d4srHk6mptT"
FirebaseData firebaseData;

const long utcOffsetInSeconds = 19800;
String formattedDate, dateStamp, dateStamp_display, dateStamp_firebase, timeStamp, timeStamp_display, timeStamp_firebase;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);

#define scd_debug 0
#define SCD30_I2C_ADDRESS 0x61
SCD30 scd30;
float temperature, humidity; int co2;
String temp_str, hum_str, co2_str;

Adafruit_SSD1306 display(-1);
#define OLED_I2C_ADDRESS 0x3C
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

const unsigned char EPRESlogo [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xdc,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xdc, 0x02, 0x00,
0x00, 0x00, 0x08, 0x01, 0xdc, 0x42, 0x00, 0x00, 0x00, 0x00, 0x41, 0x9c, 0x40, 0x00, 0x00, 0x00,
0x1f, 0xc1, 0xbc, 0x40, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x42, 0x00, 0x00, 0x00, 0x1f, 0xc0,
0x00, 0x40, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x80, 0x00, 0x00,
0x00, 0x70, 0x00, 0x19, 0x80, 0x06, 0x00, 0x00, 0x50, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x70,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
0x00, 0x22, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07,
0x77, 0x00, 0x00, 0x00, 0x22, 0x00, 0x1f, 0x27, 0xe0, 0x30, 0x00, 0x1c, 0x00, 0x36, 0x23, 0xa0,
0x20, 0x00, 0x00, 0x00, 0x38, 0x20, 0xe0, 0x3e, 0x00, 0x00, 0x00, 0x10, 0x20, 0x40, 0x87, 0x00,
0x00, 0x20, 0x00, 0x20, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x20, 0x07, 0xe7, 0x00, 0x00, 0x00,
0x00, 0x20, 0x0d, 0x6c, 0x00, 0x06, 0x40, 0x00, 0x00, 0x0f, 0x38, 0x00, 0x07, 0xc0, 0x00, 0x00,
0x2f, 0xf0, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x25, 0xe0, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x14, 0xc0,
0x00, 0x00, 0x0f, 0xe0, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x86, 0x00, 0x00, 0x00,
0x0b, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x34, 0x00, 0x00, 0x00, 0x0f, 0xe0,
0x00, 0x18, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char IITDLogo [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00,
0xdf, 0xff, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x03,
0xf8, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x78, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1f, 0x00,
0x00, 0x00, 0x78, 0x0d, 0x80, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x20, 0x0c, 0x03, 0x80, 0x00, 0x01,
0xe1, 0x40, 0x01, 0x81, 0xe0, 0x00, 0x03, 0x81, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03, 0x80, 0x01,
0xc0, 0x00, 0x60, 0x00, 0x07, 0x08, 0x01, 0xe2, 0x00, 0x78, 0x00, 0x0e, 0x00, 0x78, 0x0f, 0x00,
0x38, 0x00, 0x0e, 0x20, 0x60, 0x03, 0x82, 0x18, 0x00, 0x0c, 0x20, 0x40, 0x00, 0x00, 0x1c, 0x00,
0x1c, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x38, 0x06, 0x00, 0x00, 0x30, 0x0e, 0x00, 0x38, 0x06,
0x00, 0x00, 0x38, 0xce, 0x00, 0x38, 0x8c, 0x00, 0x00, 0x18, 0x06, 0x00, 0x70, 0x04, 0x00, 0x00,
0x10, 0x07, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x06,
0x00, 0x30, 0x18, 0x00, 0x00, 0x0c, 0x07, 0x00, 0x73, 0x18, 0x00, 0x80, 0x0c, 0xc7, 0x00, 0x73,
0x18, 0x00, 0x00, 0x0c, 0xc7, 0x00, 0x70, 0x18, 0x00, 0xc0, 0x0c, 0x07, 0x00, 0x30, 0x08, 0x00,
0x00, 0x00, 0x07, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x70, 0x84, 0x00, 0x00, 0x10,
0x07, 0x00, 0x30, 0x8c, 0x00, 0x00, 0x18, 0x06, 0x00, 0x18, 0x86, 0x00, 0x00, 0x38, 0x0e, 0x00,
0x38, 0x46, 0x00, 0x00, 0x31, 0x0e, 0x00, 0x38, 0x40, 0x00, 0x80, 0x01, 0x0e, 0x00, 0x1c, 0x20,
0x00, 0x10, 0x00, 0x18, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x0e, 0x08, 0x00, 0x00,
0x00, 0x38, 0x00, 0x0f, 0x0c, 0x00, 0x00, 0x08, 0x70, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x60,
0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03, 0xc0, 0x00, 0x01, 0x81, 0xe0, 0x00, 0x00,
0x70, 0x00, 0x06, 0x03, 0x80, 0x00, 0x00, 0x78, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x7c, 0x00,
0x00, 0x1f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x03, 0xf8,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x0d, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char temperatureLogo [] PROGMEM = {
0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x0c, 0x70, 0x00, 0x00, 0x00, 0x18, 0x18, 0x60, 0x00, 0x00,
0x11, 0x88, 0xf0, 0x00, 0x00, 0x32, 0xcc, 0xf0, 0x00, 0x00, 0x26, 0x6c, 0x60, 0x00, 0x00, 0x26,
0x6c, 0x0f, 0x80, 0x00, 0x27, 0xec, 0x18, 0xc0, 0x00, 0x27, 0xec, 0x18, 0xc0, 0x00, 0x26, 0x6c,
0x18, 0x00, 0x00, 0x26, 0x60, 0x18, 0x00, 0x00, 0x26, 0x60, 0x18, 0x00, 0x00, 0x27, 0xe4, 0x18,
0x00, 0x00, 0x26, 0x6c, 0x18, 0x00, 0x00, 0x26, 0x6c, 0x18, 0xc0, 0x00, 0x26, 0x6c, 0x0f, 0x80,
0x00, 0x26, 0x6c, 0x07, 0x00, 0x00, 0x27, 0xec, 0x00, 0x00, 0x00, 0x26, 0x6c, 0x00, 0x00, 0x00,
0x26, 0x6c, 0x00, 0x00, 0x00, 0x26, 0x6c, 0x00, 0x00, 0x00, 0x27, 0xec, 0x00, 0x00, 0x00, 0x26,
0x6c, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0xc6, 0x63, 0x00, 0x00, 0x00, 0x8c, 0x31,
0x00, 0x00, 0x01, 0x90, 0x19, 0x80, 0x00, 0x01, 0x30, 0x0c, 0x80, 0x00, 0x03, 0x20, 0x04, 0x80,
0x00, 0x03, 0x20, 0x04, 0xc0, 0x00, 0x03, 0x60, 0x04, 0xc0, 0x00, 0x03, 0x20, 0x04, 0xc0, 0x00,
0x01, 0x20, 0x04, 0x80, 0x00, 0x01, 0x30, 0x0c, 0x80, 0x00, 0x01, 0x80, 0x19, 0x80, 0x00, 0x00,
0x8f, 0xf1, 0x00, 0x00, 0x00, 0x43, 0xc2, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x1c,
0x38, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00
};
const unsigned char humidityLogo [] PROGMEM = {
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xc0, 0x18, 0x00, 0x00, 0x01, 0xe0, 0x2c, 0x00, 0x00,
0x01, 0xe0, 0x64, 0x00, 0x00, 0x03, 0xf0, 0x46, 0x00, 0x00, 0x06, 0xf8, 0x83, 0x00, 0x00, 0x06,
0xf8, 0x09, 0x00, 0x00, 0x0c, 0x7c, 0x0d, 0x80, 0x00, 0x18, 0x3e, 0x06, 0x80, 0x00, 0x18, 0x3e,
0x02, 0xc0, 0x00, 0x30, 0x1f, 0x03, 0x40, 0x00, 0x30, 0x1f, 0x81, 0x60, 0x00, 0x00, 0x0f, 0x81,
0xa0, 0x00, 0x40, 0x07, 0xc0, 0xb0, 0x00, 0xc0, 0x07, 0xc0, 0x90, 0x00, 0x80, 0x03, 0xe0, 0xd0,
0x00, 0x80, 0x03, 0xe0, 0x10, 0x00, 0x3c, 0x03, 0xf0, 0x10, 0x03, 0x7f, 0x07, 0xf0, 0x10, 0x02,
0x63, 0x8e, 0xf8, 0x10, 0x06, 0x43, 0x9d, 0xf8, 0x30, 0x06, 0x63, 0xbb, 0xf8, 0x20, 0x0c, 0x7f,
0x77, 0xfc, 0x40, 0x0c, 0x3c, 0xef, 0x7d, 0x80, 0x0c, 0x00, 0xde, 0x7f, 0x00, 0x08, 0x02, 0x3c,
0x3c, 0x00, 0x08, 0x06, 0x78, 0x3c, 0x00, 0x08, 0x0e, 0xf0, 0x3c, 0x00, 0x08, 0x1d, 0xef, 0x3c,
0x00, 0x0c, 0x3b, 0xdf, 0xfc, 0x00, 0x0c, 0x77, 0xb1, 0xfc, 0x00, 0x04, 0xef, 0x30, 0x78, 0x00,
0x06, 0xde, 0x30, 0xf8, 0x00, 0x03, 0xfc, 0x1f, 0xf0, 0x00, 0x03, 0xf0, 0x0f, 0xf0, 0x00, 0x01,
0xc0, 0x03, 0xe0, 0x00, 0x00, 0xe0, 0x0f, 0xc0, 0x00, 0x00, 0x78, 0x1f, 0x80, 0x00, 0x00, 0x1f,
0xfe, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00
};
const unsigned char co2Logo [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x01, 0xa0, 0x00, 0x00,
0x03, 0xe1, 0xe0, 0x00, 0x00, 0x0c, 0x18, 0xc0, 0x00, 0x07, 0xd8, 0x0c, 0x00, 0x00, 0x1c, 0x70,
0x04, 0x00, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0x00, 0x02,
0x00, 0x00, 0x40, 0x00, 0x02, 0xe0, 0x00, 0x40, 0x00, 0x03, 0xf8, 0x07, 0x40, 0x00, 0x00, 0x04,
0x1f, 0xc3, 0x87, 0x00, 0x02, 0x20, 0x07, 0xdf, 0x80, 0x03, 0x40, 0x0c, 0x58, 0xc0, 0x01, 0xc0,
0x0c, 0x18, 0xc0, 0x01, 0x80, 0x0c, 0x18, 0xc0, 0x01, 0x80, 0x04, 0xd9, 0x98, 0x01, 0x80, 0x07,
0xcf, 0x3c, 0x01, 0x80, 0x00, 0x00, 0x08, 0x01, 0x80, 0x00, 0x00, 0x38, 0x01, 0xc0, 0x00, 0x00,
0x18, 0x03, 0x40, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x04, 0x1f, 0xff, 0xff, 0xf1,
0xf8, 0x07, 0xff, 0xff, 0xf3, 0xe0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x9b, 0x00, 0x00, 0x00, 0x01, 0xce, 0x00, 0x00, 0x00, 0x01,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

void setup()
{
Serial.begin(9600);
Wire.begin();

Wire.beginTransmission(SCD30_I2C_ADDRESS);
scd30.setDebug(scd_debug);
scd30.begin(Wire);
scd30.setAutoSelfCalibration(1);

delay(1000);

display.begin(SSD1306_SWITCHCAPVCC, OLED_I2C_ADDRESS);
display.clearDisplay();
display.setTextColor(WHITE, BLACK);
display.setTextWrap(false);

delay(10);
Serial.println();
Serial.print("Connecting to network: ");
display.setCursor(8, 25);
display.setTextSize(2);
display.println("Connecting to network: ");
display.display(); delay(3000);
display.clearDisplay();
Serial.println(ssid);
WiFi.disconnect(true);
WiFi.mode(WIFI_STA); //init wifi mode
esp_wifi_sta_wpa2_ent_set_identity((uint8_t *)EAP_ANONYMOUS_IDENTITY, strlen(EAP_ANONYMOUS_IDENTITY));
esp_wifi_sta_wpa2_ent_set_username((uint8_t *)EAP_IDENTITY, strlen(EAP_IDENTITY));
esp_wifi_sta_wpa2_ent_set_password((uint8_t *)EAP_PASSWORD, strlen(EAP_PASSWORD));
esp_wpa2_config_t config = WPA2_CONFIG_INIT_DEFAULT(); //set config settings to default
esp_wifi_sta_wpa2_ent_enable(&config); //set config settings to enable function
WiFi.begin(ssid);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
counter++;
if (counter >= 60) //after 30 seconds timeout - reset board
{
ESP.restart();
}
}
Serial.println("");
Serial.println("WiFi connected");

Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);

// WELCOME SCREEN
rssi = WiFi.RSSI();
networkStrength(rssi);
if (rssi < 0)
{
NTP();
display.setCursor(8, 25);
display.setTextSize(2);
display.println("Datalogger");
display.display(); delay(3000);
display.clearDisplay();
NTP();
networkStrength(rssi);
display.drawBitmap(10, 15, EPRESlogo, 50, 50, WHITE);
display.drawBitmap(65, 15, IITDLogo, 50, 50, WHITE);
display.display(); delay(3000);
display.clearDisplay();
}
else
{
display.setCursor(8, 25);
display.setTextSize(2);
display.println("Datalogger");
display.display(); delay(3000);
display.clearDisplay();
networkStrength(rssi);
display.drawBitmap(10, 15, EPRESlogo, 50, 50, WHITE);
display.drawBitmap(65, 15, IITDLogo, 50, 50, WHITE);
display.display(); delay(3000);
display.clearDisplay();
}
}

void loop()
{
temperature = 0;
humidity = 0;
co2 = 0;

if (scd30.dataAvailable())
{
temperature = scd30.getTemperature(); temp_str = String(temperature) + "C";
humidity = scd30.getHumidity(); hum_str = String(humidity) + "%";
co2 = scd30.getCO2(); co2_str = String(co2) + "ppm";
notif_wifi = "";
notif_sensor = "";
LCDdisplay(temp_str, hum_str, co2_str, notif_wifi, notif_sensor);
Serial.print("co2(ppm):"); Serial.print(scd30.getCO2());
Serial.print(" temp(C):"); Serial.print(scd30.getTemperature(), 1);
Serial.print(" humidity(%):"); Serial.print(scd30.getHumidity(), 1);
}
else
{
temp_str = "No Data";
hum_str = "No Data";
co2_str = "No Data";
notif_wifi = "";
notif_sensor = "Check Sensor";
LCDdisplay(temp_str, hum_str, co2_str, notif_wifi, notif_sensor);
Serial.println("No data");
}
// const size_t capacity = JSON_ARRAY_SIZE(2) + JSON_OBJECT_SIZE(3);
// DynamicJsonBuffer jsonBuffer(capacity);
// JsonObject& root1 = jsonBuffer.createObject();
// JsonObject& root2 = jsonBuffer.createObject();
//
// root1["Date"] = dateStamp_firebase;
// root1["Time"] = timeStamp_firebase;
// root1["Temperature"] = temperature;
// root1["Humidity"] = humidity;
// root1["CO2"] = co2;
//
// root2["Temperature"] = temperature;
// root2["Humidity"] = humidity;
// root2["CO2"] = co2;
//
// String path1 = "/SensorValues";
// String path2 = "/SensorValuesLog/" + dateStamp_firebase + "/" + timeStamp_firebase;
// Firebase.set(path1, root1);
// Firebase.set(path2, root2);
// root1.printTo(Serial); Serial.println(); root2.printTo(Serial); Serial.println();
}

void networkStrength(int rssiVal)
{
if (rssiVal >= 0)
{
display.fillRect(123, 8, 1, 4, BLACK);
display.fillRect(125, 5, 1, 7, BLACK);
display.fillRect(127, 1, 1, 11, BLACK);
}
else if (rssiVal >= -50 && rssiVal < 0)
{
display.fillRect(123, 8, 1, 4, WHITE);
display.fillRect(125, 5, 1, 7, WHITE);
display.fillRect(127, 1, 1, 11, WHITE);
}
else if (rssiVal < -50 && rssiVal > -75)
{
display.fillRect(123, 8, 1, 4, WHITE);
display.fillRect(125, 5, 1, 7, WHITE);
}
else
{
display.fillRect(123, 8, 1, 4, WHITE);
}
}

void NTP()
{
timeClient.begin();
while (!timeClient.update())
{
timeClient.forceUpdate();
}
String formattedDate = timeClient.getFormattedDate();

int splitT = formattedDate.indexOf("T");
String dateStamp_display_temp = formattedDate.substring(0, splitT);
String day = String(dateStamp_display_temp[8]) + String(dateStamp_display_temp[9]);
String month = String(dateStamp_display_temp[5]) + String(dateStamp_display_temp[6]);
String year = String(dateStamp_display_temp[0]) + String(dateStamp_display_temp[1]) + String(dateStamp_display_temp[2]) + String(dateStamp_display_temp[3]);
dateStamp_display = day + "/" + month;
dateStamp_firebase = day + "-" + month + "-" + year;

String timeStamp_display_temp = formattedDate.substring(splitT + 1, formattedDate.length() - 1);
String hour = String(timeStamp_display_temp[0]) + String(timeStamp_display_temp[1]);
String minute = String(timeStamp_display_temp[3]) + String(timeStamp_display_temp[4]);
String second = String(timeStamp_display_temp[6]) + String(timeStamp_display_temp[7]);
int h = hour.toInt();
if (h < 12)
{
String hour = String(h);
timeStamp_display = hour + ":" + minute + "am";
timeStamp_firebase = hour + "-" + minute + + "-" + second + "am";
}
else
{
if (h == 12)
{
h = 12;
}
else
{
h = h - 12;
}
String hour = String(h);
timeStamp_display = hour + ":" + minute + "pm";
timeStamp_firebase = hour + "-" + minute + + "-" + second + "pm";
}
display.setCursor(20, 0);
display.setTextSize(1);
display.print(dateStamp_display);
display.print(" ");
display.println(timeStamp_display);
}

void LCDdisplay(String t, String h, String c, String n_wifi, String n_sensor)
{
String n;

// ------------------Temperature Screen------------------
rssi = WiFi.RSSI();
networkStrength(rssi);
if (rssi >= 0)
{
n_wifi = "Check WiFi";
if (n_wifi.length() != 0 && n_sensor.length() != 0)
{
String n1 = "Check WiFi";
String n2 = "and Sensor";
display.clearDisplay();
display.setTextSize(2);
display.setCursor(3, 20); display.println(n1);
display.setCursor(3, 37); display.println(n2);
display.display();
delay(2000);
display.clearDisplay();
}
else
{
n = n_wifi;
display.drawBitmap(5, 20, temperatureLogo, 40, 40, WHITE);
display.setTextSize(2);
display.setCursor(50, 30); display.println(t);
display.setTextSize(1);
display.setCursor(53, 50); display.println(n);
display.display();
delay(2000);
display.clearDisplay();
}
}

else if (rssi < 0)
{
networkStrength(rssi);
if (n_sensor.length() != 0)
{
n = n_sensor;
NTP();
display.drawBitmap(3, 20, temperatureLogo, 40, 40, WHITE);
display.setTextSize(2);
display.setCursor(47, 30); display.println(t);
display.setTextSize(1);
display.setCursor(53, 50); display.println(n);
display.display();
delay(2000);
display.clearDisplay();
}
else
{
NTP();
display.drawBitmap(5, 20, temperatureLogo, 40, 40, WHITE);
display.setTextSize(2);
display.setCursor(50, 30); display.println(t);
display.display();
delay(2000);
display.clearDisplay();
}
}

// ------------------Humidity Screen------------------
rssi = WiFi.RSSI();
networkStrength(rssi);
if (rssi >= 0)
{
n_wifi = "Check WiFi";
if (n_wifi.length() != 0 && n_sensor.length() != 0)
{
String n1 = "Check WiFi";
String n2 = "and Sensor";
display.clearDisplay();
display.setTextSize(2);
display.setCursor(3, 20); display.println(n1);
display.setCursor(3, 37); display.println(n2);
display.display();
delay(2000);
display.clearDisplay();
}
else
{
n = n_wifi;
display.drawBitmap(5, 20, humidityLogo, 40, 40, WHITE);
display.setTextSize(2);
display.setCursor(50, 30); display.println(h);
display.setTextSize(1);
display.setCursor(53, 50); display.println(n);
display.display();
delay(2000);
display.clearDisplay();
}
}

else if (rssi < 0)
{
if (n_sensor.length() != 0)
{
n = n_sensor;
NTP();
display.drawBitmap(3, 20, humidityLogo, 40, 40, WHITE);
display.setTextSize(2);
display.setCursor(47, 30); display.println(h);
display.setTextSize(1);
display.setCursor(53, 50); display.println(n);
display.display();
delay(2000);
display.clearDisplay();
}
else
{
NTP();
display.drawBitmap(5, 20, humidityLogo, 40, 40, WHITE);
display.setTextSize(2);
display.setCursor(50, 30); display.println(h);
display.display();
delay(2000);
display.clearDisplay();
}
}

// ------------------CO2 Screen------------------
rssi = WiFi.RSSI();
networkStrength(rssi);
if (rssi >= 0)
{
n_wifi = "Check WiFi";
if (n_wifi.length() != 0 && n_sensor.length() != 0)
{
String n1 = "Check WiFi";
String n2 = "and Sensor";
display.clearDisplay();
display.setTextSize(2);
display.setCursor(3, 20); display.println(n1);
display.setCursor(3, 37); display.println(n2);
display.display();
delay(2000);
display.clearDisplay();
}
else
{
n = n_wifi;
display.drawBitmap(3, 20, co2Logo, 40, 40, WHITE);
display.setTextSize(2);
display.setCursor(47, 30); display.println(c);
display.setTextSize(1);
display.setCursor(53, 50); display.println(n);
display.display();
delay(2000);
display.clearDisplay();
}
}

else if (rssi < 0)
{
if (n_sensor.length() != 0)
{
n = n_sensor;
NTP();
display.drawBitmap(3, 20, co2Logo, 40, 40, WHITE);
display.setTextSize(2);
display.setCursor(47, 30); display.println(c);
display.setTextSize(1);
display.setCursor(53, 50); display.println(n);
display.display();
delay(2000);
display.clearDisplay();
}
else
{
NTP();
display.drawBitmap(3, 20, co2Logo, 40, 40, WHITE);
display.setTextSize(2);
display.setCursor(47, 30); display.println(c);
display.display();
delay(2000);
display.clearDisplay();
}
}
}

Can you help me with this?

I2C -ESP8266 crash

Hello,
I am trying to use your library on ESP8266, in a bundle with BMP280 ( pressure and temperature) and MCP9808 (temperature) sensors. After uploading the code, the ESP is stuck and starts constantly restarting.

Is it because of the clock stretching, and other sensors cannot work in this mode? If yes, how I can use all three sensors?

Thank you

setForceRecalibration does not work

When I try to use the command I get:
error: 'setForceRecalibration' was not declared in this scope
103 | setForceRecalibration(880);
| ^~~~~~~~~~~~~~~~~~~~~
exit status 1
'setForceRecalibration' was not declared in this scope

Second I2C Bus

Hi,

I'm trying to get a set of 2 SCD30 working with an ESP32.
Since I did not find a way to change the I2C adress of the SCD30, I now try to use the second I2C bus of the ESP32 to get both working with the same adress. However, it seems that your twowire class in softwire does not include the functionality to use a second bus.
I tried to compare your softwire.cpp and twi.cpp to the corresponding files of the "normal" wire.cpp (and others used) but i cannot find a solution to add the functionality to use the second bus.
Can you help with that?

Thank you very much,
Michael

BME280 not detected

Hello, first let me say thanks for the library you have created. I love it!
I do have a question, i am unable to get the BME2180 sensor to be detected.
I have the BME sensor connected with a breadbord the BME sensor scl is connected to D1 of my ESP-12 and the sda to D2. First i was thinking that the sensor was broken, but i got it working with the adafruit lib, i did had to change: #define BME280_ADDRESS 0x77, to: #define BME280_ADDRESS 0x76 in the: Adafruit_BME280.h file to get it to work.
So my questions:
1 Did i connected the BME280 sensor the right way?
2 do i have to make a change to the SparkFunBME280.h file to get it working? as my sensor uses the 0x76 address.

Off be one error in getSerialNumber

In getSerial number, there is an off by one error when terminating the string:
{
// request from SCD30
if (ReadFromSCD30(CMD_READ_SERIALNBR, (uint8_t *) val, SCD30_SERIAL_NUM_WORDS * 2) != SCD30_SERIAL_NUM_WORDS * 2) return(false);
val[(SCD30_SERIAL_NUM_WORDS * 2) + 1] = 0x0; // terminate
return(true);
}

It should be:
val[(SCD30_SERIAL_NUM_WORDS * 2)] = 0x0; // terminate

TemperatureOffset

Hi Paul,
I never see any changes if I put the airSensor.setTemperatureOffset((float) 6); line in my programm for the arduino. Is it possible there is a similar problem with the format of the numbers like there was with the readings I never got in my last post? The numbers change like crazy if I put numbers like 200 in the program but these numbers are not right either. Do I have to put 10 in the program to change te reading by one degree?

-Dirk Scheumann

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.