Tuesday, March 1, 2016

YellowJacket Arduino with WiShield Wifi (Part 7)

A dedicated Sensor Shield was fabricated for prototyping various sensor circuits. The Sensor Shield will be used as a data source for sending data over wifi using the YellowJacket Wifi boards. The Sensor Shield also stacks with the SD Card Shield for use as a Data Logger.
The first sensor circuits on the Sensor Shield were those described for the Adafruit Data Logger Shield (SD Card Shield) (Ref: https://learn.adafruit.com/adafruit-data-logger-shield/light-and-temperature-logger-use-it). The Sensor Shield also has a green LED that can be used as a visual sensor state indicator, and a push button switch that can serve as a switch sensor. Other sensors can be added as needed.
The Sensor Shield has a voltage jumper from either 5V0 or 3V3 to AREF which also powers the TEMP and PHOTOCELL sensors. The TEMP sensor is connected to pin A0 and the PHOTOCELL sensor is connected to pin A1. Either 5V0 or 3V3 must be chosen with the on-board AREF jumper for those sensors to get power. The AREF voltage on the Sensor Shield also powers the red power LED ON. The AREF voltage used on the Shield is the value which is used as the AREF voltage in a sketch using the sensors. The AREF pin voltage will propagate through to other Shields that are backpacked together, so make sure AREF is only set on one Shield or board.
The Sensor Shield green led is ON when the green jumper wire is connected to HIGH and can be used as a state indicator sensor (pin 5 On/Off).
The button switch connects the white jumper wire to Gnd when pushed. This button can set a hardware interrupt pin (INT0-pin 2 or INT1-pin 3) as a door_open/set sensor. In this photo, the INT1-pin 3 side of the button is held HIGH through a 10K resistor to AREF voltage or through software using “pinMode(buttonPin, INPUT_PULLUP);”.
The Sensor Shield has a 7-12V input socket to power Vin on any boards that are backpacked together. Vin is not currently converted to 5V or 3V on this Sensor Shield. The YellowJacket Shields can use this Vin as RAW voltage to place +5V and +3.3V on the appropriate voltage pins for the Shield stack.
The Sensor Shield was connected to a YellowJacket Shield for gathering temperature and photocell values. It also can send/receive the Green LED state over Wifi, and the push button connected to INT1 can send/receive whether the button has been pushed.
Temperature-Light Sensor Sketch
Hardware Setup –
  • YJ Shield
  • Sensor Shield
  • USB/FTDI programming cable from Mac to YJ Shield
Software – This sketch is a modification of the AdaFruit Data Logger Use It! Sensor Test tutorial (Ref: https://learn.adafruit.com/adafruit-data-logger-shield/light-and-temperature-logger-use-it)
/* 
 * light_temp_sensors_01
 *
 * This sketch works with the Sensor Shield, Adafruit SD Card Shield, 
 * and Arduino UNO Shield or YellowJacket Shield (2016-02-27)
 * 
 * Sensor test sketch
 * Ref: https://learn.adafruit.com/adafruit-data-logger-shield
 * 
 * Example output:
 *  Light reading = 441 - Light
 *  Temp reading = 230 - 0.74 volts
 *  24.12 degrees C
 *  75.42 degrees F
 * 
 */
// Sensor Shield has wire from 5V to ARef.
// UNO board can use the ARef connection.
// YellowJacket does not have ARef pin connected.
//
//#define aref_voltage 3.3       // if 3.3V is connected to ARef
#define aref_voltage 5.0         // default internal 5V to ARef

int photocellPin = 1;     // the cell and 10K pulldown are connected to a0
int photocellReading;     // the analog reading from the analog resistor divider

//TMP36 Pin Variables
int tempPin = 0;        //the analog pin the TMP36's Vout (sense) pin is connected to
                        //the resolution is 10 mV / degree centigrade with a
                        //500 mV offset to allow for negative temperatures
int tempReading;        // the analog reading from the sensor
    
void setup(void) {
  // We'll send debugging information via the Serial monitor
  Serial.begin(115200);   

  // If you want to set the aref to something other than 5v
  //analogReference(EXTERNAL); // enable EXTERNAL if using 3.3 AREF, ie, SD Card Shield and UNO
    analogReference(DEFAULT);  // DEFAULT for no external AREF, ie, SD Card Shield and YellowJacket
}


void loop(void) {
  photocellReading = analogRead(photocellPin);  

  Serial.println(" "); // blank line
   
  Serial.print("Light reading = ");
  Serial.print(photocellReading);     // the raw analog reading
  
  // We'll have a few thresholds, qualitatively determined
  if (photocellReading < 10) {
    Serial.println(" - Dark");
  } else if (photocellReading < 200) {
    Serial.println(" - Dim");
  } else if (photocellReading < 500) {
    Serial.println(" - Light");
  } else if (photocellReading < 800) {
    Serial.println(" - Bright");
  } else {
    Serial.println(" - Very bright");
  }
  
  tempReading = analogRead(tempPin);  
  
  Serial.print("Temp reading = ");
  Serial.print(tempReading);     // the raw analog reading
  
  // converting that reading to voltage, which is based off the reference voltage
  float voltage = tempReading * aref_voltage / 1024; 
 
  // print out the voltage
  Serial.print(" - ");
  Serial.print(voltage); Serial.println(" volts");
 
  // now print out the temperature
  float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
                                               //to degrees ((voltage - 500mV) times 100)
  Serial.print(temperatureC); Serial.println(" degrees C");
 
  // now convert to Fahrenheit
  float temperatureF = (temperatureC * 9 / 5) + 32;
  Serial.print(temperatureF); Serial.println(" degrees F");
 
  delay(1000);
}

Serial Monitor display: Sensor values change by blocking light to photocell or by using body heat to increase the temperature sensor reading:
Light reading = 555 - Bright
Temp reading = 150 - 0.73 volts
23.24 degrees C
73.84 degrees F
... (block light)
Light reading = 279 - Light
Temp reading = 150 - 0.73 volts
23.24 degrees C
73.84 degrees F
... (touch temperature sensor to increase temperature)
Light reading = 398 - Light
Temp reading = 152 - 0.74 volts
24.22 degrees C
75.59 degrees F

Adding the SD Card Shield as a Data Logger
Hardware Setup –
  • YJ Shield
  • Sensor Shield
  • SD Card Shield
  • USB/FTDI programming cable from Mac to YJ Shield
Software – The following sketch is a modification of the AdaFruit Data Logger Shield tutorial (Ref: https://learn.adafruit.com/adafruit-data-logger-shield/using-the-real-time-clock-3)
The sketch reads data from the sensors on the Sensor Shield and writes the data to a file on the SD Card.
/*
 * Light_and_Temp_Log_to_File
 * 
 * Data Logger test sketch
 * for more information see https://learn.adafruit.com/adafruit-data-logger-shield
 * Ref: https://learn.adafruit.com/adafruit-data-logger-shield/using-the-real-time-clock-3
 * 
 * 
 * Example Serial Monitor output:
 * 
 * Initializing SD card...card initialized.
 * Logging to: LOGGER01.CSV
 * millis,stamp,datetime,light,temp,vcc
 * 998, 1441706750, "2015/9/8 10:5:50", 278, 74.84, 4.08
 * 1999, 1441706751, "2015/9/8 10:5:51", 275, 74.84, 4.07
 * 2998, 1441706752, "2015/9/8 10:5:52", 275, 74.84, 4.07
 * 
 */

#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"


// A simple data logger for the Arduino analog pins

// how many milliseconds between grabbing data and logging it. 1000 ms is once a second
#define LOG_INTERVAL  1000 // mills between entries (reduce to take more/faster data)

// how many milliseconds before writing the logged data permanently to disk
// set it to the LOG_INTERVAL to write each time (safest)
// set it to 10*LOG_INTERVAL to write all data every 10 data reads, you could lose up to
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()

#define ECHO_TO_SERIAL   1 // echo data to serial port
#define WAIT_TO_START    0 // Wait for serial input in setup()

// the digital pins that connect to the LEDs
#define redLEDpin 4
#define greenLEDpin 3

// The analog pins that connect to the sensors
#define photocellPin 1           // analog 1
#define tempPin 0                // analog 0
#define BANDGAPREF 14            // special indicator that we want to measure the bandgap

#define aref_voltage 5.0         // default=5V on UNO; Aref set to 5V on Sensor Shield
//#define aref_voltage 3.3       // or 3.3V to ARef can be set on the Sensor Shield
#define bandgap_voltage 1.1      // this is not super guaranteed but its not -too- off

RTC_DS1307 RTC; // define the Real Time Clock object

// for the data logging shield, we use digital pin 7 for the SD CS line
const int chipSelect = 7;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);

  // red LED indicates error
  digitalWrite(redLEDpin, HIGH);

  while (1);
}

void setup(void)
{
  Serial.begin(115200);
  Serial.println();

  // use debugging LEDs
  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);

#if WAIT_TO_START
  Serial.println("Type any character to start");
  while (!Serial.available());
#endif //WAIT_TO_START

  // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(chipSelect, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");

  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i / 10 + '0';
    filename[7] = i % 10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!
    }
  }

  if (! logfile) {
    error("couldn't create file");
  }

  Serial.print("Logging to: ");
  Serial.println(filename);

  // connect to RTC
  Wire.begin();
  if (!RTC.begin()) {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif  //ECHO_TO_SERIAL
  }


  logfile.println("millis,stamp,datetime,light,temp,vcc");
#if ECHO_TO_SERIAL
  Serial.println("millis,stamp,datetime,light,temp,vcc");
#endif //ECHO_TO_SERIAL

  // If you want to set the aref to something other than 5v
  // analogReference(EXTERNAL); // for 3.3V ARef
  analogReference(DEFAULT);
}

void loop(void)
{
  DateTime now;

  // delay for the amount of time we want between readings
  delay((LOG_INTERVAL - 1) - (millis() % LOG_INTERVAL));

  digitalWrite(greenLEDpin, HIGH);

  // log milliseconds since starting
  uint32_t m = millis();
  logfile.print(m);           // milliseconds since start
  logfile.print(", ");
#if ECHO_TO_SERIAL
  Serial.print(m);         // milliseconds since start
  Serial.print(", ");
#endif

  // fetch the time
  now = RTC.now();
  // log time
  logfile.print(now.unixtime()); // seconds since 1/1/1970
  logfile.print(", ");
  logfile.print('"');
  logfile.print(now.year(), DEC);
  logfile.print("/");
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.day(), DEC);
  logfile.print(" ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC);
  logfile.print('"');
#if ECHO_TO_SERIAL
  Serial.print(now.unixtime()); // seconds since 1/1/1970
  Serial.print(", ");
  Serial.print('"');
  Serial.print(now.year(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
  Serial.print('"');
#endif //ECHO_TO_SERIAL

  analogRead(photocellPin);
  delay(10);
  int photocellReading = analogRead(photocellPin);

  analogRead(tempPin);
  delay(10);
  int tempReading = analogRead(tempPin);

  // converting that reading to voltage, for 3.3v arduino use 3.3, for 5.0, use 5.0
  float voltage = tempReading * aref_voltage / 1024;
  float temperatureC = (voltage - 0.5) * 100 ;
  float temperatureF = (temperatureC * 9 / 5) + 32;

  logfile.print(", ");
  logfile.print(photocellReading);
  logfile.print(", ");
  logfile.print(temperatureF);
#if ECHO_TO_SERIAL
  Serial.print(", ");
  Serial.print(photocellReading);
  Serial.print(", ");
  Serial.print(temperatureF);
#endif //ECHO_TO_SERIAL

  // Log the estimated 'VCC' voltage by measuring the internal 1.1v ref
  analogRead(BANDGAPREF);
  delay(10);
  int refReading = analogRead(BANDGAPREF);
  float supplyvoltage = (bandgap_voltage * 1024) / refReading;

  logfile.print(", ");
  logfile.print(supplyvoltage);
#if ECHO_TO_SERIAL
  Serial.print(", ");
  Serial.print(supplyvoltage);
#endif // ECHO_TO_SERIAL

  logfile.println();
#if ECHO_TO_SERIAL
  Serial.println();
#endif // ECHO_TO_SERIAL

  digitalWrite(greenLEDpin, LOW);

  // Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();

  // blink LED to show we are syncing data to the card & updating FAT!
  digitalWrite(redLEDpin, HIGH);
  logfile.flush();
  digitalWrite(redLEDpin, LOW);

}


Serial Monitor display of sketch output:
Initializing SD card...card initialized.
Logging to: LOGGER01.CSV
millis,stamp,datetime,light,temp,vcc
14999, 1463985836, "2016/3/3 6:43:56", 569, 74.71, 7.46
16000, 1463985837, "2016/3/3 6:43:57", 568, 73.84, 7.46
16999, 1463985838, "2016/3/3 6:43:58", 569, 74.71, 7.46
17998, 1463985839, "2016/3/3 6:43:59", 570, 73.84, 7.51
18999, 1463985840, "2016/3/3 6:44:0", 570, 74.71, 7.46
19998, 1463985841, "2016/3/3 6:44:1", 570, 74.71, 7.46

Example data written to SD Card file LOGGER01.CSV:
millis,stamp,datetime,light,temp,vcc
14999, 1463985836, "2016/5/23 6:43:56", 569, 74.71, 7.46
16000, 1463985837, "2016/5/23 6:43:57", 568, 73.84, 7.46
16999, 1463985838, "2016/5/23 6:43:58", 569, 74.71, 7.46
17998, 1463985839, "2016/5/23 6:43:59", 570, 73.84, 7.51
18999, 1463985840, "2016/5/23 6:44:0", 570, 74.71, 7.46
19998, 1463985841, "2016/5/23 6:44:1", 570, 74.71, 7.46
(Mar 1, 2016)





No comments:

Post a Comment