Initializing TM repository
This commit is contained in:
commit
d4f1f57a01
290
arduino/libraries/sensors/BMP085.cpp
Normal file
290
arduino/libraries/sensors/BMP085.cpp
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
/***************************************************
|
||||||
|
This is a library for the BMP085 Barometric Pressure & Temp Sensor
|
||||||
|
|
||||||
|
Designed specifically to work with the Adafruit BMP085 Breakout
|
||||||
|
----> https://www.adafruit.com/products/391
|
||||||
|
|
||||||
|
These displays use I2C to communicate, 2 pins are required to
|
||||||
|
interface
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit and open-source hardware by purchasing
|
||||||
|
products from Adafruit!
|
||||||
|
|
||||||
|
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||||
|
BSD license, all text above must be included in any redistribution
|
||||||
|
****************************************************/
|
||||||
|
|
||||||
|
#include "BMP085.h"
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
BMP085::BMP085() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BMP085::begin(uint8_t mode) {
|
||||||
|
if (mode > BMP085_ULTRAHIGHRES)
|
||||||
|
mode = BMP085_ULTRAHIGHRES;
|
||||||
|
oversampling = mode;
|
||||||
|
|
||||||
|
Wire.begin();
|
||||||
|
|
||||||
|
/* read calibration data */
|
||||||
|
ac1 = read16(BMP085_CAL_AC1);
|
||||||
|
ac2 = read16(BMP085_CAL_AC2);
|
||||||
|
ac3 = read16(BMP085_CAL_AC3);
|
||||||
|
ac4 = read16(BMP085_CAL_AC4);
|
||||||
|
ac5 = read16(BMP085_CAL_AC5);
|
||||||
|
ac6 = read16(BMP085_CAL_AC6);
|
||||||
|
|
||||||
|
b1 = read16(BMP085_CAL_B1);
|
||||||
|
b2 = read16(BMP085_CAL_B2);
|
||||||
|
|
||||||
|
mb = read16(BMP085_CAL_MB);
|
||||||
|
mc = read16(BMP085_CAL_MC);
|
||||||
|
md = read16(BMP085_CAL_MD);
|
||||||
|
#if (BMP085_DEBUG == 1)
|
||||||
|
Serial.print("ac1 = "); Serial.println(ac1, DEC);
|
||||||
|
Serial.print("ac2 = "); Serial.println(ac2, DEC);
|
||||||
|
Serial.print("ac3 = "); Serial.println(ac3, DEC);
|
||||||
|
Serial.print("ac4 = "); Serial.println(ac4, DEC);
|
||||||
|
Serial.print("ac5 = "); Serial.println(ac5, DEC);
|
||||||
|
Serial.print("ac6 = "); Serial.println(ac6, DEC);
|
||||||
|
|
||||||
|
Serial.print("b1 = "); Serial.println(b1, DEC);
|
||||||
|
Serial.print("b2 = "); Serial.println(b2, DEC);
|
||||||
|
|
||||||
|
Serial.print("mb = "); Serial.println(mb, DEC);
|
||||||
|
Serial.print("mc = "); Serial.println(mc, DEC);
|
||||||
|
Serial.print("md = "); Serial.println(md, DEC);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t BMP085::readRawTemperature(void) {
|
||||||
|
write8(BMP085_CONTROL, BMP085_READTEMPCMD);
|
||||||
|
_delay_ms(5);
|
||||||
|
#if BMP085_DEBUG == 1
|
||||||
|
Serial.print("Raw temp: "); Serial.println(read16(BMP085_TEMPDATA));
|
||||||
|
#endif
|
||||||
|
return read16(BMP085_TEMPDATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t BMP085::readRawPressure(void) {
|
||||||
|
uint32_t raw;
|
||||||
|
|
||||||
|
write8(BMP085_CONTROL, BMP085_READPRESSURECMD + (oversampling << 6));
|
||||||
|
|
||||||
|
if (oversampling == BMP085_ULTRALOWPOWER)
|
||||||
|
_delay_ms(5);
|
||||||
|
else if (oversampling == BMP085_STANDARD)
|
||||||
|
_delay_ms(8);
|
||||||
|
else if (oversampling == BMP085_HIGHRES)
|
||||||
|
_delay_ms(14);
|
||||||
|
else
|
||||||
|
_delay_ms(26);
|
||||||
|
|
||||||
|
raw = read16(BMP085_PRESSUREDATA);
|
||||||
|
|
||||||
|
raw <<= 8;
|
||||||
|
raw |= read8(BMP085_PRESSUREDATA+2);
|
||||||
|
raw >>= (8 - oversampling);
|
||||||
|
|
||||||
|
/* this pull broke stuff, look at it later?
|
||||||
|
if (oversampling==0) {
|
||||||
|
raw <<= 8;
|
||||||
|
raw |= read8(BMP085_PRESSUREDATA+2);
|
||||||
|
raw >>= (8 - oversampling);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if BMP085_DEBUG == 1
|
||||||
|
Serial.print("Raw pressure: "); Serial.println(raw);
|
||||||
|
#endif
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t BMP085::readPressure(void) {
|
||||||
|
int32_t UT, UP, B3, B5, B6, X1, X2, X3, p;
|
||||||
|
uint32_t B4, B7;
|
||||||
|
|
||||||
|
UT = readRawTemperature();
|
||||||
|
UP = readRawPressure();
|
||||||
|
|
||||||
|
#if BMP085_DEBUG == 1
|
||||||
|
// use datasheet numbers!
|
||||||
|
UT = 27898;
|
||||||
|
UP = 23843;
|
||||||
|
ac6 = 23153;
|
||||||
|
ac5 = 32757;
|
||||||
|
mc = -8711;
|
||||||
|
md = 2868;
|
||||||
|
b1 = 6190;
|
||||||
|
b2 = 4;
|
||||||
|
ac3 = -14383;
|
||||||
|
ac2 = -72;
|
||||||
|
ac1 = 408;
|
||||||
|
ac4 = 32741;
|
||||||
|
oversampling = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// do temperature calculations
|
||||||
|
X1 = ((UT - (int32_t)ac6) * (int32_t)ac5) >> 15;
|
||||||
|
X2 = ((int32_t)mc << 11) - (X1 + md)/2; // round up
|
||||||
|
X2 /= (X1 + md);
|
||||||
|
B5 = X1 + X2;
|
||||||
|
|
||||||
|
#if BMP085_DEBUG == 1
|
||||||
|
Serial.print("X1 = "); Serial.println(X1);
|
||||||
|
Serial.print("X2 = "); Serial.println(X2);
|
||||||
|
Serial.print("B5 = "); Serial.println(B5);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// do pressure calcs
|
||||||
|
B6 = B5 - 4000;
|
||||||
|
X1 = ((int32_t)b2 * ( (B6 * B6)>>12 )) >> 11;
|
||||||
|
X2 = ((int32_t)ac2 * B6) >> 11;
|
||||||
|
X3 = X1 + X2;
|
||||||
|
B3 = ((((int32_t)ac1*4 + X3) << oversampling) + 2) / 4;
|
||||||
|
|
||||||
|
#if BMP085_DEBUG == 1
|
||||||
|
Serial.print("B6 = "); Serial.println(B6);
|
||||||
|
Serial.print("X1 = "); Serial.println(X1);
|
||||||
|
Serial.print("X2 = "); Serial.println(X2);
|
||||||
|
Serial.print("B3 = "); Serial.println(B3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
X1 = ((int32_t)ac3 * B6) >> 13;
|
||||||
|
X2 = ((int32_t)b1 * ((B6 * B6) >> 12)) >> 16;
|
||||||
|
X3 = ((X1 + X2) + 2) >> 2;
|
||||||
|
B4 = ((uint32_t)ac4 * (uint32_t)(X3 + 32768)) >> 15;
|
||||||
|
B7 = ((uint32_t)UP - B3) * (uint32_t)( 50000UL >> oversampling );
|
||||||
|
|
||||||
|
#if BMP085_DEBUG == 1
|
||||||
|
Serial.print("X1 = "); Serial.println(X1);
|
||||||
|
Serial.print("X2 = "); Serial.println(X2);
|
||||||
|
Serial.print("B4 = "); Serial.println(B4);
|
||||||
|
Serial.print("B7 = "); Serial.println(B7);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (B7 < 0x80000000) {
|
||||||
|
p = (B7 * 2) / B4;
|
||||||
|
} else {
|
||||||
|
p = (B7 / B4) * 2;
|
||||||
|
}
|
||||||
|
X1 = (p >> 8) * (p >> 8);
|
||||||
|
X1 = (X1 * 3038) >> 16;
|
||||||
|
X2 = (-7357 * p) >> 16;
|
||||||
|
|
||||||
|
#if BMP085_DEBUG == 1
|
||||||
|
Serial.print("p = "); Serial.println(p);
|
||||||
|
Serial.print("X1 = "); Serial.println(X1);
|
||||||
|
Serial.print("X2 = "); Serial.println(X2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
p = p + ((X1 + X2 + (int32_t)3791)>>4);
|
||||||
|
#if BMP085_DEBUG == 1
|
||||||
|
Serial.print("p = "); Serial.println(p);
|
||||||
|
#endif
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float BMP085::readTemperature(void) {
|
||||||
|
int32_t UT, X1, X2, B5; // following ds convention
|
||||||
|
float temp;
|
||||||
|
|
||||||
|
UT = readRawTemperature();
|
||||||
|
|
||||||
|
#if BMP085_DEBUG == 1
|
||||||
|
// use datasheet numbers!
|
||||||
|
UT = 27898;
|
||||||
|
ac6 = 23153;
|
||||||
|
ac5 = 32757;
|
||||||
|
mc = -8711;
|
||||||
|
md = 2868;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// step 1
|
||||||
|
X1 = ((UT - (int32_t)ac6) * (int32_t)ac5) >> 15;
|
||||||
|
X2 = ((int32_t)mc << 11) / (X1 + (int32_t)md);
|
||||||
|
B5 = X1 + X2;
|
||||||
|
temp = (B5 + 8) >> 4;
|
||||||
|
temp /= 10;
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
float BMP085::readAltitude(float sealevelPressure) {
|
||||||
|
float altitude;
|
||||||
|
|
||||||
|
float pressure = readPressure();
|
||||||
|
|
||||||
|
altitude = 44330 * (1.0 - pow(pressure /sealevelPressure,0.1903));
|
||||||
|
|
||||||
|
return altitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
uint8_t BMP085::read8(uint8_t a) {
|
||||||
|
uint8_t ret;
|
||||||
|
|
||||||
|
Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
|
||||||
|
#if (ARDUINO >= 100)
|
||||||
|
Wire.write(a); // sends register address to read from
|
||||||
|
#else
|
||||||
|
Wire.send(a); // sends register address to read from
|
||||||
|
#endif
|
||||||
|
Wire.endTransmission(); // end transmission
|
||||||
|
|
||||||
|
Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
|
||||||
|
Wire.requestFrom(BMP085_I2CADDR, 1);// send data n-bytes read
|
||||||
|
#if (ARDUINO >= 100)
|
||||||
|
ret = Wire.read(); // receive DATA
|
||||||
|
#else
|
||||||
|
ret = Wire.receive(); // receive DATA
|
||||||
|
#endif
|
||||||
|
Wire.endTransmission(); // end transmission
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t BMP085::read16(uint8_t a) {
|
||||||
|
uint16_t ret;
|
||||||
|
|
||||||
|
Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
|
||||||
|
#if (ARDUINO >= 100)
|
||||||
|
Wire.write(a); // sends register address to read from
|
||||||
|
#else
|
||||||
|
Wire.send(a); // sends register address to read from
|
||||||
|
#endif
|
||||||
|
Wire.endTransmission(); // end transmission
|
||||||
|
|
||||||
|
Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
|
||||||
|
Wire.requestFrom(BMP085_I2CADDR, 2);// send data n-bytes read
|
||||||
|
#if (ARDUINO >= 100)
|
||||||
|
ret = Wire.read(); // receive DATA
|
||||||
|
ret <<= 8;
|
||||||
|
ret |= Wire.read(); // receive DATA
|
||||||
|
#else
|
||||||
|
ret = Wire.receive(); // receive DATA
|
||||||
|
ret <<= 8;
|
||||||
|
ret |= Wire.receive(); // receive DATA
|
||||||
|
#endif
|
||||||
|
Wire.endTransmission(); // end transmission
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BMP085::write8(uint8_t a, uint8_t d) {
|
||||||
|
Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
|
||||||
|
#if (ARDUINO >= 100)
|
||||||
|
Wire.write(a); // sends register address to read from
|
||||||
|
Wire.write(d); // write data
|
||||||
|
#else
|
||||||
|
Wire.send(a); // sends register address to read from
|
||||||
|
Wire.send(d); // write data
|
||||||
|
#endif
|
||||||
|
Wire.endTransmission(); // end transmission
|
||||||
|
}
|
71
arduino/libraries/sensors/BMP085.h
Normal file
71
arduino/libraries/sensors/BMP085.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/***************************************************
|
||||||
|
This is a library for the BMP085 Barometric Pressure & Temp Sensor
|
||||||
|
|
||||||
|
Designed specifically to work with the Adafruit BMP085 Breakout
|
||||||
|
----> https://www.adafruit.com/products/391
|
||||||
|
|
||||||
|
These displays use I2C to communicate, 2 pins are required to
|
||||||
|
interface
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit and open-source hardware by purchasing
|
||||||
|
products from Adafruit!
|
||||||
|
|
||||||
|
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||||
|
BSD license, all text above must be included in any redistribution
|
||||||
|
****************************************************/
|
||||||
|
|
||||||
|
#if (ARDUINO >= 100)
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
|
#include "WProgram.h"
|
||||||
|
#endif
|
||||||
|
#include "Wire.h"
|
||||||
|
|
||||||
|
#define BMP085_DEBUG 0
|
||||||
|
|
||||||
|
#define BMP085_I2CADDR 0x77
|
||||||
|
|
||||||
|
#define BMP085_ULTRALOWPOWER 0
|
||||||
|
#define BMP085_STANDARD 1
|
||||||
|
#define BMP085_HIGHRES 2
|
||||||
|
#define BMP085_ULTRAHIGHRES 3
|
||||||
|
#define BMP085_CAL_AC1 0xAA // R Calibration data (16 bits)
|
||||||
|
#define BMP085_CAL_AC2 0xAC // R Calibration data (16 bits)
|
||||||
|
#define BMP085_CAL_AC3 0xAE // R Calibration data (16 bits)
|
||||||
|
#define BMP085_CAL_AC4 0xB0 // R Calibration data (16 bits)
|
||||||
|
#define BMP085_CAL_AC5 0xB2 // R Calibration data (16 bits)
|
||||||
|
#define BMP085_CAL_AC6 0xB4 // R Calibration data (16 bits)
|
||||||
|
#define BMP085_CAL_B1 0xB6 // R Calibration data (16 bits)
|
||||||
|
#define BMP085_CAL_B2 0xB8 // R Calibration data (16 bits)
|
||||||
|
#define BMP085_CAL_MB 0xBA // R Calibration data (16 bits)
|
||||||
|
#define BMP085_CAL_MC 0xBC // R Calibration data (16 bits)
|
||||||
|
#define BMP085_CAL_MD 0xBE // R Calibration data (16 bits)
|
||||||
|
|
||||||
|
#define BMP085_CONTROL 0xF4
|
||||||
|
#define BMP085_TEMPDATA 0xF6
|
||||||
|
#define BMP085_PRESSUREDATA 0xF6
|
||||||
|
#define BMP085_READTEMPCMD 0x2E
|
||||||
|
#define BMP085_READPRESSURECMD 0x34
|
||||||
|
|
||||||
|
|
||||||
|
class BMP085 {
|
||||||
|
public:
|
||||||
|
BMP085();
|
||||||
|
void begin(uint8_t mode = BMP085_ULTRAHIGHRES); // by default go highres
|
||||||
|
float readTemperature(void);
|
||||||
|
int32_t readPressure(void);
|
||||||
|
float readAltitude(float sealevelPressure = 101325); // std atmosphere
|
||||||
|
uint16_t readRawTemperature(void);
|
||||||
|
uint32_t readRawPressure(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t read8(uint8_t addr);
|
||||||
|
uint16_t read16(uint8_t addr);
|
||||||
|
void write8(uint8_t addr, uint8_t data);
|
||||||
|
|
||||||
|
uint8_t oversampling;
|
||||||
|
|
||||||
|
int16_t ac1, ac2, ac3, b1, b2, mb, mc, md;
|
||||||
|
uint16_t ac4, ac5, ac6;
|
||||||
|
};
|
||||||
|
|
263
arduino/libraries/sensors/Chronodot.cpp
Normal file
263
arduino/libraries/sensors/Chronodot.cpp
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
// Code by JeeLabs http://news.jeelabs.org/code/
|
||||||
|
// Released to the public domain! Enjoy!
|
||||||
|
//
|
||||||
|
// Modified for Chronodot / DS3132 with
|
||||||
|
// temperature data by Stephanie Maks
|
||||||
|
// http://planetstephanie.net/
|
||||||
|
|
||||||
|
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include "Chronodot.h"
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
|
#include "WProgram.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CHRONODOT_ADDRESS 0x68
|
||||||
|
#define SECONDS_PER_DAY 86400L
|
||||||
|
|
||||||
|
#define SECONDS_FROM_1970_TO_2000 946684800
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// utility code, some of this could be exposed in the DateTime API if needed
|
||||||
|
|
||||||
|
static uint8_t daysInMonth [] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 };
|
||||||
|
|
||||||
|
// number of days since 2000/01/01, valid for 2001..2099
|
||||||
|
static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) {
|
||||||
|
if (y >= 2000)
|
||||||
|
y -= 2000;
|
||||||
|
uint16_t days = d;
|
||||||
|
for (uint8_t i = 1; i < m; ++i)
|
||||||
|
days += pgm_read_byte(daysInMonth + i - 1);
|
||||||
|
if (m > 2 && y % 4 == 0)
|
||||||
|
++days;
|
||||||
|
return days + 365 * y + (y + 3) / 4 - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) {
|
||||||
|
return ((days * 24L + h) * 60 + m) * 60 + s;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// DateTime implementation - ignores time zones and DST changes
|
||||||
|
// NOTE: also ignores leap seconds, see http://en.wikipedia.org/wiki/Leap_second
|
||||||
|
|
||||||
|
DateTime::DateTime (uint32_t t) {
|
||||||
|
t -= SECONDS_FROM_1970_TO_2000; // bring to 2000 timestamp from 1970
|
||||||
|
|
||||||
|
ss = t % 60;
|
||||||
|
t /= 60;
|
||||||
|
mm = t % 60;
|
||||||
|
t /= 60;
|
||||||
|
hh = t % 24;
|
||||||
|
uint16_t days = t / 24;
|
||||||
|
uint8_t leap;
|
||||||
|
for (yOff = 0; ; ++yOff) {
|
||||||
|
leap = yOff % 4 == 0;
|
||||||
|
if (days < 365 + leap)
|
||||||
|
break;
|
||||||
|
days -= 365 + leap;
|
||||||
|
}
|
||||||
|
for (m = 1; ; ++m) {
|
||||||
|
uint8_t daysPerMonth = pgm_read_byte(daysInMonth + m - 1);
|
||||||
|
if (leap && m == 2)
|
||||||
|
++daysPerMonth;
|
||||||
|
if (days < daysPerMonth)
|
||||||
|
break;
|
||||||
|
days -= daysPerMonth;
|
||||||
|
}
|
||||||
|
d = days + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime::DateTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec, int tempF, float tempC) {
|
||||||
|
if (year >= 2000)
|
||||||
|
year -= 2000;
|
||||||
|
yOff = year;
|
||||||
|
m = month;
|
||||||
|
d = day;
|
||||||
|
hh = hour;
|
||||||
|
mm = min;
|
||||||
|
ss = sec;
|
||||||
|
ttf = tempF;
|
||||||
|
ttc = tempC;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t conv2d(const char* p) {
|
||||||
|
uint8_t v = 0;
|
||||||
|
if ('0' <= *p && *p <= '9')
|
||||||
|
v = *p - '0';
|
||||||
|
return 10 * v + *++p - '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// A convenient constructor for using "the compiler's time":
|
||||||
|
// DateTime now (__DATE__, __TIME__);
|
||||||
|
// NOTE: using PSTR would further reduce the RAM footprint
|
||||||
|
DateTime::DateTime (const char* date, const char* time) {
|
||||||
|
// sample input: date = "Dec 26 2009", time = "12:34:56"
|
||||||
|
yOff = conv2d(date + 9);
|
||||||
|
// Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
|
||||||
|
switch (date[0]) {
|
||||||
|
case 'J': m = date[1] == 'a' ? 1 : m = date[2] == 'n' ? 6 : 7; break;
|
||||||
|
case 'F': m = 2; break;
|
||||||
|
case 'A': m = date[2] == 'r' ? 4 : 8; break;
|
||||||
|
case 'M': m = date[2] == 'r' ? 3 : 5; break;
|
||||||
|
case 'S': m = 9; break;
|
||||||
|
case 'O': m = 10; break;
|
||||||
|
case 'N': m = 11; break;
|
||||||
|
case 'D': m = 12; break;
|
||||||
|
}
|
||||||
|
d = conv2d(date + 4);
|
||||||
|
hh = conv2d(time);
|
||||||
|
mm = conv2d(time + 3);
|
||||||
|
ss = conv2d(time + 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t DateTime::dayOfWeek() const {
|
||||||
|
uint16_t day = date2days(yOff, m, d);
|
||||||
|
return (day + 6) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6
|
||||||
|
}
|
||||||
|
|
||||||
|
long DateTime::secondstime(void) const {
|
||||||
|
long t;
|
||||||
|
uint16_t days = date2days(yOff, m, d);
|
||||||
|
t = time2long(days, hh, mm, ss);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t DateTime::unixtime(void) const {
|
||||||
|
uint32_t t;
|
||||||
|
uint16_t days = date2days(yOff, m, d);
|
||||||
|
t = time2long(days, hh, mm, ss);
|
||||||
|
t += SECONDS_FROM_1970_TO_2000; // seconds from 1970 to 2000
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// RTC_DS3231 implementation
|
||||||
|
|
||||||
|
static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); }
|
||||||
|
static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); }
|
||||||
|
|
||||||
|
uint8_t Chronodot::begin(void) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Chronodot::isrunning(void) {
|
||||||
|
Wire.beginTransmission(CHRONODOT_ADDRESS);
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
Wire.write((byte)0x0F);
|
||||||
|
#else
|
||||||
|
Wire.send(0x0F);
|
||||||
|
#endif
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
Wire.requestFrom(CHRONODOT_ADDRESS, 1);
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
uint8_t ss = Wire.read();
|
||||||
|
#else
|
||||||
|
uint8_t ss = Wire.receive();
|
||||||
|
#endif
|
||||||
|
return !(ss>>7);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Chronodot::adjust(const DateTime& dt) {
|
||||||
|
// send new date & time to chronodot
|
||||||
|
Wire.beginTransmission(CHRONODOT_ADDRESS);
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
Wire.write((byte)0); // memory address
|
||||||
|
Wire.write(bin2bcd(dt.second())); // byte 0
|
||||||
|
Wire.write(bin2bcd(dt.minute())); // byte 1
|
||||||
|
Wire.write(bin2bcd(dt.hour())); // byte 2
|
||||||
|
Wire.write(bin2bcd(0)); // byte 3
|
||||||
|
Wire.write(bin2bcd(dt.day())); // byte 4
|
||||||
|
Wire.write(bin2bcd(dt.month())); // byte 5
|
||||||
|
Wire.write(bin2bcd(dt.year() - 2000)); // byte 6
|
||||||
|
#else
|
||||||
|
Wire.send(0);
|
||||||
|
Wire.send(bin2bcd(dt.second()));
|
||||||
|
Wire.send(bin2bcd(dt.minute()));
|
||||||
|
Wire.send(bin2bcd(dt.hour()));
|
||||||
|
Wire.send(bin2bcd(0));
|
||||||
|
Wire.send(bin2bcd(dt.day()));
|
||||||
|
Wire.send(bin2bcd(dt.month()));
|
||||||
|
Wire.send(bin2bcd(dt.year() - 2000));
|
||||||
|
#endif
|
||||||
|
Wire.endTransmission();
|
||||||
|
// now get the control byte - we need to set bit 7 to zero
|
||||||
|
Wire.beginTransmission(CHRONODOT_ADDRESS);
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
Wire.write((byte)0x0F);
|
||||||
|
#else
|
||||||
|
Wire.send(0x0F);
|
||||||
|
#endif
|
||||||
|
Wire.endTransmission();
|
||||||
|
Wire.requestFrom(CHRONODOT_ADDRESS, 1);
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
uint8_t ss = Wire.read();
|
||||||
|
#else
|
||||||
|
uint8_t ss = Wire.receive();
|
||||||
|
#endif
|
||||||
|
ss &= ~(1 << 7); // clear OSF bit
|
||||||
|
Wire.beginTransmission(CHRONODOT_ADDRESS);
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
Wire.write((byte)0x0F);
|
||||||
|
Wire.write((byte)ss);
|
||||||
|
#else
|
||||||
|
Wire.send(0x0F);
|
||||||
|
Wire.send(ss);
|
||||||
|
#endif
|
||||||
|
Wire.endTransmission();
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime Chronodot::now() {
|
||||||
|
Wire.beginTransmission(CHRONODOT_ADDRESS);
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
Wire.write((byte)0);
|
||||||
|
#else
|
||||||
|
Wire.send(0);
|
||||||
|
#endif
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
Wire.requestFrom(CHRONODOT_ADDRESS, 19);
|
||||||
|
byte blah[20];
|
||||||
|
int i;
|
||||||
|
for(i=0; i<20; i++) {
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
blah[i] = Wire.read();
|
||||||
|
#else
|
||||||
|
blah[i] = Wire.receive();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
uint8_t ss = bcd2bin(blah[0] & 0x7F);
|
||||||
|
uint8_t mm = bcd2bin(blah[1]);
|
||||||
|
uint8_t hh = bcd2bin(blah[2]);
|
||||||
|
uint8_t d = bcd2bin(blah[4]);
|
||||||
|
uint8_t m = bcd2bin(blah[5]);
|
||||||
|
uint16_t y = bcd2bin(blah[6]) + 2000;
|
||||||
|
float ttc = (float)(int)blah[17];
|
||||||
|
byte portion = blah[18];
|
||||||
|
if(portion == 0b01000000) ttc += 0.25;
|
||||||
|
if(portion == 0b10000000) ttc += 0.5;
|
||||||
|
if(portion == 0b11000000) ttc += 0.75;
|
||||||
|
float degF = (((ttc * 9.0) / 5.0) + 32.5);
|
||||||
|
int ttf = (int)degF;
|
||||||
|
return DateTime (y, m, d, hh, mm, ss, ttf, ttc);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// RTC_Millis implementation
|
||||||
|
|
||||||
|
long RTC_Millis::offset = 0;
|
||||||
|
|
||||||
|
void RTC_Millis::adjust(const DateTime& dt) {
|
||||||
|
offset = dt.unixtime() - millis() / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime RTC_Millis::now() {
|
||||||
|
return (uint32_t)(offset + millis() / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
60
arduino/libraries/sensors/Chronodot.h
Normal file
60
arduino/libraries/sensors/Chronodot.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// Code by JeeLabs http://news.jeelabs.org/code/
|
||||||
|
// Released to the public domain! Enjoy!
|
||||||
|
//
|
||||||
|
// Modified for Chronodot / DS3132 with
|
||||||
|
// temperature data by Stephanie Maks
|
||||||
|
// http://planetstephanie.net/
|
||||||
|
|
||||||
|
#ifndef CHRONODOT_H
|
||||||
|
#define CHRONODOT_H
|
||||||
|
|
||||||
|
// Simple general-purpose date/time class (no TZ / DST / leap second handling!)
|
||||||
|
class DateTime {
|
||||||
|
public:
|
||||||
|
DateTime (uint32_t t =0);
|
||||||
|
DateTime (uint16_t year, uint8_t month, uint8_t day,
|
||||||
|
uint8_t hour =0, uint8_t min =0, uint8_t sec =0, int tempF =0, float tempC = 0.0);
|
||||||
|
DateTime (const char* date, const char* time);
|
||||||
|
uint16_t year() const { return 2000 + yOff; }
|
||||||
|
uint8_t month() const { return m; }
|
||||||
|
uint8_t day() const { return d; }
|
||||||
|
uint8_t hour() const { return hh; }
|
||||||
|
uint8_t minute() const { return mm; }
|
||||||
|
uint8_t second() const { return ss; }
|
||||||
|
int tempF() const { return ttf; }
|
||||||
|
float tempC() const { return ttc; }
|
||||||
|
uint8_t dayOfWeek() const;
|
||||||
|
|
||||||
|
// 32-bit times as seconds since 1/1/2000
|
||||||
|
long secondstime() const;
|
||||||
|
// 32-bit times as seconds since 1/1/1970
|
||||||
|
uint32_t unixtime(void) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint8_t yOff, m, d, hh, mm, ss;
|
||||||
|
int ttf;
|
||||||
|
float ttc;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Chronodot based on the DS3231 chip connected via I2C and the Wire library
|
||||||
|
class Chronodot {
|
||||||
|
public:
|
||||||
|
static uint8_t begin(void);
|
||||||
|
static void adjust(const DateTime& dt);
|
||||||
|
uint8_t isrunning(void);
|
||||||
|
static DateTime now();
|
||||||
|
};
|
||||||
|
|
||||||
|
// RTC using the internal millis() clock, has to be initialized before use
|
||||||
|
// NOTE: this clock won't be correct once the millis() timer rolls over (>49d?)
|
||||||
|
class RTC_Millis {
|
||||||
|
public:
|
||||||
|
static void begin(const DateTime& dt) { adjust(dt); }
|
||||||
|
static void adjust(const DateTime& dt);
|
||||||
|
static DateTime now();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static long offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif CHRONODOT_H
|
160
arduino/libraries/sensors/DHT.cpp
Normal file
160
arduino/libraries/sensors/DHT.cpp
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
/* DHT library
|
||||||
|
|
||||||
|
MIT license
|
||||||
|
written by Adafruit Industries
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "DHT.h"
|
||||||
|
|
||||||
|
DHT::DHT(uint8_t pin, uint8_t type) {
|
||||||
|
_pin = pin;
|
||||||
|
_type = type;
|
||||||
|
firstreading = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DHT::begin(void) {
|
||||||
|
// set up the pins!
|
||||||
|
pinMode(_pin, INPUT);
|
||||||
|
digitalWrite(_pin, HIGH);
|
||||||
|
_lastreadtime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//boolean S == Scale. True == Farenheit; False == Celcius
|
||||||
|
float DHT::readTemperature(bool S) {
|
||||||
|
float f;
|
||||||
|
|
||||||
|
if (read()) {
|
||||||
|
switch (_type) {
|
||||||
|
case DHT11:
|
||||||
|
f = data[2];
|
||||||
|
if(S)
|
||||||
|
f = convertCtoF(f);
|
||||||
|
|
||||||
|
return f;
|
||||||
|
case DHT22:
|
||||||
|
case DHT21:
|
||||||
|
f = data[2] & 0x7F;
|
||||||
|
f *= 256;
|
||||||
|
f += data[3];
|
||||||
|
f /= 10;
|
||||||
|
if (data[2] & 0x80)
|
||||||
|
f *= -1;
|
||||||
|
if(S)
|
||||||
|
f = convertCtoF(f);
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Serial.print("Read fail");
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
float DHT::convertCtoF(float c) {
|
||||||
|
return c * 9 / 5 + 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
float DHT::readHumidity(void) {
|
||||||
|
float f;
|
||||||
|
if (read()) {
|
||||||
|
switch (_type) {
|
||||||
|
case DHT11:
|
||||||
|
f = data[0];
|
||||||
|
return f;
|
||||||
|
case DHT22:
|
||||||
|
case DHT21:
|
||||||
|
f = data[0];
|
||||||
|
f *= 256;
|
||||||
|
f += data[1];
|
||||||
|
f /= 10;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Serial.print("Read fail");
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boolean DHT::read(void) {
|
||||||
|
uint8_t laststate = HIGH;
|
||||||
|
uint8_t counter = 0;
|
||||||
|
uint8_t j = 0, i;
|
||||||
|
unsigned long currenttime;
|
||||||
|
|
||||||
|
// pull the pin high and wait 250 milliseconds
|
||||||
|
digitalWrite(_pin, HIGH);
|
||||||
|
delay(250);
|
||||||
|
|
||||||
|
currenttime = millis();
|
||||||
|
if (currenttime < _lastreadtime) {
|
||||||
|
// ie there was a rollover
|
||||||
|
_lastreadtime = 0;
|
||||||
|
}
|
||||||
|
if (!firstreading && ((currenttime - _lastreadtime) < 2000)) {
|
||||||
|
return true; // return last correct measurement
|
||||||
|
//delay(2000 - (currenttime - _lastreadtime));
|
||||||
|
}
|
||||||
|
firstreading = false;
|
||||||
|
/*
|
||||||
|
Serial.print("Currtime: "); Serial.print(currenttime);
|
||||||
|
Serial.print(" Lasttime: "); Serial.print(_lastreadtime);
|
||||||
|
*/
|
||||||
|
_lastreadtime = millis();
|
||||||
|
|
||||||
|
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
|
||||||
|
|
||||||
|
// now pull it low for ~20 milliseconds
|
||||||
|
pinMode(_pin, OUTPUT);
|
||||||
|
digitalWrite(_pin, LOW);
|
||||||
|
delay(20);
|
||||||
|
cli();
|
||||||
|
digitalWrite(_pin, HIGH);
|
||||||
|
delayMicroseconds(40);
|
||||||
|
pinMode(_pin, INPUT);
|
||||||
|
|
||||||
|
// read in timings
|
||||||
|
for ( i=0; i< MAXTIMINGS; i++) {
|
||||||
|
counter = 0;
|
||||||
|
while (digitalRead(_pin) == laststate) {
|
||||||
|
counter++;
|
||||||
|
delayMicroseconds(1);
|
||||||
|
if (counter == 255) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
laststate = digitalRead(_pin);
|
||||||
|
|
||||||
|
if (counter == 255) break;
|
||||||
|
|
||||||
|
// ignore first 3 transitions
|
||||||
|
if ((i >= 4) && (i%2 == 0)) {
|
||||||
|
// shove each bit into the storage bytes
|
||||||
|
data[j/8] <<= 1;
|
||||||
|
if (counter > 6)
|
||||||
|
data[j/8] |= 1;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sei();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Serial.println(j, DEC);
|
||||||
|
Serial.print(data[0], HEX); Serial.print(", ");
|
||||||
|
Serial.print(data[1], HEX); Serial.print(", ");
|
||||||
|
Serial.print(data[2], HEX); Serial.print(", ");
|
||||||
|
Serial.print(data[3], HEX); Serial.print(", ");
|
||||||
|
Serial.print(data[4], HEX); Serial.print(" =? ");
|
||||||
|
Serial.println(data[0] + data[1] + data[2] + data[3], HEX);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// check we read 40 bits and that the checksum matches
|
||||||
|
if ((j >= 40) &&
|
||||||
|
(data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
36
arduino/libraries/sensors/DHT.h
Normal file
36
arduino/libraries/sensors/DHT.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#if ARDUINO >= 100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
|
#include "WProgram.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* DHT library
|
||||||
|
|
||||||
|
MIT license
|
||||||
|
written by Adafruit Industries
|
||||||
|
*/
|
||||||
|
|
||||||
|
// how many timing transitions we need to keep track of. 2 * number bits + extra
|
||||||
|
#define MAXTIMINGS 85
|
||||||
|
|
||||||
|
#define DHT11 11
|
||||||
|
#define DHT22 22
|
||||||
|
#define DHT21 21
|
||||||
|
#define AM2301 21
|
||||||
|
|
||||||
|
class DHT {
|
||||||
|
private:
|
||||||
|
uint8_t data[6];
|
||||||
|
uint8_t _pin, _type;
|
||||||
|
boolean read(void);
|
||||||
|
unsigned long _lastreadtime;
|
||||||
|
boolean firstreading;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DHT(uint8_t pin, uint8_t type);
|
||||||
|
void begin(void);
|
||||||
|
float readTemperature(bool S=false);
|
||||||
|
float convertCtoF(float);
|
||||||
|
float readHumidity(void);
|
||||||
|
|
||||||
|
};
|
298
arduino/libraries/sensors/TSL2561.cpp
Normal file
298
arduino/libraries/sensors/TSL2561.cpp
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@file tsl2561.c
|
||||||
|
@author K. Townsend (microBuilder.eu / adafruit.com)
|
||||||
|
|
||||||
|
@section LICENSE
|
||||||
|
|
||||||
|
Software License Agreement (BSD License)
|
||||||
|
|
||||||
|
Copyright (c) 2010, microBuilder SARL, Adafruit Industries
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the copyright holders nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "TSL2561.h"
|
||||||
|
|
||||||
|
TSL2561::TSL2561(uint8_t addr) {
|
||||||
|
_addr = addr;
|
||||||
|
_initialized = false;
|
||||||
|
_integration = TSL2561_INTEGRATIONTIME_13MS;
|
||||||
|
_gain = TSL2561_GAIN_16X;
|
||||||
|
|
||||||
|
// we cant do wire initialization till later, because we havent loaded Wire yet
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean TSL2561::begin(void) {
|
||||||
|
Wire.begin();
|
||||||
|
|
||||||
|
// Initialise I2C
|
||||||
|
Wire.beginTransmission(_addr);
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
Wire.write(TSL2561_REGISTER_ID);
|
||||||
|
#else
|
||||||
|
Wire.send(TSL2561_REGISTER_ID);
|
||||||
|
#endif
|
||||||
|
Wire.endTransmission();
|
||||||
|
Wire.requestFrom(_addr, 1);
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
int x = Wire.read();
|
||||||
|
#else
|
||||||
|
int x = Wire.receive();
|
||||||
|
#endif
|
||||||
|
//Serial.print("0x"); Serial.println(x, HEX);
|
||||||
|
if (x & 0x0A ) {
|
||||||
|
//Serial.println("Found TSL2561");
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_initialized = true;
|
||||||
|
|
||||||
|
// Set default integration time and gain
|
||||||
|
setTiming(_integration);
|
||||||
|
setGain(_gain);
|
||||||
|
// Note: by default, the device is in power down mode on bootup
|
||||||
|
disable();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TSL2561::enable(void)
|
||||||
|
{
|
||||||
|
if (!_initialized) begin();
|
||||||
|
|
||||||
|
// Enable the device by setting the control bit to 0x03
|
||||||
|
write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TSL2561::disable(void)
|
||||||
|
{
|
||||||
|
if (!_initialized) begin();
|
||||||
|
|
||||||
|
// Disable the device by setting the control bit to 0x03
|
||||||
|
write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TSL2561::setGain(tsl2561Gain_t gain) {
|
||||||
|
if (!_initialized) begin();
|
||||||
|
|
||||||
|
enable();
|
||||||
|
_gain = gain;
|
||||||
|
write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _integration | _gain);
|
||||||
|
disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TSL2561::setTiming(tsl2561IntegrationTime_t integration)
|
||||||
|
{
|
||||||
|
if (!_initialized) begin();
|
||||||
|
|
||||||
|
enable();
|
||||||
|
_integration = integration;
|
||||||
|
write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _integration | _gain);
|
||||||
|
disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TSL2561::calculateLux(uint16_t ch0, uint16_t ch1)
|
||||||
|
{
|
||||||
|
unsigned long chScale;
|
||||||
|
unsigned long channel1;
|
||||||
|
unsigned long channel0;
|
||||||
|
|
||||||
|
switch (_integration)
|
||||||
|
{
|
||||||
|
case TSL2561_INTEGRATIONTIME_13MS:
|
||||||
|
chScale = TSL2561_LUX_CHSCALE_TINT0;
|
||||||
|
break;
|
||||||
|
case TSL2561_INTEGRATIONTIME_101MS:
|
||||||
|
chScale = TSL2561_LUX_CHSCALE_TINT1;
|
||||||
|
break;
|
||||||
|
default: // No scaling ... integration time = 402ms
|
||||||
|
chScale = (1 << TSL2561_LUX_CHSCALE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale for gain (1x or 16x)
|
||||||
|
if (!_gain) chScale = chScale << 4;
|
||||||
|
|
||||||
|
// scale the channel values
|
||||||
|
channel0 = (ch0 * chScale) >> TSL2561_LUX_CHSCALE;
|
||||||
|
channel1 = (ch1 * chScale) >> TSL2561_LUX_CHSCALE;
|
||||||
|
|
||||||
|
// find the ratio of the channel values (Channel1/Channel0)
|
||||||
|
unsigned long ratio1 = 0;
|
||||||
|
if (channel0 != 0) ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0;
|
||||||
|
|
||||||
|
// round the ratio value
|
||||||
|
unsigned long ratio = (ratio1 + 1) >> 1;
|
||||||
|
|
||||||
|
unsigned int b, m;
|
||||||
|
|
||||||
|
#ifdef TSL2561_PACKAGE_CS
|
||||||
|
if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C))
|
||||||
|
{b=TSL2561_LUX_B1C; m=TSL2561_LUX_M1C;}
|
||||||
|
else if (ratio <= TSL2561_LUX_K2C)
|
||||||
|
{b=TSL2561_LUX_B2C; m=TSL2561_LUX_M2C;}
|
||||||
|
else if (ratio <= TSL2561_LUX_K3C)
|
||||||
|
{b=TSL2561_LUX_B3C; m=TSL2561_LUX_M3C;}
|
||||||
|
else if (ratio <= TSL2561_LUX_K4C)
|
||||||
|
{b=TSL2561_LUX_B4C; m=TSL2561_LUX_M4C;}
|
||||||
|
else if (ratio <= TSL2561_LUX_K5C)
|
||||||
|
{b=TSL2561_LUX_B5C; m=TSL2561_LUX_M5C;}
|
||||||
|
else if (ratio <= TSL2561_LUX_K6C)
|
||||||
|
{b=TSL2561_LUX_B6C; m=TSL2561_LUX_M6C;}
|
||||||
|
else if (ratio <= TSL2561_LUX_K7C)
|
||||||
|
{b=TSL2561_LUX_B7C; m=TSL2561_LUX_M7C;}
|
||||||
|
else if (ratio > TSL2561_LUX_K8C)
|
||||||
|
{b=TSL2561_LUX_B8C; m=TSL2561_LUX_M8C;}
|
||||||
|
#else
|
||||||
|
if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T))
|
||||||
|
{b=TSL2561_LUX_B1T; m=TSL2561_LUX_M1T;}
|
||||||
|
else if (ratio <= TSL2561_LUX_K2T)
|
||||||
|
{b=TSL2561_LUX_B2T; m=TSL2561_LUX_M2T;}
|
||||||
|
else if (ratio <= TSL2561_LUX_K3T)
|
||||||
|
{b=TSL2561_LUX_B3T; m=TSL2561_LUX_M3T;}
|
||||||
|
else if (ratio <= TSL2561_LUX_K4T)
|
||||||
|
{b=TSL2561_LUX_B4T; m=TSL2561_LUX_M4T;}
|
||||||
|
else if (ratio <= TSL2561_LUX_K5T)
|
||||||
|
{b=TSL2561_LUX_B5T; m=TSL2561_LUX_M5T;}
|
||||||
|
else if (ratio <= TSL2561_LUX_K6T)
|
||||||
|
{b=TSL2561_LUX_B6T; m=TSL2561_LUX_M6T;}
|
||||||
|
else if (ratio <= TSL2561_LUX_K7T)
|
||||||
|
{b=TSL2561_LUX_B7T; m=TSL2561_LUX_M7T;}
|
||||||
|
else if (ratio > TSL2561_LUX_K8T)
|
||||||
|
{b=TSL2561_LUX_B8T; m=TSL2561_LUX_M8T;}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned long temp;
|
||||||
|
temp = ((channel0 * b) - (channel1 * m));
|
||||||
|
|
||||||
|
// do not allow negative lux value
|
||||||
|
if (temp < 0) temp = 0;
|
||||||
|
|
||||||
|
// round lsb (2^(LUX_SCALE-1))
|
||||||
|
temp += (1 << (TSL2561_LUX_LUXSCALE-1));
|
||||||
|
|
||||||
|
// strip off fractional portion
|
||||||
|
uint32_t lux = temp >> TSL2561_LUX_LUXSCALE;
|
||||||
|
|
||||||
|
// Signal I2C had no errors
|
||||||
|
return lux;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TSL2561::getFullLuminosity (void)
|
||||||
|
{
|
||||||
|
if (!_initialized) begin();
|
||||||
|
|
||||||
|
// Enable the device by setting the control bit to 0x03
|
||||||
|
enable();
|
||||||
|
|
||||||
|
// Wait x ms for ADC to complete
|
||||||
|
switch (_integration)
|
||||||
|
{
|
||||||
|
case TSL2561_INTEGRATIONTIME_13MS:
|
||||||
|
delay(14);
|
||||||
|
break;
|
||||||
|
case TSL2561_INTEGRATIONTIME_101MS:
|
||||||
|
delay(102);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
delay(400);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t x;
|
||||||
|
x = read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW);
|
||||||
|
x <<= 16;
|
||||||
|
x |= read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW);
|
||||||
|
|
||||||
|
disable();
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
uint16_t TSL2561::getLuminosity (uint8_t channel) {
|
||||||
|
|
||||||
|
uint32_t x = getFullLuminosity();
|
||||||
|
|
||||||
|
if (channel == 0) {
|
||||||
|
// Reads two byte value from channel 0 (visible + infrared)
|
||||||
|
return (x & 0xFFFF);
|
||||||
|
} else if (channel == 1) {
|
||||||
|
// Reads two byte value from channel 1 (infrared)
|
||||||
|
return (x >> 16);
|
||||||
|
} else if (channel == 2) {
|
||||||
|
// Reads all and subtracts out just the visible!
|
||||||
|
return ( (x & 0xFFFF) - (x >> 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
// unknown channel!
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t TSL2561::read16(uint8_t reg)
|
||||||
|
{
|
||||||
|
uint16_t x; uint16_t t;
|
||||||
|
|
||||||
|
Wire.beginTransmission(_addr);
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
Wire.write(reg);
|
||||||
|
#else
|
||||||
|
Wire.send(reg);
|
||||||
|
#endif
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
Wire.requestFrom(_addr, 2);
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
t = Wire.read();
|
||||||
|
x = Wire.read();
|
||||||
|
#else
|
||||||
|
t = Wire.receive();
|
||||||
|
x = Wire.receive();
|
||||||
|
#endif
|
||||||
|
x <<= 8;
|
||||||
|
x |= t;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void TSL2561::write8 (uint8_t reg, uint8_t value)
|
||||||
|
{
|
||||||
|
Wire.beginTransmission(_addr);
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
Wire.write(reg);
|
||||||
|
Wire.write(value);
|
||||||
|
#else
|
||||||
|
Wire.send(reg);
|
||||||
|
Wire.send(value);
|
||||||
|
#endif
|
||||||
|
Wire.endTransmission();
|
||||||
|
}
|
184
arduino/libraries/sensors/TSL2561.h
Normal file
184
arduino/libraries/sensors/TSL2561.h
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@file tsl2561.h
|
||||||
|
@author K. Townsend (microBuilder.eu)
|
||||||
|
|
||||||
|
@section LICENSE
|
||||||
|
|
||||||
|
Software License Agreement (BSD License)
|
||||||
|
|
||||||
|
Copyright (c) 2010, microBuilder SARL
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the copyright holders nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _TSL2561_H_
|
||||||
|
#define _TSL2561_H_
|
||||||
|
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
#include <Arduino.h>
|
||||||
|
#else
|
||||||
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
|
#define TSL2561_VISIBLE 2 // channel 0 - channel 1
|
||||||
|
#define TSL2561_INFRARED 1 // channel 1
|
||||||
|
#define TSL2561_FULLSPECTRUM 0 // channel 0
|
||||||
|
|
||||||
|
// 3 i2c address options!
|
||||||
|
#define TSL2561_ADDR_LOW 0x29
|
||||||
|
#define TSL2561_ADDR_FLOAT 0x39
|
||||||
|
#define TSL2561_ADDR_HIGH 0x49
|
||||||
|
|
||||||
|
// Lux calculations differ slightly for CS package
|
||||||
|
//#define TSL2561_PACKAGE_CS
|
||||||
|
#define TSL2561_PACKAGE_T_FN_CL
|
||||||
|
|
||||||
|
#define TSL2561_READBIT (0x01)
|
||||||
|
|
||||||
|
#define TSL2561_COMMAND_BIT (0x80) // Must be 1
|
||||||
|
#define TSL2561_CLEAR_BIT (0x40) // Clears any pending interrupt (write 1 to clear)
|
||||||
|
#define TSL2561_WORD_BIT (0x20) // 1 = read/write word (rather than byte)
|
||||||
|
#define TSL2561_BLOCK_BIT (0x10) // 1 = using block read/write
|
||||||
|
|
||||||
|
#define TSL2561_CONTROL_POWERON (0x03)
|
||||||
|
#define TSL2561_CONTROL_POWEROFF (0x00)
|
||||||
|
|
||||||
|
#define TSL2561_LUX_LUXSCALE (14) // Scale by 2^14
|
||||||
|
#define TSL2561_LUX_RATIOSCALE (9) // Scale ratio by 2^9
|
||||||
|
#define TSL2561_LUX_CHSCALE (10) // Scale channel values by 2^10
|
||||||
|
#define TSL2561_LUX_CHSCALE_TINT0 (0x7517) // 322/11 * 2^TSL2561_LUX_CHSCALE
|
||||||
|
#define TSL2561_LUX_CHSCALE_TINT1 (0x0FE7) // 322/81 * 2^TSL2561_LUX_CHSCALE
|
||||||
|
|
||||||
|
// T, FN and CL package values
|
||||||
|
#define TSL2561_LUX_K1T (0x0040) // 0.125 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B1T (0x01f2) // 0.0304 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M1T (0x01be) // 0.0272 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_K2T (0x0080) // 0.250 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B2T (0x0214) // 0.0325 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M2T (0x02d1) // 0.0440 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_K3T (0x00c0) // 0.375 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B3T (0x023f) // 0.0351 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M3T (0x037b) // 0.0544 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_K4T (0x0100) // 0.50 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B4T (0x0270) // 0.0381 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M4T (0x03fe) // 0.0624 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_K5T (0x0138) // 0.61 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B5T (0x016f) // 0.0224 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M5T (0x01fc) // 0.0310 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_K6T (0x019a) // 0.80 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B6T (0x00d2) // 0.0128 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M6T (0x00fb) // 0.0153 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_K7T (0x029a) // 1.3 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B7T (0x0018) // 0.00146 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M7T (0x0012) // 0.00112 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_K8T (0x029a) // 1.3 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B8T (0x0000) // 0.000 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M8T (0x0000) // 0.000 * 2^LUX_SCALE
|
||||||
|
|
||||||
|
// CS package values
|
||||||
|
#define TSL2561_LUX_K1C (0x0043) // 0.130 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B1C (0x0204) // 0.0315 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M1C (0x01ad) // 0.0262 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_K2C (0x0085) // 0.260 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B2C (0x0228) // 0.0337 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M2C (0x02c1) // 0.0430 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_K3C (0x00c8) // 0.390 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B3C (0x0253) // 0.0363 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M3C (0x0363) // 0.0529 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_K4C (0x010a) // 0.520 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B4C (0x0282) // 0.0392 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M4C (0x03df) // 0.0605 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_K5C (0x014d) // 0.65 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B5C (0x0177) // 0.0229 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M5C (0x01dd) // 0.0291 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_K6C (0x019a) // 0.80 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B6C (0x0101) // 0.0157 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M6C (0x0127) // 0.0180 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_K7C (0x029a) // 1.3 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B7C (0x0037) // 0.00338 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M7C (0x002b) // 0.00260 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_K8C (0x029a) // 1.3 * 2^RATIO_SCALE
|
||||||
|
#define TSL2561_LUX_B8C (0x0000) // 0.000 * 2^LUX_SCALE
|
||||||
|
#define TSL2561_LUX_M8C (0x0000) // 0.000 * 2^LUX_SCALE
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TSL2561_REGISTER_CONTROL = 0x00,
|
||||||
|
TSL2561_REGISTER_TIMING = 0x01,
|
||||||
|
TSL2561_REGISTER_THRESHHOLDL_LOW = 0x02,
|
||||||
|
TSL2561_REGISTER_THRESHHOLDL_HIGH = 0x03,
|
||||||
|
TSL2561_REGISTER_THRESHHOLDH_LOW = 0x04,
|
||||||
|
TSL2561_REGISTER_THRESHHOLDH_HIGH = 0x05,
|
||||||
|
TSL2561_REGISTER_INTERRUPT = 0x06,
|
||||||
|
TSL2561_REGISTER_CRC = 0x08,
|
||||||
|
TSL2561_REGISTER_ID = 0x0A,
|
||||||
|
TSL2561_REGISTER_CHAN0_LOW = 0x0C,
|
||||||
|
TSL2561_REGISTER_CHAN0_HIGH = 0x0D,
|
||||||
|
TSL2561_REGISTER_CHAN1_LOW = 0x0E,
|
||||||
|
TSL2561_REGISTER_CHAN1_HIGH = 0x0F
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TSL2561_INTEGRATIONTIME_13MS = 0x00, // 13.7ms
|
||||||
|
TSL2561_INTEGRATIONTIME_101MS = 0x01, // 101ms
|
||||||
|
TSL2561_INTEGRATIONTIME_402MS = 0x02 // 402ms
|
||||||
|
}
|
||||||
|
tsl2561IntegrationTime_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TSL2561_GAIN_0X = 0x00, // No gain
|
||||||
|
TSL2561_GAIN_16X = 0x10, // 16x gain
|
||||||
|
}
|
||||||
|
tsl2561Gain_t;
|
||||||
|
|
||||||
|
|
||||||
|
class TSL2561 {
|
||||||
|
public:
|
||||||
|
TSL2561(uint8_t addr);
|
||||||
|
boolean begin(void);
|
||||||
|
void enable(void);
|
||||||
|
void disable(void);
|
||||||
|
void write8(uint8_t r, uint8_t v);
|
||||||
|
uint16_t read16(uint8_t reg);
|
||||||
|
|
||||||
|
uint32_t calculateLux(uint16_t ch0, uint16_t ch1);
|
||||||
|
void setTiming(tsl2561IntegrationTime_t integration);
|
||||||
|
void setGain(tsl2561Gain_t gain);
|
||||||
|
uint16_t getLuminosity (uint8_t channel);
|
||||||
|
uint32_t getFullLuminosity ();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int8_t _addr;
|
||||||
|
tsl2561IntegrationTime_t _integration;
|
||||||
|
tsl2561Gain_t _gain;
|
||||||
|
|
||||||
|
boolean _initialized;
|
||||||
|
};
|
||||||
|
#endif
|
1175
arduino/libraries/webserver/WebServer.h
Normal file
1175
arduino/libraries/webserver/WebServer.h
Normal file
File diff suppressed because it is too large
Load Diff
93
arduino/weather_station_logger/weather_station_logger.ino
Normal file
93
arduino/weather_station_logger/weather_station_logger.ino
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include <SD.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
#include "BMP085.h"
|
||||||
|
#include "DHT.h"
|
||||||
|
#include "TSL2561.h"
|
||||||
|
#include "Chronodot.h"
|
||||||
|
|
||||||
|
#define TIMING 1000 // milliseconds
|
||||||
|
#define DHTPIN 2
|
||||||
|
#define DHTTYPE DHT22
|
||||||
|
#define SDPIN 4
|
||||||
|
|
||||||
|
BMP085 bmp;
|
||||||
|
DHT dht(DHTPIN, DHTTYPE);
|
||||||
|
TSL2561 tsl(TSL2561_ADDR_FLOAT);
|
||||||
|
Chronodot chronodot;
|
||||||
|
File file;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
//----- SD Card
|
||||||
|
Serial.println("INIT SD Card");
|
||||||
|
|
||||||
|
if (!SD.begin(4)) {
|
||||||
|
Serial.println("FAILED");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Serial.println("DONE");
|
||||||
|
|
||||||
|
//----- Sensors
|
||||||
|
Serial.println("INIT Sensors");
|
||||||
|
|
||||||
|
bmp.begin();
|
||||||
|
dht.begin();
|
||||||
|
tsl.begin();
|
||||||
|
chronodot.begin();
|
||||||
|
|
||||||
|
// You can change the gain on the fly, to adapt to brighter/dimmer light situations
|
||||||
|
//tsl.setGain(TSL2561_GAIN_0X); // set no gain (for bright situtations)
|
||||||
|
tsl.setGain(TSL2561_GAIN_16X); // set 16x gain (for dim situations)
|
||||||
|
|
||||||
|
// Changing the integration time gives you a longer time over which to sense light
|
||||||
|
// longer timelines are slower, but are good in very low light situtations!
|
||||||
|
tsl.setTiming(TSL2561_INTEGRATIONTIME_13MS); // shortest integration time (bright light)
|
||||||
|
//tsl.setTiming(TSL2561_INTEGRATIONTIME_101MS); // medium integration time (medium light)
|
||||||
|
//tsl.setTiming(TSL2561_INTEGRATIONTIME_402MS); // longest integration time (dim light)
|
||||||
|
|
||||||
|
if (!SD.exists("data.tsv")) {
|
||||||
|
file = SD.open("data.tsv", FILE_WRITE);
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
Serial.print("Creating data.tsv");
|
||||||
|
file.println("#Time\t\tT [°C]\tP [Pa]\tAlt [m]\tHr [%]\tLx [lux]");
|
||||||
|
file.close();
|
||||||
|
Serial.println("DONE");
|
||||||
|
} else {
|
||||||
|
Serial.println("Error opening data.tsv");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
float temperature = bmp.readTemperature();
|
||||||
|
int32_t pressure = bmp.readPressure();
|
||||||
|
float altitude = bmp.readAltitude();
|
||||||
|
|
||||||
|
float humidity = dht.readHumidity();
|
||||||
|
|
||||||
|
uint32_t lum = tsl.getFullLuminosity();
|
||||||
|
uint16_t lightIr = lum >> 16;
|
||||||
|
uint16_t lightFull = lum & 0xFFFF;
|
||||||
|
|
||||||
|
DateTime time = chronodot.now();
|
||||||
|
|
||||||
|
file = SD.open("data.tsv", FILE_WRITE);
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
Serial.print("Writing to data.tsv...");
|
||||||
|
file.print(time.year()); file.print("-"); file.print(time.month()); file.print("-"); file.print(time.day()); file.print(" "); file.print(time.hour()); file.print(":"); file.print(time.minute()); file.print(":"); file.print(time.second()); file.print("\t");
|
||||||
|
file.print(temperature); file.print("\t");
|
||||||
|
file.print(pressure); file.print("\t");
|
||||||
|
file.print(altitude); file.print("\t");
|
||||||
|
file.print(humidity); file.print("\t");
|
||||||
|
file.println(tsl.calculateLux(lightFull, lightIr));
|
||||||
|
file.close();
|
||||||
|
Serial.println("DONE");
|
||||||
|
} else {
|
||||||
|
Serial.println("Error opening data.tsv");
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(TIMING);
|
||||||
|
}
|
113
arduino/weather_station_web/index.html
Normal file
113
arduino/weather_station_web/index.html
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset='utf-8' />
|
||||||
|
<title>Station Météo</title>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
background: #000;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'DejaVu Sans', Verdana, Arial, sans-serif;
|
||||||
|
font-size: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#home {
|
||||||
|
background: #000;
|
||||||
|
color: #fff;
|
||||||
|
margin: 1em;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#home h1 {
|
||||||
|
color: #f7c000;
|
||||||
|
font-size: 2em;
|
||||||
|
margin: 1em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#home p {
|
||||||
|
background: #111;
|
||||||
|
border: 1px solid #444;
|
||||||
|
font-size: 1.5em;
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#home table {
|
||||||
|
background: #111;
|
||||||
|
border: 1px solid #444;
|
||||||
|
font-size: 1.5em;
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#home ul#links li {
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0.8em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer {
|
||||||
|
background: #000;
|
||||||
|
color: #888;
|
||||||
|
font-size: 0.8em;
|
||||||
|
margin: 1em;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id='home'>
|
||||||
|
<h1>Station Météo</h1>
|
||||||
|
<table><tr><th>Temps</th><th>T [°C]</th><th>P [Pa]</th><th>Alt [m]</th><th>Hr [%]</th><th>Lx [lux]</th></tr>
|
||||||
|
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr></table>
|
||||||
|
<p><label>Intervale de mise à jour (en secondes) : </label><input id='interval' type='number' value=2 /></p>
|
||||||
|
</div>
|
||||||
|
<div id='footer'>
|
||||||
|
par Nathanaël Restori
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function updateInfo() {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', '/sensors.json');
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
if (xhr.readyState == 4 && xhr.status == 200) {
|
||||||
|
var response = JSON.parse(xhr.responseText);
|
||||||
|
|
||||||
|
var rows = document.getElementsByTagName('tr');
|
||||||
|
var cell = rows[1].firstChild;
|
||||||
|
var index = 0;
|
||||||
|
while (cell) {
|
||||||
|
cell.firstChild.nodeValue = response.sensors[index].data;
|
||||||
|
cell = cell.nextSibling;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateInfo();
|
||||||
|
|
||||||
|
var updateID = setInterval(updateInfo, 2000);
|
||||||
|
|
||||||
|
var interval = document.getElementById('interval');
|
||||||
|
interval.addEventListener('change', function(e) {
|
||||||
|
clearInterval(updateID);
|
||||||
|
updateID = setInterval(updateInfo, e.target.value*1000);
|
||||||
|
}, true);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
158
arduino/weather_station_web/weather_station_web.ino
Normal file
158
arduino/weather_station_web/weather_station_web.ino
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#include <Wire.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Ethernet.h>
|
||||||
|
#include "WebServer.h"
|
||||||
|
#include "BMP085.h"
|
||||||
|
#include "DHT.h"
|
||||||
|
#include "TSL2561.h"
|
||||||
|
#include "Chronodot.h"
|
||||||
|
|
||||||
|
#define TIMEZONE 7200 // 2 hours
|
||||||
|
#define DHTPIN 2
|
||||||
|
#define DHTTYPE DHT22
|
||||||
|
#define PREFIX ""
|
||||||
|
#define NTP_PACKET_SIZE 48
|
||||||
|
|
||||||
|
static uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||||
|
static IPAddress ip = IPAddress(192, 168, 1, 210);
|
||||||
|
static IPAddress timeserver = IPAddress(192, 43, 244, 18);
|
||||||
|
|
||||||
|
P(indexHtml) = "<!DOCTYPE html><html><head><meta charset='utf-8' /><title>Station Météo</title>"
|
||||||
|
"<style>html, body{background: #000;color: #fff;}body{font-family: 'DejaVu Sans', Verdana, Arial, sans-serif;font-size: 100%;margin: 0;padding: 0;}#home{background: #000;color: #fff;margin: 1em;padding: 0;}#home h1{color: #f7c000;font-size: 2em;margin: 1em;text-align: center;}#home p{background: #111;border: 1px solid #444;font-size: 1.5em;list-style-type: none;padding: 0;width: 100%;text-align: center;}#home table{background: #111;border: 1px solid #444;font-size: 1.5em;list-style-type: none;padding: 0;width: 100%;text-align: center;}#home ul#links li{font-weight: bold;margin: 0;padding: 0.8em;text-align: center;}#footer{background: #000;color: #888;font-size: 0.8em;margin: 1em;text-align: center;padding: 0;}</style>"
|
||||||
|
"</head><body>"
|
||||||
|
"<div id='home'><h1>Station Météo</h1>"
|
||||||
|
"<table><tr><th>Temps</th><th>T [°C]</th><th>P [Pa]</th><th>Alt [m]</th><th>Hr [%]</th><th>Lx [lux]</th></tr>"
|
||||||
|
"<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr></table>"
|
||||||
|
"<p><label>Intervale de mise à jour (en secondes) : </label><input id='interval' type='number' value=2 /></p></div><div id='footer'>par Nathanal Restori</div>"
|
||||||
|
"<script>function updateInfo(){var xhr=new XMLHttpRequest();xhr.open('GET', '/sensors.json');xhr.onreadystatechange=function(){if (xhr.readyState==4 && xhr.status==200){var response=JSON.parse(xhr.responseText);var rows=document.getElementsByTagName('tr');var cell=rows[1].firstChild;var index=0;while (cell){cell.firstChild.nodeValue=response.sensors[index].data;cell=cell.nextSibling;index++;}}};xhr.send(null);}updateInfo();var updateID=setInterval(updateInfo, 2000);var interval=document.getElementById('interval');interval.addEventListener('change', function(e){clearInterval(updateID);updateID=setInterval(updateInfo, e.target.value*1000);}, true);</script>"
|
||||||
|
"</body></html>";
|
||||||
|
|
||||||
|
// no-cost stream operator as described at
|
||||||
|
// http://sundial.org/arduino/?page_id=119
|
||||||
|
template<class T>
|
||||||
|
inline Print &operator <<(Print &obj, T arg)
|
||||||
|
{ obj.print(arg); return obj; }
|
||||||
|
|
||||||
|
BMP085 bmp;
|
||||||
|
DHT dht(DHTPIN, DHTTYPE);
|
||||||
|
TSL2561 tsl(TSL2561_ADDR_FLOAT);
|
||||||
|
Chronodot chronodot;
|
||||||
|
WebServer webserver(PREFIX, 80);
|
||||||
|
|
||||||
|
byte packetBuffer[ NTP_PACKET_SIZE];
|
||||||
|
EthernetUDP Udp;
|
||||||
|
|
||||||
|
void defaultCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) {
|
||||||
|
server.httpSuccess();
|
||||||
|
server.printP(indexHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sensorsJsonCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) {
|
||||||
|
float temperature = bmp.readTemperature();
|
||||||
|
int32_t pressure = bmp.readPressure();
|
||||||
|
float altitude = bmp.readAltitude();
|
||||||
|
|
||||||
|
float humidity = dht.readHumidity();
|
||||||
|
|
||||||
|
uint32_t lum = tsl.getFullLuminosity();
|
||||||
|
uint16_t lightIr = lum >> 16;
|
||||||
|
uint16_t lightFull = lum & 0xFFFF;
|
||||||
|
|
||||||
|
DateTime time = chronodot.now();
|
||||||
|
|
||||||
|
server.httpSuccess("application/json");
|
||||||
|
|
||||||
|
server << "{ \"sensors\": ["
|
||||||
|
<< "{\"data\":\"" << time.hour() << ":" << time.minute() << ":" << time.second() << " " << time.day() << "/" << time.month() << "/" << time.year() << "\"},"
|
||||||
|
<< "{\"data\":" << temperature << "},"
|
||||||
|
<< "{\"data\":" << pressure << "},"
|
||||||
|
<< "{\"data\":" << altitude << "},"
|
||||||
|
<< "{\"data\":" << humidity << "},"
|
||||||
|
<< "{\"data\":" << tsl.calculateLux(lightFull, lightIr) << "}"
|
||||||
|
<< "] }";
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendNTPpacket(IPAddress& address) {
|
||||||
|
// set all bytes in the buffer to 0
|
||||||
|
memset(packetBuffer, 0, NTP_PACKET_SIZE);
|
||||||
|
// Initialize values needed to form NTP request
|
||||||
|
// (see URL above for details on the packets)
|
||||||
|
packetBuffer[0] = 0b11100011; // LI, Version, Mode
|
||||||
|
packetBuffer[1] = 0; // Stratum, or type of clock
|
||||||
|
packetBuffer[2] = 6; // Polling Interval
|
||||||
|
packetBuffer[3] = 0xEC; // Peer Clock Precision
|
||||||
|
// 8 bytes of zero for Root Delay & Root Dispersion
|
||||||
|
packetBuffer[12] = 49;
|
||||||
|
packetBuffer[13] = 0x4E;
|
||||||
|
packetBuffer[14] = 49;
|
||||||
|
packetBuffer[15] = 52;
|
||||||
|
|
||||||
|
// all NTP fields have been given values, now
|
||||||
|
// you can send a packet requesting a timestamp:
|
||||||
|
Udp.beginPacket(address, 123); //NTP requests are to port 123
|
||||||
|
Udp.write(packetBuffer,NTP_PACKET_SIZE);
|
||||||
|
Udp.endPacket();
|
||||||
|
Serial.println("Sending ntp packet");
|
||||||
|
|
||||||
|
delay(1000);
|
||||||
|
if ( Udp.parsePacket() ) {
|
||||||
|
// We've received a packet, read the data from it
|
||||||
|
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
|
||||||
|
|
||||||
|
//the timestamp starts at byte 40 of the received packet and is four bytes,
|
||||||
|
// or two words, long. First, esxtract the two words:
|
||||||
|
|
||||||
|
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
|
||||||
|
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
|
||||||
|
// combine the four bytes (two words) into a long integer
|
||||||
|
// this is NTP time (seconds since Jan 1 1900):
|
||||||
|
unsigned long secsSince1900 = highWord << 16 | lowWord;
|
||||||
|
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
|
||||||
|
const unsigned long seventyYears = 2208988800UL;
|
||||||
|
// subtract seventy years:
|
||||||
|
unsigned long epoch = secsSince1900 - seventyYears + TIMEZONE;
|
||||||
|
|
||||||
|
Serial.println("Adjusting time");
|
||||||
|
chronodot.adjust(DateTime(epoch));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
//----- Ethernet/WebServer
|
||||||
|
Serial.println("INIT Ethernet");
|
||||||
|
|
||||||
|
Ethernet.begin(mac, ip);
|
||||||
|
webserver.begin();
|
||||||
|
|
||||||
|
webserver.setDefaultCommand(&defaultCmd);
|
||||||
|
webserver.addCommand("sensors.json", &sensorsJsonCmd);
|
||||||
|
|
||||||
|
//----- Sensors
|
||||||
|
Serial.println("INIT Sensors");
|
||||||
|
|
||||||
|
bmp.begin();
|
||||||
|
dht.begin();
|
||||||
|
tsl.begin();
|
||||||
|
chronodot.begin();
|
||||||
|
|
||||||
|
// You can change the gain on the fly, to adapt to brighter/dimmer light situations
|
||||||
|
//tsl.setGain(TSL2561_GAIN_0X); // set no gain (for bright situtations)
|
||||||
|
tsl.setGain(TSL2561_GAIN_16X); // set 16x gain (for dim situations)
|
||||||
|
|
||||||
|
// Changing the integration time gives you a longer time over which to sense light
|
||||||
|
// longer timelines are slower, but are good in very low light situtations!
|
||||||
|
tsl.setTiming(TSL2561_INTEGRATIONTIME_13MS); // shortest integration time (bright light)
|
||||||
|
//tsl.setTiming(TSL2561_INTEGRATIONTIME_101MS); // medium integration time (medium light)
|
||||||
|
//tsl.setTiming(TSL2561_INTEGRATIONTIME_402MS); // longest integration time (dim light)
|
||||||
|
|
||||||
|
Udp.begin(8888);
|
||||||
|
sendNTPpacket(timeserver);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
webserver.processConnection();
|
||||||
|
|
||||||
|
delay(500);
|
||||||
|
}
|
BIN
latex/Arduino_Ethernet_Board_.jpg
Normal file
BIN
latex/Arduino_Ethernet_Board_.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 MiB |
91
latex/TM.tex
Normal file
91
latex/TM.tex
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
\documentclass{scrreprt}
|
||||||
|
\usepackage{fontspec}
|
||||||
|
\usepackage{xunicode}
|
||||||
|
\usepackage{polyglossia}
|
||||||
|
\usepackage{csquotes}
|
||||||
|
\usepackage[citestyle=verbose-trad2]{biblatex}
|
||||||
|
\usepackage[hidelinks]{hyperref}
|
||||||
|
\usepackage[acronym,toc,xindy]{glossaries}
|
||||||
|
|
||||||
|
\setmainlanguage{french}
|
||||||
|
|
||||||
|
\title{La lumière s'éteint-elle dans le frigo ?}
|
||||||
|
\subtitle{ou bla bli blu}
|
||||||
|
\author{Nathanaël \textsc{Restori}}
|
||||||
|
\date{\today}
|
||||||
|
|
||||||
|
\bibliography{bibliographie.bib}
|
||||||
|
|
||||||
|
\renewcommand*{\glstextformat}{\textbf}
|
||||||
|
\makeglossaries
|
||||||
|
\input{glossaire.tex}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
|
||||||
|
\input{couverture.tex}
|
||||||
|
|
||||||
|
\chapter*{Remerciements}
|
||||||
|
\thispagestyle{empty}
|
||||||
|
Je remercie bla bla bla...
|
||||||
|
\vfill
|
||||||
|
Image de couverture par \enquote{oomlout}, sous licence Creative Commons Attribution-Share like 2.0 Generic (CC BY-SA 2.0)
|
||||||
|
|
||||||
|
\tableofcontents
|
||||||
|
|
||||||
|
\chapter{Introduction}
|
||||||
|
\section{Motivations}
|
||||||
|
J'ai décidé de faire mon travaille de maturité sur ce sujet car je suis passionné de robotique depuis tout petit. J'ai commencé en participant à un atelier de soudures à la Maison Picson\footnote{Établissement servant de cantine proposant aussi des activités à Blonay}. Je suis aussi allé à la première édition du Festival de Robotique à l'EPFL en 2008 et ai participé à deux ateliers (introduction à la programmation de microcontrôleur et soudure d'un robot DIDEL).
|
||||||
|
|
||||||
|
Je suis aussi passionné par l'informatique en général, la programmation ainsi que les logiciels libres.
|
||||||
|
|
||||||
|
\section{Présentation du travail}
|
||||||
|
TODO
|
||||||
|
|
||||||
|
\section{Les principes du logiciel libre}
|
||||||
|
Un logiciel libre est un logiciel qui respecte quatre libertés fondamentales~:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item la liberté d'utiliser le logiciel
|
||||||
|
\item la liberté de copier le logiciel
|
||||||
|
\item la liberté d'étudier le logiciel
|
||||||
|
\item la liberté de modifier le logiciel et de redistribuer les versions modifiées
|
||||||
|
\end{enumerate}
|
||||||
|
Les deux dernière libertés demandent la mise à disposition du \gls{code source}. On parle souvent de \emph{copyleft}, par opposition au copyright.
|
||||||
|
|
||||||
|
On retrouve aussi le terme \enquote{\emph{open source}}, mais celui-ci est ambigu : celui-ci pouvant désigner un logiciel des les sources sont disponibles mais non réutilisables ou redistribuable ou désigner un logiciel libre (comme définit par \gls{OSI}).
|
||||||
|
|
||||||
|
Les sources du logiciels sont soumis à des licences spécifiques garantissant ces libertés. Les plus connues sont la \gls{GPL}, la \gls{BSD} ou la MIT.
|
||||||
|
|
||||||
|
Quelques logiciels libres connus sont Firefox et Thunderbird, Linux ou OpenOffice.org/LibreOffice.
|
||||||
|
|
||||||
|
\section{Conventions d'écriture}
|
||||||
|
Les mots en \textbf{gras} sont des mots expliqués dans le glossaire ou des acronymes.
|
||||||
|
|
||||||
|
Les textes écrits avec \verb|cette police d'écriture| sont des extraits de code.
|
||||||
|
|
||||||
|
\chapter{Le matériel}
|
||||||
|
\section{Le choix de la plate-forme}
|
||||||
|
Il existe de nombreuse \gls{plate-forme} en robotique~: par exemple, le Boe-Bot de Parallax, utilisé dans les cours facultatifs de robotique de M. \textsc{Gardon}. J'ai fait le choix d'un Arduino car cette un plate-forme de plus en plus répandue, peu chère (20 € pour une carte programmable) et puissante. On trouve de nombreux exemples de \gls{DIY}, elle est programmable en \gls{C++} (donc il est possible d'utiliser des \glspl{bibliotheque}) et c'est du \gls{materiel libre}.
|
||||||
|
|
||||||
|
\section{Les capteurs}
|
||||||
|
Il a été décidé de faire une station météo. Nous avons donc besoin d'un thermomètre, d'un hygromètre, d'un baromètre et d'un capteur de luminosité. J'ai ajouté une horloge qui nous permettra d'avoir l'heure à laquelle les mesures ont été prises. Tous les capteurs ont été commandé sur le site d'Adafruit. L'hygromètre ne se connecte malheureusement pas en I²C, aucun capteur de ce type n'étant disponible% TODO : ajouter images/figures
|
||||||
|
|
||||||
|
\section{Les limitations}
|
||||||
|
J'ai vite été confronté a quelque limitations : la mémoire de l'Arduino ne peux contenir seulement 32256 octets de code compilé. Il ne peux donc pas contenir en même temps les \glspl{bibliotheque} pour utiliser les capteurs en I²C, utiliser le port RJ45 et utiliser la carte SD. La solution a été de couper le programme en deux : il y a donc un code pour afficher les mesures en direct à travers un navigateur web et un code pour prendre des mesures de manière régulière et les enregistrer.
|
||||||
|
|
||||||
|
%\listoffigures
|
||||||
|
|
||||||
|
\glsadd{DIYg}
|
||||||
|
\printglossary[type=\acronymtype,title=Acronymes,toctitle=Acronymes]
|
||||||
|
\newpage
|
||||||
|
\printglossary[type=main,title=Glossaire,toctitle=Glossaire]
|
||||||
|
|
||||||
|
%\chapter{Bibliographie}
|
||||||
|
\nocite{*}
|
||||||
|
%\printbibliography[heading=none]
|
||||||
|
\printbibliography
|
||||||
|
|
||||||
|
\appendix
|
||||||
|
%\appendixpage
|
||||||
|
%\addappheadtotoc
|
||||||
|
|
||||||
|
\end{document}
|
9
latex/bibliographie.bib
Normal file
9
latex/bibliographie.bib
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
@Article{ref,
|
||||||
|
author={Durand, Patrick AND Durand, René},
|
||||||
|
journal={Le beau journal},
|
||||||
|
title={Les tomates tueuses},
|
||||||
|
year={2007},
|
||||||
|
month={jan},
|
||||||
|
pages={24},
|
||||||
|
notes={sympatique},
|
||||||
|
}
|
34
latex/couverture.tex
Normal file
34
latex/couverture.tex
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
\begin{titlepage}
|
||||||
|
\makeatletter
|
||||||
|
\begin{center}
|
||||||
|
|
||||||
|
\textsc{\LARGE Gymnase de Burier}\\[4cm]
|
||||||
|
|
||||||
|
\textbf{\huge \@title\\[0.5em]
|
||||||
|
\large \@subtitle}
|
||||||
|
|
||||||
|
\vfill
|
||||||
|
|
||||||
|
\begin{figure}[htp]
|
||||||
|
\centering
|
||||||
|
\includegraphics[scale=1.0]{Arduino_Ethernet_Board_.jpg}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\vfill
|
||||||
|
|
||||||
|
\begin{minipage}{0.59\textwidth}
|
||||||
|
\begin{flushleft}
|
||||||
|
Blonay, le \@date
|
||||||
|
\end{flushleft}
|
||||||
|
\end{minipage}
|
||||||
|
\begin{minipage}{0.4\textwidth}
|
||||||
|
\begin{flushright}
|
||||||
|
\@author, 2M6\\
|
||||||
|
\end{flushright}
|
||||||
|
\end{minipage}
|
||||||
|
|
||||||
|
\end{center}
|
||||||
|
|
||||||
|
\setcounter{page}{0}
|
||||||
|
\makeatother
|
||||||
|
\end{titlepage}
|
41
latex/glossaire.tex
Normal file
41
latex/glossaire.tex
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
\newglossaryentry{code source}
|
||||||
|
{
|
||||||
|
name=code source,
|
||||||
|
description={bla}
|
||||||
|
}
|
||||||
|
|
||||||
|
\newglossaryentry{DIYg}
|
||||||
|
{
|
||||||
|
name=DIY,
|
||||||
|
description={littéralement, \enquote{faites-le vous-même}. S'assimile à du bricolage}
|
||||||
|
}
|
||||||
|
|
||||||
|
\newglossaryentry{C++}
|
||||||
|
{
|
||||||
|
name=C++,
|
||||||
|
description={langage de programmation ancien et répandu}
|
||||||
|
}
|
||||||
|
|
||||||
|
\newglossaryentry{bibliotheque}
|
||||||
|
{
|
||||||
|
name=bibliothèque,
|
||||||
|
plural=bilbiothèques,
|
||||||
|
description={ensemble de fonctions permettant de manipuler un capteur, un objet, une puce (etc.) plus facilement}
|
||||||
|
}
|
||||||
|
|
||||||
|
\newglossaryentry{materiel libre}
|
||||||
|
{
|
||||||
|
name=matériel libre,
|
||||||
|
description={matériel dont les plans sont publics. Tout le monde peux les modifier, fabriquer, redistribuer et utiliser. Pendant matériel du logiciel libre}
|
||||||
|
}
|
||||||
|
|
||||||
|
\newglossaryentry{plate-forme}
|
||||||
|
{
|
||||||
|
name=plate-forme,
|
||||||
|
description={en informatique, une base de travail à partir de laquelle on peut écrire, lire, utiliser, développer un ensemble de logiciels\footnote{tiré de Wikipédia}}
|
||||||
|
}
|
||||||
|
|
||||||
|
\newacronym{BSD}{BSD}{Berkeley Software Distribution}
|
||||||
|
\newglossaryentry{DIY}{type=\acronymtype, name={DIY}, description={Do It Yourself}, first={Do It Yourself (DIY)}, see=[Glossaire :]{DIYg}}
|
||||||
|
\newacronym{GPL}{GPL}{GNU General Public License}
|
||||||
|
\newacronym{OSI}{OSI}{Open Source Initiative}
|
11
latex/latexmkrc
Normal file
11
latex/latexmkrc
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
$pdflatex = "xelatex";
|
||||||
|
$pdf_mode = "1";
|
||||||
|
|
||||||
|
push @generated_exts, 'glo', 'gls', 'glg';
|
||||||
|
push @generated_exts, 'acn', 'acr', 'alg';
|
||||||
|
$clean_ext .= ' %R.bbl %R-blx.bib %R.ist %R.nav %R.run.xml %R.snm %R.xdy';
|
||||||
|
|
||||||
|
add_cus_dep( 'glo', 'gls', 0, 'makeglossaries' );
|
||||||
|
sub makeglossaries {
|
||||||
|
system( "makeglossaries \"$_[0]\"" );
|
||||||
|
}
|
52
latex/presentation.tex
Normal file
52
latex/presentation.tex
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
%\pdfminorversion=4
|
||||||
|
\documentclass{beamer}
|
||||||
|
|
||||||
|
\usepackage[utf8]{inputenc}
|
||||||
|
\usepackage[T1]{fontenc}
|
||||||
|
\usepackage[francais]{babel}
|
||||||
|
|
||||||
|
\title{La lumière s'éteint-elle dans le frigo ?}
|
||||||
|
\subtitle{ou bla bli blu}
|
||||||
|
\author{Nathanaël \bsc{Restori}}
|
||||||
|
\date{\today}
|
||||||
|
\institute{Gymnase de Burier}
|
||||||
|
|
||||||
|
\usetheme{Warsaw}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\titlepage
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\tableofcontents[pausesections]
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\section{Section 1}
|
||||||
|
\subsection{Sous section 1 de la Section 1}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
Ma première page !
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\subsection{Sous section 2 de la Section 1}
|
||||||
|
\begin{frame}
|
||||||
|
Et maintenant ma deuxième page !
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\section{Section 2}
|
||||||
|
\subsection{Sous section 1 de la Section 2}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
Voici ma troisième page, elle appartient à ma deuxième section ! :)
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\subsection{Sous section 2 de la Section 2}
|
||||||
|
\begin{frame}
|
||||||
|
Et celle là c'est la deuxième page, mais de ma deuxième section.
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\end{document}
|
Loading…
Reference in New Issue
Block a user