My First Project - Completed! Mostly.

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
Ado
 
Posts: 11
Joined: Thu Feb 02, 2012 7:22 am

My First Project - Completed! Mostly.

Post by Ado »

Hi,

I have been working on a rather ambitious project since this is my first time with the Arduino and C++ programming. I purchased the ARDX Experimental kit, LoL Shield and some sensors from adafruit about 3 or so week ago. I went through all the tutorials and managed to get all the seperate components to work individually but as a next step I wanted to put it all together in to the one project. I purchased a prototyping shield from Freetronics and mounted some headers on the board so I wasn't perminantly mounting the sensors on the shield. The shield has stacking headers on it to so I was able to mount the LoL Shield on top of that too.

So the plan was to have the Arduino, temperature / barometric sensor (BMP085), light sensor (TSL2561), movement sensor (PIR) and the LoL Shield all in one project. Ambitious indeed :!:

How does it work :?:

When you turn on the Arduino it checks it see if the PIR has detected any movement. If it has, it displays some scrolling welcome text on the LoL Shield and then displays the temperature and barometric pressure. As time progresses(configurable), the temp and baro readings will be rechecked and disaplyed on the LoL Shield. If no movement has been detected for a specified amount of time a goodbye message is displayed and everything resets. If movement is detected again, after the reset, it displays the welcome text etc. The light sensor will be used to dim the LEDs in low light situations so you dont blind people. There is a bug in the library that handles the scrolling text and over writes the brightness settings for the LoL Shield grayscale settings. Another bug is that the LoL Shield code seems to stop any comms to the serial monitor, so no Serial.print() works... which was a pain when I was troubleshooting the sensors.

So thats it! I have a few "To-Do's" (perspex case, custom fonts, minor code changes) which I will get to over time but in general the code is complete. :mrgreen:

Code is shown below. Use at your own risk and let me know what you think! :)

Regards,

Ado

Code: Select all

/*
  The below is my first project using the Arduino Uno R3 and sensors purchase from adafruit industries.
  A lot of the code is from the tutorials provided either by adadfruit or oomlout which was then "massaged" to
  work together as one. The code may not be the most effecient of the prettiest!
  
  The design of this project is to display the temperature, barometric pressure readings on a LoL Shield. Also
  using a PIR sensor to enable the device when movement is detected and after a specific amount of time to turn
  off the device to save on power. A light sensor will be utilised to dim the LEDs in low light situations as
  to not be overly bright and blinding.

  adafdruit industries  http://www.adafruit.com
  oomlout  http://www.oomlout.com

  * Environment Sensors Setup (Light, Temperature, Barometric)
  Connect VCC of the BMP085 and TSL2561 sensor to +3.3V (Do NOT use +5v!)
  Connect GND to Ground
  Connect SCL to i2c clock to Analog 5 (A5)
  Connect SDA to i2c data to Analog 4 (A4)
    
  * PIR Sensor (Movement)
  VCC to +5V
  GND to Ground
  OUT to Analog 2 (A2)
  
  *LoL Shield uses all digital outputs (D2-D13)
  
  *** To Do ***
  Figure out better "unsigned char tempText[]" declarations
  Create perspex case to mount everything in to sit on desk or mount on a wall
  Add custom font(arrow up and down) to display when the temp/baro is rising or falling in value
    
  *** BUGS ***
  LoL Shield initialization kills serial output to Serial Monitor
  Bug in Myfont:Banner overwrites LedSign::SetBrightness() settings

*/

// Library
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>   // BMP085 (Temperature/Barometric) Library from adafruit
#include <TSL2561.h>           // TSL2561 (Light) Library from adafruit
#include <Charliplexing.h>     // LoL Shield Library from Jimmie Rodgers  http://jimmieprodgers.com/kits/lolshield/
#include <MyFont.h>            // LoL Shield Font Library from Michael Schwarzer

// PIR Initial Setup and pin allocation to Analog 1
int pirPin = A1;        // PIR Pin allocation
int pirState = LOW;     // Initialize the PIR to Low (Off)
int pirRead = 0;        // Variable for reading the PIR Pin status

// Counters    
int itc = 0; // Idle Time Counter
int trc = 0; // Text Repeat Counter
int trc2 = 0; // Variable to assit TRC calculations
int sleepTime = 300; // Set the idle timer to number of 'n' seconds before going into (sleep) mode
int textRepeat = 30; // Set the repeat timer to redisplay the temperature text. Will repeat the temp/baro every 'n' secs until the sleep counter is hit.

// LED Initial Setup
// The Freetronics Protoboard Pro which I used has 2 LEDs onboard which I use the RED LED to show when the PIR sensor is active.
int ledPin = A0; // Set to analog pin 0

// LED text length of CHAR array
int tLen = 0; // Text length
unsigned char welcomeText[]="Welcome User...\0"; // \0 is required at end of text.
unsigned char tempText[]="Only way I can get this to work but needs to be longer than the total text displayed later in the code. Sloppy indeed. \0"; // This is temporary text. Only way I could get it to work and feed the unsigned char to the LoL Shield
unsigned char goodbyeText[]="Goodbye..."; // \0 is required at end of text.

// Temperature / Barometric Sensor Initialization
Adafruit_BMP085 bmp;
int temp = 0; // Temperature reading value
int baro = 0; // Baromatric reading value

// Light Sensor Initialization
TSL2561 tsl(TSL2561_ADDR_FLOAT);
int lums = 0; // Luminosity reading value

// Setup
void setup(void) {

  Serial.begin(9600); // Set the serial baud rate
  LedSign::Init(GRAYSCALE); // Initialize Lol Shield using Grayscale
  bmp.begin(); // Initialize temp sensor

  tsl.begin(); // Initialize light sensor 
  tsl.setGain(TSL2561_GAIN_16X);
  tsl.setTiming(TSL2561_INTEGRATIONTIME_13MS);
  
  pinMode(pirPin, INPUT);   // PIR pin setup
  pinMode(ledPin, OUTPUT);  // LED ping setup
}

// Rinse and Repeat
void loop() {
  
  pirRead = digitalRead(pirPin);  // Read PIR input pin
  
  if (pirRead == HIGH) { // If the PIR is active
    digitalWrite(ledPin, HIGH);  // Turn LED ON for visual confirmation
    itc = 0; // Reset idle timer counter
    if (pirState == LOW) {
      // We have just turned on from an low (off) state
      pirState = HIGH; // Set the PIR state to high (on)
      trc = 0; // Reset trc
      trc2 = textRepeat; // set trc2 to textRepeat variable value to initialize
      displayWelcomeText(); // Display the welcome text for the first time
      displayTempText(); // Display the temperature
    }
  }
  
  if (pirRead == LOW && itc >= sleepTime && pirState == HIGH) { // If PIR is inactive and idle time counter has reached the desired sleep time.
    digitalWrite(ledPin, LOW); // Turn PIR LED indicator off
    pirState = LOW; // Change PIR state to low (off).
    itc = 0;
    trc = 0;
    displayGoodbyeText(); // Display the temperature
  }
  
  if (trc == trc2 && pirState == HIGH) { // If idle for more than the textRepeat timer
    replayTempText(); // Display basic temp and baro information to Lol Shield
    trc2 = trc2 + textRepeat; // Increment the trc2 counter by the textRepeat variable amount.
  }
  
  trc = trc ++; // increment text repeat counter
  itc = itc ++; // Increment idle time counter
  delay(1000);

}    

// Print welcome text to LoL Shield
void displayWelcomeText() {
  setBrightness();
  tLen=0; // Reset text length variable
  for(int i=0; ; i++){ // Get the length of the text
    if(welcomeText[i]==0){
      tLen=i;
      break;
      }
    }
  Myfont::Banner(tLen,welcomeText); // Send the welcome text to the LoL Shield to be displayed.
}

// Print temperature and barometric pressure text to LoL Shield
void displayTempText() {
  getTemp();
  setBrightness();
  tLen=0; // Reset text length variable
  sprintf((char *)tempText,"The temp is %d*C & barometric pressure is %dpa.",temp, baro);
  for(int i=0; ; i++){ //get the length of the text
    if(tempText[i]==0){
    tLen=i;
    break;
    }
  }
  Myfont::Banner(tLen,tempText); // Send the temperature text to the LoL Shield to be displayed.
}

// Replay temperature and barometric pressure text to LoL Shield
void replayTempText() {
  getTemp();
  setBrightness();
  tLen=0; // Reset text length variable
  sprintf((char *)tempText,"Temp: %d*C / Baro: %dpa.",temp, baro);
  for(int i=0; ; i++){ //get the length of the text
    if(tempText[i]==0){
    tLen=i;
    break;
    }
  }
  Myfont::Banner(tLen,tempText); // Send the temperature text to the LoL Shield to be displayed.
}

// Print goodbye text to LoL Shield
void displayGoodbyeText() {
  setBrightness();
  tLen=0; // Reset text length variable
  for(int i=0; ; i++){ //get the length of the text
    if(goodbyeText[i]==0){
    tLen=i;
    break;
    }
  }
  Myfont::Banner(tLen,goodbyeText); // Send the temperature text to the LoL Shield to be displayed.
}

// Prepares the Luminosity sensor and gets the lux (lums) value.
int getLums(void) { 
  uint16_t x = tsl.getLuminosity(TSL2561_VISIBLE);     
  uint32_t lum = tsl.getFullLuminosity();
  uint16_t ir, full;
  full = lum & 0xFFFF;
  lums = tsl.calculateLux(full, ir);
  // Display output to serial monitor
  Serial.print("Luminosity detected at ");
  Serial.print(lums);
  Serial.println(" lux");
}

// Get the temperature and barometric pressure readings
void getTemp () { 
  temp = bmp.readTemperature(); // Get the temperature reading
  // Display output to serial monitor
  Serial.print("Temperature = ");
  Serial.print(temp);
  Serial.println(" *C");
  
  delay(100);
  baro = (bmp.readPressure() / 100 + 3); // Get the barometric pressure reading and modify for localized sea level pressure readings.
  // Display output to serial monitor
  Serial.print("Pressure = ");
  Serial.print(baro);
  Serial.println(" Pa");
}

// Set brightness level of display based on lux levels. 1 = Lowest 7 = Highest 0 = Off
void setBrightness() { 
  getLums();
  if (lums <= 5) {
    LedSign::SetBrightness(1);
  } else if (lums > 5 && lums , 100) {
    LedSign::SetBrightness(4);
  } else {
    LedSign::SetBrightness(7);
  }
}

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”