Up and Running
I have the Sensirion SCD30 sensor connected up to my Arduino Yun, so just a quick update.
Below you’ll find a quick hand sketch showing the connection to hook up the sensor. In the the middle the “BOB-12009” handles the level translation from the Arduino DIO 5V signal level to the 3.3V signal level of the CO2 Sensor.
The sensors are reading within a few counts of each other. I did an outdoor calibration on the SCD30 last night, and I turned off automatic background calibration. Reading the doc, for the automatic background calibration to work, it wants to see fresh air for 1hr once a day. I don’t think it will ever see that.
#include <SparkFun_SCD30_Arduino_Library.h>
#include <Wire.h> //I2C needed for sensors
#include <FileIO.h>
#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>
#include <SoftwareSerial.h>
SCD30 airSensor;
//SCD30 Sensor is connected to D2 & D3 for I2C use.
//Bi-level logic converter used to convert the Yun 5V logic level to 3.3V for SCD30
//The 7 segment display is connected to D9 for serial control
const int softwareTx = 9;
const int softwareRx = 8;
SoftwareSerial s7s(softwareRx, softwareTx);
//Set up global variables to store readings
//Continuouslu update the globals on every loop when data is available
float humidity = 0; // [%]
float temperature = 0; // [temperature C]
uint16_t CO2Level = 0;
//These are used to either log or switch (Blink) the display at a fixed interval
unsigned long previousMillisLog;
unsigned long previousMillisBlink;
bool firstPass = true;
bool showTemp = true;
YunServer server;
//Setup gets called once on load
void setup()
{
Bridge.begin(); //Setup link between linux side and arduino side
Serial.begin(9600); //Configure serial port
FileSystem.begin(); // Setup the file system on the linux side
Wire.begin(); //Startup the I2C comms
airSensor.begin(Wire,false); //startup the SCD30 but disable auto background cal. It wants to see fresh air for 1hr every day
s7s.begin(9600); //Startup 7 segment display
Serial.println("Temperature Monitor online!");
server.listenOnLocalhost(); //Have the webserver start listening to requests
server.begin();
File dataFile = FileSystem.open("/mnt/sd/datalog.txt", FILE_APPEND);
delay(2000);
// if the file is available, write to it:
if (dataFile) {
dataFile.println("Logging Begins");
dataFile.close();
}
previousMillisLog = millis();
previousMillisBlink = millis();
logMeasurements();
clearDisplay(); // Clears display, resets cursor
//s7s.print("-HI-"); // Displays -HI- on all digits
//setDecimals(0b111111); // Turn on all decimals, colon, apos
}
void loop()
{
char tempString[10];
int tempf;
// Get clients coming from server
YunClient client = server.accept();
// There is a new client?
if (client) {
// Process request
process(client);
// Close connection and free resources.
client.stop();
}
if (firstPass == true)
{
firstPass = false;
File dataFile = FileSystem.open("/mnt/sd/datalog.txt", FILE_APPEND);
//delay(2000);
// if the file is available, write to it:
if (dataFile) {
dataFile.println("Logging Begins");
dataFile.close();
}
}
//Every 30 Seconds log to file
if(millis() - previousMillisLog > 30000)
{
previousMillisLog = millis();
logMeasurements();
}
//Every 5 seconds update display
if(millis() - previousMillisBlink > 5000)
{
previousMillisBlink = millis();
if (showTemp)
{
showTemp = false; //Next time show CO2
tempf = (temperature)*10; //Doing this to show decimal plave on display
sprintf(tempString, "%4d", tempf);
s7s.print(tempString);
setDecimals(0b00000100);
}
else
{
showTemp = true; //Next time show temperature
tempf = CO2Level;
sprintf(tempString, "%4d", tempf);
s7s.print(tempString);
setDecimals(0b00000000);
}
}
if (airSensor.dataAvailable())
{
CO2Level = airSensor.getCO2();
temperature = airSensor.getTemperature();
humidity = airSensor.getHumidity();
}
delay(50);
}
void process(YunClient client) {
// read the command
String command = client.readStringUntil('/');
Serial.println(command);
if (command.startsWith("temp"))
if (command.startsWith("cal"))
}
void tempCommand(YunClient client) {
String dataString;
float voltage, degreesC, degreesF;
dataString += getTimeStamp();
dataString += "\n Humidity = ";
Serial.println("Hello!");
client.println("Request Received");
dataString += humidity;
dataString += " pct \n Temp = ";
dataString += (temperature);
dataString += " \n CO2 = ";
dataString += CO2Level;
dataString += " ppm";
// Send feedback to client
client.println(dataString);
}
void calCommand(YunClient client) {
String dataString;
float voltage, degreesC, degreesF;
dataString += getTimeStamp();
dataString += "\n Calibrated ";
airSensor.setForcedRecalibrationFactor(400);
client.println("Request Received");
// Send feedback to client
client.println(dataString);
}
String getTimeStamp() {
String result;
Process time;
// date is a command line utility to get the date and the time
// in different formats depending on the additional parameter
time.begin("date");
time.addParameter("+%D-%T"); // parameters: D for the complete date mm/dd/yy
// T for the time hh:mm:ss
time.run(); // run the command
// read the output of the command
while(time.available()>0) {
char c = time.read();
if(c != '\n')
result += c;
}
return result;
}
//Prints the various variables directly to the port
//I don't like the way this function is written but Arduino doesn't support floats under sprintf
void logMeasurements()
{
String dataString;
//float voltage, degreesC, degreesF;
dataString += getTimeStamp();
dataString += ",";
dataString += humidity;
dataString += ",";
dataString += temperature;
dataString += ",";
dataString += CO2Level;
File dataFile = FileSystem.open("/mnt/sd/datalog.txt", FILE_APPEND);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}
void clearDisplay()
{
s7s.write(0x76); // Clear display command
}
void setDecimals(byte decimals)
{
s7s.write(0x77);
s7s.write(decimals);
}