Customer Check-in

I’m trying out O Snap! on an old iPhone.

I put the iPhone right on the Grow Chamber’s leaf shelf.  I set the timer to go off once an hour.  Within the O Snap! app I created a .mov and shared it on YouTube.  Not that great, but it’s a start.  I’ll try mounting the iPhone on the LED shelf.

First Run

I imported the log file into the 3/2/2017 sheet of the Test Run Log Files spreadsheet.

The run starts at 12:40:20 3/2/2017 (row 5).  


Expected:  Readings every 2 minutes

Simpson DOH Not As Expected

debug = 0;  
globalSettings.secsBtwnReadings = (debug == 1) ? 60 : 2 * 60; 

Readings were taken every minute.

WhyCat Why?

The firmware’s logic is to use what is stored in the EEPROM unless the writeCheck value changes.

  if (globalSettings.writeCheck != eepromWriteCheck) {

but in resetGlobalSettings(), I am using DEBUG to change global settings values:

void resetGlobalSettings() {
  bool debug = true;
#ifndef DEBUG
  debug = false;
  DEBUG_PRINTLNF("In resetGlobalSettings()");
  globalSettings.writeCheck = eepromWriteCheck;
  globalSettings.secsBtwnReadings = (debug == 1) ? 60 : 2 * 60;  //if in debug mode, make the period between readings short.
  globalSettings.targetCO2Level = 1200;
  globalSettings.amtSecsWaterPumpIsOn = (debug == 1) ? 5 :  60; //amount of seconds for pump to be ON.
  globalSettings.secsBetweenTurningPumpON = (debug == 1) ? 60 :  15 * 60; //# secs between turning pump ON.
  globalSettings.hourToTurnLightOff = 0; //Turn light off at midnight.
  globalSettings.hourToTurnLightOn = 4; //Turn light on at 4AM.
  eeprom_write_block(&globalSettings, (void *)0, sizeof(globalSettings)); //write settings to eeprom

The reason I used EEPROM to store global settings was the earlier thought I would allow the user to change global settings on the fly through a UI (either Internet or buttons).  Right now, I do not allow user input.  I could remove the code to EEPROM, but instead I added:

#ifdef DEBUG
#define eepromWriteCheck 0x1234
#define eepromWriteCheck 0x5678

This way, the write check bytes in EEPROM will change when the definition of DEBUG changes.


Expected: if readings < 1200ppm, add CO2.

ChallengesBringOpportunitesYIPPEE! Worked as Expected

void adjustCO2() {
  if (fLEDon) {
    int CO2Value = takeCO2Reading();
    if (CO2Value > 0 && CO2Value <= 1200) { // -1 is returned if the sensor isn't working correctly.
      //Got a good reading that is below 1200 ppm so turn on the CO2.  It is assume the valve is opened just
      //a little bit. Leave the valve on for less time as the value gets closer to 1200
      int nSecondsValveIsOpen = 0;
      CO2Value < 800 ? nSecondsValveIsOpen = 10 : nSecondsValveIsOpen = 5;
      digitalWrite(CO2Pin, ON);
      Alarm.timerOnce((const unsigned long)nSecondsValveIsOpen, turnCO2Off);
    } else {
      DEBUG_PRINTLNF("The LED is off - no need to adjust");


Expected: LEDs should be off for four hours between 12AM and 3:59:59 AM.

ChallengesBringOpportunitesYIPPEE! Worked as Expected

  • The  LEDs are turned on after the 3 minute warm up at 12:43:20.  
  • The LEDs are turned off at 0:00:00  
  • The LEDs are turned back on at 4:00:00

2nd Run

I deleted the log file from the SD card, put the SD Card back into the Arduino, and uploaded the updated code.  

ChallengesBringOpportunitesYippee!  All Worked as Expected

I decided to adjust the amount of time the CO2 regulator is on to a little higher:

      CO2Value < 800 ? nSecondsValveIsOpen = 13 : nSecondsValveIsOpen = 8 

3rd Run

I let the system run from 12PM to close to 4AM.    I :

  • expect no CO2 to be released between 12AM and 3:59AM.
  • am interested in the temperatures at night.
  • want to fix any other issues shown by the data.

CO2 Off Based on LED ON/OFF

ChallengesBringOpportunites YIPPEE!  As Expected.  No CO2 is released between 12AM and 3:59AM.

Differences in LED ON vs. LED OFF Measurements

I took the average of measurements when the LED was ON and when it was OFF.  Another variable is we turn the heat off at night.  The indoor temperature goes from 21.11˚C during the day to 15.56˚C during the night.  Here are the averages for the 3/3/2017 – 3rd Run:

Lights ON    
Average Temp Avg Humidity Avg CO2
29.88 35.76 1267.16
Lights OFF    
18.76 56.31 313.05

The average measurements are what I expected.  Close to ambient CO2, a higher humidity. The higher humidity makes sense because when the LED is off, respiration should increase relative to transpiration.

Additional Issues

Bug in Adjusting the CO2 Code

Simpson DOHMy code was incorrect in the case the MH-Z16 CO2 sensor couldn’t take a reading (i.e.: returned -1).  I updated the adjustCO2() function to:

void adjustCO2(int CO2Value) {
  if (fLEDon) {
    if (CO2Value < 0) { // The MH-Z16 returns a -1 when it couldn't get a valid reading.
      DEBUG_PRINTLNF("Could not get a valid CO2 reading - no adjustment made");
    if (CO2Value <= 1200) {
      //Got a good reading that is below 1200 ppm so turn on the CO2.  It is assume the valve is opened just
      //a little bit. Leave the valve on for less time as the value gets closer to 1200
      int nSecondsValveIsOpen = 0;
      CO2Value < 800 ? nSecondsValveIsOpen = 13 : nSecondsValveIsOpen = 8;
      digitalWrite(CO2Pin, ON);
      Alarm.timerOnce((const unsigned long)nSecondsValveIsOpen, turnCO2Off);
  }else {
      DEBUG_PRINTLNF("The LED is off - no adjustment made");    


Leak 1

hmmm….looks like there is a small leak:

Pasted Image 3 3 17 10 51 AM

I’m noticing drips coming from a drip irrigation bib.

I fixed this leak by spreading silicone over the hole.  


The challenge is getting the silicone to the hole since at this point the hose is within a tight space on top of the gutters and below the plant’s shelf.

Leak 2

Fixing Leak 1 led me to find leak 2.

Pasted Image 3 4 17 12 51 PM 

Time Lapse

As shown by the 3 frame Youtube video under Customer Check-In, I ran my first test of producing a time lapse movie.

I used an old iPhone I found kicking around our house, loaded O Snap! as well as the WiFi transfer extension pack…although I’m not sure I need the extension pack for what I ultimately ended up doing, which was to upload the time lapse movie to YouTube.

First Attempt – Camera Sitting On Leaf Shelf

I’m trying to figure out the best placement of the camera.  In the first attempt, I placed the camera on the leaf shelf.  This gives a lilliputian’s view but not even close to a best placement.  For my second attempt, I will shorten the time between taking an image to 5 minutes.  For the second attempt, I will mount the camera on the LED shelf.

Well…hmmm…I’m on my third attempt..more on this in another log!  For now, time to go.