Arduino CO2 Sensor Calibration

Hello,

I'm currently working on a research project that focuses on measuring the pressure level of CO2 in a volume using an Arduino MKR Zero that has a CO2 Sensor attached to it. It is also supposed to save to an SD file. Currently, the program is running smoothly and can be downloaded on the SD port of the MKR Zero. However, from looking at my math, it is estimated the CO2 sensor is measuring over a factor of 10 of what the true CO2 would be. I'm wondering if it has to do with the sensor itself or something with code itself that needs to be changed. Below I've attached what I have thus far.

Additionally, there is also a tendency for when I take the USB port connected to both my computer and Arduino board, that the data does not record and sensor doesn't work. Is this something that is commonly known with the CO2 Sensor or is it something to add into my code as a fail safe. Thank you for the help and I appreciate the time!

#include <Wire.h>
#include <SD.h>
#include "SparkFun_SCD30_Arduino_Library.h"

SCD30 airSensor;

// Valve control
const int valvePin = 7;
const uint16_t co2Threshold = 1000; // ppm
bool valveIsOpen = false;

// SD settings
const int chipSelect = SDCARD_SS_PIN; // Built-in SD pin for MKR ZERO
File dataFile;

void setup() {
  Serial.begin(115200);
  while (!Serial);
  Serial.println("SCD30 MKR ZERO Example with Valve Control and SD Logging");
  delay(1000);

  Wire.begin();

  // Initialize valve pin
  pinMode(valvePin, OUTPUT);
  digitalWrite(valvePin, LOW);

  // Initialize SD card
  Serial.println("Testing SD Card");
   if (SD.begin(chipSelect)) {
    Serial.println("SD card initialization successful!");
   } else {
    Serial.println("SD card initalization failed!");
  }

  // Open or create the log file
  if (!SD.exists("co2log.csv")) {
  dataFile = SD.open("co2log.csv", FILE_WRITE);
  if (dataFile) {
    dataFile.println("Time(ms),CO2(ppm),Temp(C),Humidity(%),ValveState");
    dataFile.close();
  } else {
    Serial.println("Error creating co2log.csv");
  }
} else {
  Serial.println("co2log.csv already exists. Skipping header.");
}

  // Initialize sensor
  if (!airSensor.begin()) {
    Serial.println("Air sensor not detected. Freezing...");
    while(1);

  }
    Serial.println("SCD30 found! Starting measurements...");

  airSensor.setMeasurementInterval(1);
  airSensor.setAltitudeCompensation(1600);
  airSensor.setAmbientPressure(835);
  airSensor.setTemperatureOffset(5);

  Serial.println("Setup complete.");
}

void loop() {
  static unsigned long lastRequest = 0;
  unsigned long intervalMs = airSensor.getMeasurementInterval() * 1000UL;

  
  if (airSensor.dataAvailable()) {
    float co2  = airSensor.getCO2();
    float temp = airSensor.getTemperature();
    float hum  = airSensor.getHumidity();

    String valveState;

    if (co2 < (co2Threshold - 100) && !valveIsOpen) {
  digitalWrite(valvePin, HIGH);
  delay(1000);
  digitalWrite(valvePin, LOW);
  valveIsOpen = true;
  valveState = "OPEN";
  } 
  else if (co2 > (co2Threshold + 100) && valveIsOpen) {
  // Keep valve closed
  valveIsOpen = false;
  valveState = "CLOSED";
  } 
  else {
  // No change in valve state; retain previous state
  valveState = valveIsOpen ? "OPEN" : "CLOSED";
  }
    Serial.print(co2, 1); Serial.print(" :CO2(ppm), ");
    Serial.print(temp, 1); Serial.print(" :Temp(C), ");
    Serial.print(hum, 1); Serial.print(" :Humidity(%) ");
    Serial.println(valveState); Serial.print(" -> Valve, ");

    // Save to SD card
    dataFile = SD.open("co2log.csv", FILE_WRITE);
    if (dataFile) {
      dataFile.print(millis());
      dataFile.print(",");
      dataFile.print(co2, 1);
      dataFile.print(",");
      dataFile.print(temp, 1);
      dataFile.print(",");
      dataFile.print(hum, 1);
      dataFile.print(",");
      dataFile.println(valveState);
      dataFile.close();
    } else {
      Serial.println("Failed to open file for writing.");
    }
  } else {
    Serial.println("Waiting for new data");
  }
  delay(500);
}

Additionally, when I say a factor of 10, I mean the CO2 ppm is read by the arduino as 40000 ppm when it should be 4000 ppm. Also the sensor is a Sensirion CO2 Sensor

What does that mean?
What's the application?
Scd30 is only good for relative low co2 levels, up to few percent.

Also, your pressure compensation indicates that you are located high on the mountains...

The SCD-30 sensor is not intended for measuring CO2 levels below typical atmospheric levels (about 400 PPM) and must be properly calibrated before use.

The Adafruit tutorial is pretty good, so study it carefully: Overview | Adafruit SCD-30 - NDIR CO2 Temperature and Humidity Sensor | Adafruit Learning System