/* ////////////////////////////////////////////////////////////////// ARDUINO/Genuino Project "MADIMOD-77110", Environmental Monitoring https://www.changpuak.ch/electronics/Arduino-Madimod-77110-I2C.php Software Version 21.0 CO2 Sensor, Sensirion SCD30 25.07.2025 by ALEXANDER SSE FRANK The Serial Parser was written by Christian Monstein, used in "Easy_Diseqc V1.2", Monstein ETH Zurich, 20.06.2018 ////////////////////////////////////////////////////////////////// */ #include #include #include #include Adafruit_SCD30 scd30; #define SENSORTYPE "CO2" // DISPLAY #define OLED_MOSI 11 #define OLED_CLK 13 #define OLED_DC 9 #define OLED_CS 8 #define OLED_RESET 10 bool OLED_UPSIDE_DOWN = false ; Adafruit_SH1106 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); #if (SH1106_LCDHEIGHT != 64) #error("Height incorrect, please fix Adafruit_SH1106.h!"); #endif int BeepPin = 5 ; bool DEBUG = false ; // SERIAL COMMUNICATION String buffer ; // SENSOR ATTACHED int SENSOR_TYPE = 3023 ; int EEPROMADR = 0x50 ; float co2Concentration = 0.0 ; float temperature = 0.0 ; float humidity = 0.0 ; const int POSHUM = 89 ; unsigned int d = 0x0000 ; // ///////////////////////////////////////////////////////////////////// // SUBROUTINES SENSOR // ///////////////////////////////////////////////////////////////////// void I2CScan() { byte error, address ; for(address = 1; address < 127; 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.println(address,HEX); } } } void MEASURE() { if (scd30.dataReady()) { if (!scd30.read()) { Serial.println("Error reading sensor data"); return; } temperature = scd30.temperature ; humidity = scd30.relative_humidity ; co2Concentration = scd30.CO2 ; } else { temperature = 0.0 ; humidity = 0.0 ; co2Concentration = 999.9 ; } } // ///////////////////////////////////////////////////////////////////// // SUBROUTINES DISPLAY. // ///////////////////////////////////////////////////////////////////// void UpDateDisplay() { display.clearDisplay() ; display.setTextSize(1) ; display.setTextColor(WHITE) ; display.setCursor(0, 0) ; display.print("MADIMOD-77110-I2C-") ; display.print(SENSORTYPE) ; display.drawLine(0, 12, 128, 12, WHITE) ; display.drawLine(0, 63, 128, 63, WHITE) ; display.setCursor(0, 21) ; display.setTextSize(2) ; if(co2Concentration < 10000.0) display.print(" ") ; if(co2Concentration < 1000.0) display.print(" ") ; if(co2Concentration < 100.0) display.print(" ") ; if(co2Concentration < 10.0) display.print(" ") ; display.print(co2Concentration,0) ; display.print(" PPM") ; display.setCursor(0, 42) ; // if(temperature < 0.0) display.print("-") ; if(temperature > 0.0) display.print("+") ; // if(temperature = 0.0) display.print(" ") ; display.print(temperature,1) ; display.setCursor(70, 42) ; display.print("C") ; // DEGREE CIRCLE display.drawCircle(64, 45, 3, 1); display.drawCircle(64, 45, 2, 1); display.setCursor(POSHUM, 42) ; display.print(humidity,0) ; display.setCursor(POSHUM+27, 42) ; display.print("%") ; display.display() ; } // ///////////////////////////////////////////////////////////////////// // SUBROUTINES BEEPER // ///////////////////////////////////////////////////////////////////// const unsigned int BEEPlength = 99 ; void BEEP(unsigned int data) { unsigned int pointer = 0 ; for(int i=31; i>0; i--) { pointer = (1 << i) ; if((pointer & data) > 0) digitalWrite(BeepPin, HIGH) ; else digitalWrite(BeepPin, LOW) ; delay(BEEPlength) ; } digitalWrite(BeepPin, LOW) ; // JUST IN CASE :-) } // ///////////////////////////////////////////////////////////////////// // S E T U P // ///////////////////////////////////////////////////////////////////// void setup() { // START SERIAL COMMUNICATIONS Serial.begin(115200) ; // START WIRE - I2C Wire.begin() ; // START OLED display.begin(SH1106_SWITCHCAPVCC); if(OLED_UPSIDE_DOWN) display.setRotation(2) ; // 180 degrees // SHOW STARTUP SCREEN display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.println("MADIMOD-77110-I2C") ; display.drawLine(0, 12, 128, 12, WHITE) ; display.setTextSize(1) ; display.setCursor(0, 20) ; display.println("ARDUINO/GENUINO BASED") ; display.setCursor(0, 32) ; display.println("ENVIRONMENTAL MONITOR") ; display.setCursor(0, 44) ; display.println("(C) WWW.CHANGPUAK.CH") ; display.setCursor(0, 56) ; display.println("BUILT 05.12.2025") ; display.display() ; delay(999) ; // BEEPER BEGIN pinMode(BeepPin, OUTPUT) ; digitalWrite(BeepPin, HIGH) ; delay(499) ; digitalWrite(BeepPin, LOW) ; // CHECK SENSOR I2CScan() ; // Try to initialize! if (!scd30.begin()) { Serial.println("Failed to find SCD30 chip"); while (1) { delay(10); } } Serial.println("SCD30 Found!"); // if (!scd30.setMeasurementInterval(10)){ // Serial.println("Failed to set measurement interval"); // while(1){ delay(10);} // } Serial.print("Measurement Interval: ") ; Serial.print(scd30.getMeasurementInterval()) ; Serial.println(" seconds") ; } // ///////////////////////////////////////////////////////////////////// // M A I N L O O P // ///////////////////////////////////////////////////////////////////// void loop() { // ///////////////////////////////////////////////////////////////// // CHECK SERIAL PORT if (Serial.available() > 0) // ///////////////////////////////////////////////////////////////// { buffer = Serial.readString() ; // /////////////////////////////////////////////////////// if (buffer.startsWith("*IDN?")) // /////////////////////////////////////////////////////// { Serial.println("MADIMOD-77110-I2C BY CHANGPUAK.CH") ; } else // /////////////////////////////////////////////////////// if (buffer.startsWith("HELP")) // /////////////////////////////////////////////////////// { Serial.println("> HELP"); Serial.println("RTFM."); } buffer = "" ; // erase buffer for next command } delay(2999) ; MEASURE() ; UpDateDisplay() ; } // ///////////////////////////////////////////////////////////// // END OF FILE. // /////////////////////////////////////////////////////////////