sensors
Dependencies: allsensors TEMDHT FastAnalogIn SDFileSystem
Revision 0:e83b7345b15f, committed 2017-12-12
- Comitter:
- david8251
- Date:
- Tue Dec 12 12:29:05 2017 +0000
- Commit message:
- sensor
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/C027_Support.lib Tue Dec 12 12:29:05 2017 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/david8251/code/allsensors/#0d7160fa8733
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DHT.lib Tue Dec 12 12:29:05 2017 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/david8251/code/TEMDHT/#fd491ce3cd8d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FastAnalogIn.lib Tue Dec 12 12:29:05 2017 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/Sissors/code/FastAnalogIn/#46fbc645de4d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MMA7455.cpp Tue Dec 12 12:29:05 2017 +0000 @@ -0,0 +1,295 @@ +/****************************************************************************** + * Includes + *****************************************************************************/ + +#include "mbed.h" +#include "mbed_debug.h" + +#include "MMA7455.h" + +/****************************************************************************** + * Defines and typedefs + *****************************************************************************/ + +#define MMA7455_I2C_ADDR (0x1D << 1) + +#define MMA7455_ADDR_XOUTL 0x00 +#define MMA7455_ADDR_XOUTH 0x01 +#define MMA7455_ADDR_YOUTL 0x02 +#define MMA7455_ADDR_YOUTH 0x03 +#define MMA7455_ADDR_ZOUTL 0x04 +#define MMA7455_ADDR_ZOUTH 0x05 +#define MMA7455_ADDR_XOUT8 0x06 +#define MMA7455_ADDR_YOUT8 0x07 +#define MMA7455_ADDR_ZOUT8 0x08 +#define MMA7455_ADDR_STATUS 0x09 +#define MMA7455_ADDR_DETSRC 0x0A +#define MMA7455_ADDR_TOUT 0x0B +#define MMA7455_ADDR_I2CAD 0x0D +#define MMA7455_ADDR_USRINF 0x0E +#define MMA7455_ADDR_WHOAMI 0x0F +#define MMA7455_ADDR_XOFFL 0x10 +#define MMA7455_ADDR_XOFFH 0x11 +#define MMA7455_ADDR_YOFFL 0x12 +#define MMA7455_ADDR_YOFFH 0x13 +#define MMA7455_ADDR_ZOFFL 0x14 +#define MMA7455_ADDR_ZOFFH 0x15 +#define MMA7455_ADDR_MCTL 0x16 +#define MMA7455_ADDR_INTRST 0x17 +#define MMA7455_ADDR_CTL1 0x18 +#define MMA7455_ADDR_CTL2 0x19 +#define MMA7455_ADDR_LDTH 0x1A +#define MMA7455_ADDR_PDTH 0x1B +#define MMA7455_ADDR_PW 0x1C +#define MMA7455_ADDR_LT 0x1D +#define MMA7455_ADDR_TW 0x1E + +#define MMA7455_MCTL_MODE(m) ((m) << 0) +#define MMA7455_MCTL_GLVL(g) ((g) << 2) + +#define MMA7455_STATUS_DRDY (1 << 0) +#define MMA7455_STATUS_DOVR (1 << 1) +#define MMA7455_STATUS_PERR (1 << 2) + + +MMA7455::MMA7455(PinName sda, PinName scl) : _i2c(sda, scl) +{ + _mode = ModeStandby; + _range = Range_8g; + + _xOff = 0; + _yOff = 0; + _zOff = 0; +} + +bool MMA7455::setMode(Mode mode) { + bool result = false; + int mCtrl = 0; + + do { + mCtrl = getModeControl(); + if (mCtrl < 0) break; + + mCtrl &= ~(0x03 << 0); + mCtrl |= MMA7455_MCTL_MODE(mode); + + if (setModeControl((uint8_t)mCtrl) < 0) { + break; + } + + _mode = mode; + result = true; + } while(0); + + + + return result; +} + +bool MMA7455::setRange(Range range) { + bool result = false; + int mCtrl = 0; + + do { + mCtrl = getModeControl(); + if (mCtrl < 0) break; + + mCtrl &= ~(0x03 << 2); + mCtrl |= MMA7455_MCTL_GLVL(range); + + if (setModeControl((uint8_t)mCtrl) < 0) { + break; + } + + _range = range; + result = true; + } while(0); + + + + return result; + +} + +bool MMA7455::read(int32_t& x, int32_t& y, int32_t& z) { + bool result = false; + + + // nothing to read in standby mode + if (_mode == ModeStandby) return false; + + // wait for ready flag + int status = 0; + do { + status = getStatus(); + } while (status >= 0 && (status & MMA7455_STATUS_DRDY) == 0); + + + do { + if (status < 0) break; + + + char buf[6]; + buf[0] = MMA7455_ADDR_XOUTL; + if (_i2c.write(MMA7455_I2C_ADDR, buf, 1) != 0) break; + if (_i2c.read(MMA7455_I2C_ADDR, buf, 6) != 0) break; + + // check if second bit is set in high byte -> negative value + // expand negative value to full byte + if (buf[1] & 0x02) buf[1] |= 0xFC; + if (buf[3] & 0x02) buf[3] |= 0xFC; + if (buf[5] & 0x02) buf[5] |= 0xFC; + + x = (int16_t)((buf[1] << 8) | buf[0]) + _xOff; + y = (int16_t)((buf[3] << 8) | buf[2]) + _yOff; + z = (int16_t)((buf[5] << 8) | buf[4]) + _zOff; + + + result = true; + + } while(0); + + + return result; +} + +bool MMA7455::calibrate() { + bool result = false; + bool failed = false; + + int32_t x = 0; + int32_t y = 0; + int32_t z = 0; + + int32_t xr = 0; + int32_t yr = 0; + int32_t zr = 0; + + int xOff = 0; + int yOff = 0; + int zOff = 16; + if (_range == Range_2g) { + zOff = 64; + } + if (_range == Range_4g) { + zOff = 32; + } + + do { + + // get an average of 6 values + for (int i = 0; i < 6; i++) { + if (!read(xr, yr, zr)) { + failed = true; + break; + } + x += xr; + y += yr; + z += zr; + + wait_ms(100); + } + + if (failed) break; + x /= 6; + y /= 6; + z /= 6; + + xOff -= x; + yOff -= y; + zOff -= z; + + /* + * For some reason we have not got correct/reliable calibration + * by using the offset drift registers. Instead we are + * calculating the offsets and store them in member variables. + * + * These member variables are then used in the read() method + */ + + _xOff = xOff; + _yOff = yOff; + _zOff = zOff; + + + result = true; + + } while (0); + + + + return result; +} + +bool MMA7455::setCalibrationOffsets(int32_t xOff, int32_t yOff, int32_t zOff) { + _xOff = xOff; + _yOff = yOff; + _zOff = zOff; + + return true; +} + +bool MMA7455::getCalibrationOffsets(int32_t& xOff, int32_t& yOff, int32_t& zOff) { + xOff = _xOff; + yOff = _yOff; + zOff = _zOff; + + return true; +} + +int MMA7455::getStatus() { + int result = -1; + char data[1]; + + do { + data[0] = MMA7455_ADDR_STATUS; + if (_i2c.write(MMA7455_I2C_ADDR, data, 1) != 0) break; + + if (_i2c.read(MMA7455_I2C_ADDR, data, 1) != 0) break; + + result = data[0]; + + } while (0); + + + + return result; +} + +int MMA7455::getModeControl() { + + int result = -1; + char data[1]; + + do { + data[0] = MMA7455_ADDR_MCTL; + if (_i2c.write(MMA7455_I2C_ADDR, data, 1) != 0) break; + + if (_i2c.read(MMA7455_I2C_ADDR, data, 1) != 0) break; + + result = data[0]; + + } while (0); + + + + return result; +} + +int MMA7455::setModeControl(uint8_t mctl) { + int result = -1; + char data[2]; + + do { + data[0] = MMA7455_ADDR_MCTL; + data[1] = (char)mctl; + if (_i2c.write(MMA7455_I2C_ADDR, data, 2) != 0) break; + + result = 0; + + } while (0); + + + + return result; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MMA7455.h Tue Dec 12 12:29:05 2017 +0000 @@ -0,0 +1,93 @@ +#ifndef MMA7455_H +#define MMA7455_H + + +/** + * Freescale Accelerometer MMA7455. + */ +class MMA7455 { +public: + + enum Mode { + ModeStandby = 0, + ModeMeasurement = 1, + }; + + /** Acceleration range */ + enum Range { + Range_8g = 0, + Range_2g = 1, + Range_4g = 2 + }; + + /** + * Create an interface to the MMA7455 accelerometer + * + * @param sda I2C data line pin + * @param scl I2C clock line pin + */ + MMA7455(PinName sda, PinName scl); + + bool setMode(Mode mode); + bool setRange(Range range); + + bool read(int32_t& x, int32_t& y, int32_t& z); + + /** + * Calibrate for 0g, that is, calculate offset to achieve + * 0g values when accelerometer is placed on flat surface. + * + * Please make sure the accelerometer is placed on a flat surface before + * calling this function. + * + * @return true if request was successful; otherwise false + */ + bool calibrate(); + + /** + * Get calculated offset values. Offsets will be calculated by the + * calibrate() method. + * + * Use these values and put them in persistent storage to avoid + * having to calibrate the accelerometer after a reset/power cycle. + * + * @param xOff x offset is written to this argument + * @param yOff y offset is written to this argument + * @param zOff z offset is written to this argument + * + * @return true if request was successful; otherwise false + */ + bool getCalibrationOffsets(int32_t& xOff, int32_t& yOff, int32_t& zOff); + + /** + * Set calibration offset values. These values should normally + * at one point in time have been retrieved by calling the + * getCalibrationOffsets method. + * + * + * @param xOff x offset + * @param yOff y offset + * @param zOff z offset + * + * @return true if request was successful; otherwise false + */ + bool setCalibrationOffsets(int32_t xOff, int32_t yOff, int32_t zOff); + + + +private: + + I2C _i2c; + Mode _mode; + Range _range; + int32_t _xOff; + int32_t _yOff; + int32_t _zOff; + + int getStatus(); + int getModeControl(); + int setModeControl(uint8_t mctl); + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Tue Dec 12 12:29:05 2017 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/mbed_official/code/SDFileSystem/#8db0d3b02cec
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Dec 12 12:29:05 2017 +0000 @@ -0,0 +1,372 @@ +#include "mbed.h" +//--------------------------------- +#include "SDFileSystem.h" +//--------------------------------- +#include "GPS.h" +//--------------------------------- +#include "DHT.h" +//--------------------------------- +#include "MMA7455.h" +//--------------------------------- +#define PI 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253 +//--------------------------------- +SDFileSystem sd(p5, p6, p7, p8, "sd"); +DHT sensor(D7,DHT22); +MMA7455 acc(p32,p31); +Serial wind(P0_2, P0_3); +Serial Mod(p9, p10); +AnalogIn adc(p15); +AnalogIn adc(p16); + +void task_GPS(); +void task_MMA(); +void task_DHT(); +void task_windy(); +void task_resist(); +void task_current(); +void task_extend(); + +Timer timer; +Timer timer2; + +struct tm t; +struct tm t1; +int main() { + t.tm_sec = 37; // 0-59 + t.tm_min = 58; // 0-59 + t.tm_hour = 23; // 0-23 + t.tm_mday = 28; // 1-31 + t.tm_mon = 1; // 0-11 + t.tm_year = 117; // year since 1900 + + t1.tm_sec = 37; // 0-59 + t1.tm_min = 58; // 0-59 + t1.tm_hour = 23; // 0-23 + t1.tm_mday = 28; // 1-31 + t1.tm_mon = 1; // 0-11 + t1.tm_year = 117; // year since 1900 + + time_t seconds = mktime(&t); + set_time(seconds); + + time_t second = mktime(&t1); + set_time(second); + + mkdir("/sd/DHT", 0777); + mkdir("/sd/MMA", 0777); + mkdir("/sd/GPS",0777); + mkdir("/sd/resist", 0777); + mkdir("/sd/windy", 0777); + mkdir("/sd/current",0777); + mkdir("/sd/extend",0777); + + timer.start(); + timer2.start(); + acc.setMode(MMA7455::ModeMeasurement); + acc.setRange(MMA7455::Range_2g); + acc.calibrate(); + + t.tm_mon+=1; + t1.tm_mon+=1; + while(1) { + if(timer.read()>3){ + t.tm_min+=1; + if(t.tm_min>59){ + t.tm_min=0; + t.tm_hour++; + } + if(t.tm_hour>23){ + t.tm_hour=0; + t.tm_mday++; + } + if((t.tm_mday>31)&&((t.tm_mon==1)||(t.tm_mon==3)||(t.tm_mon==5)||(t.tm_mon==7)||(t.tm_mon==8)||(t.tm_mon==10))) + { + t.tm_mon+=1; + t.tm_mday=1; + } + if((t.tm_mday>31)&&(t.tm_mon==12)) + { + t.tm_mon=1; + t.tm_mday=1; + t.tm_year++; + } + if((t.tm_mday>28)&&(t.tm_mon==2)&&((((1900+t.tm_year)/4)!=0)||((((1900+t.tm_year)/100)==0)&&((1900+t.tm_year)/400)!=0))) + { + t.tm_mon+=1; + t.tm_mday=1; + } + if((t.tm_mday>29)&&(t.tm_mon==2)&&((((1900+t.tm_year)/400)==0)||((((1900+t.tm_year)/4)==0)&&((1900+t.tm_year)/100)!=0))) + { + t.tm_mon+=1; + t.tm_mday=1; + } + if((t.tm_mday>30)&&((t.tm_mon==4)||(t.tm_mon==6)||(t.tm_mon==8)||(t.tm_mon==9))) + { + t.tm_mon+=1; + t.tm_mday=1; + } + task_GPS(); + task_windy(); + task_DHT(); + timer.reset(); + } + if(timer2.read()> 10){ + t1.tm_min+=1; + if(t1.tm_min>59){ + t1.tm_min=0; + t1.tm_hour++; + } + if(t1.tm_hour>23){ + t1.tm_hour=0; + t1.tm_mday++; + } + if((t1.tm_mday>31)&&((t1.tm_mon==1)||(t1.tm_mon==3)||(t1.tm_mon==5)||(t1.tm_mon==7)||(t1.tm_mon==8)||(t1.tm_mon==10))) + { + t1.tm_mon+=1; + t1.tm_mday=1; + } + if((t1.tm_mday>31)&&(t1.tm_mon==12)) + { + t1.tm_mon=1; + t1.tm_mday=1; + t1.tm_year++; + } + if((t1.tm_mday>28)&&(t1.tm_mon==2)&&((((1900+t1.tm_year)/4)!=0)||((((1900+t1.tm_year)/100)==0)&&((1900+t1.tm_year)/400)!=0))) + { + t1.tm_mon+=1; + t1.tm_mday=1; + } + if((t1.tm_mday>29)&&(t1.tm_mon==2)&&((((1900+t1.tm_year)/400)==0)||((((1900+t1.tm_year)/4)==0)&&((1900+t1.tm_year)/100)!=0))) + { + t1.tm_mon+=1; + t1.tm_mday=1; + } + if((t1.tm_mday>30)&&((t1.tm_mon==4)||(t1.tm_mon==6)||(t1.tm_mon==8)||(t1.tm_mon==9))) + { + t1.tm_mon+=1; + t1.tm_mday=1; + } + task_MMA(); + task_resist(); + task_current(); + task_extend(); + timer2.reset(); + } + } +} +//---------------------------------------------------------- +void task_resist(){ +char filename[64]; +int command[8]={0x08, 0x03, 0x00, 0x01, 0x00, 0x02,0x95,0x52}; +char receice[8]={0}; +int j=0; + + for (int i=0; i<8; i++) { + while(1) + { + if (Mod.writeable()) + { + Mod.putc(command[i]); + break; + } + } + } + + for (int i=0; i<8; i++) { + while (j<7) { + if (Mod.readable()) { + receice[i]= Mod.getc(); + if(j>5) + { + sprintf(filename, "/sd/resist/%02d%02d%02d%02d%02d.txt",t1.tm_year-100,t1.tm_mon,t1.tm_mday,t1.tm_hour,t1.tm_min); + FILE *fp = fopen(filename, "a"); + fprintf(fp,"%.1f\r\n",((receice[3] << 8) + receice[4])/100.0); + fclose(fp); + printf("Resistance:%.1fΩ\r\n", ((receice[3] << 8) + receice[4])/100.0); + j++; + } + j++; + break; + } + } + + } +} +//---------------------------------------------------------- +void task_windy(){ +char filename[64]; +char command[17]; +int i = 0; +int j=1; +float windSpeed; +int windDirection; + for(j=1;j<17;j++) + { + command[i]= wind.getc(); + i++; + } + printf("\r\n"); + if(command[0]==0x3A){ + windSpeed=((command[8]-48)*10000+(command[9]-48)*1000+(command[10]-48)*100+(command[12]-48)*10+(command[13]-48))/100.0; + windDirection= (command[4]-48)*100+(command[5]-48)*10+(command[6]-48); + + sprintf(filename, "/sd/windy/%02d%02d%02d%02d%02d.txt",t.tm_year-100,t.tm_mon,t.tm_mday,t.tm_hour,t.tm_min); + FILE *fp = fopen(filename, "a"); + fprintf(fp,"%.2f\t",windSpeed); + fprintf(fp,"%d\r\n",windDirection); + fclose(fp); + + printf("The Wind Speed is %.2f (m/s)\r\n",windSpeed); + printf("The Wind Direction is %d",windDirection); + } + printf("\r\n"); +} +//---------------------------------------------------------- +void task_MMA(){ + char filename[64]; + int32_t x,y,z; + double x1,y1,z1; + double xg,yg,zg; + double xd,yd,zd; + acc.read(x,y,z); + + xg=x*0.016; //實際g值 + yg=y*0.016; //實際g值 + zg=z*0.016; //實際g值 + + x1=xg/(sqrt(pow(yg,2.0)+pow(zg,2.0))); + y1=yg/(sqrt(pow(xg,2.0)+pow(zg,2.0))); + z1=(sqrt(pow(yg,2.0)+pow(xg,2.0)))/zg; + + xd=atan(x1); //徑度 + yd=atan(y1); //徑度 + zd=atan(z1); //徑度 + + printf("xd: %.2f ",xd*180.0/PI); + printf("yd: %.2f ",yd*180.0/PI); + printf("zd: %.2f ",zd*180.0/PI); + sprintf(filename, "/sd/MMA/%02d%02d%02d%02d%02d.txt",t1.tm_year-100,t1.tm_mon,t1.tm_mday,t1.tm_hour,t1.tm_min); + FILE *fp = fopen(filename, "a"); + fprintf(fp,"%.2f\t",xd*180.0/PI); + fprintf(fp,"%.2f\t",yd*180.0/PI); + fprintf(fp,"%.2f\r\n",zd*180.0/PI); + fclose(fp); + printf("\r\n\n"); +} +//---------------------------------------------------------- +void task_DHT(){ + int error = 0; + int h, c,f; + float dp = 0.0f; + char filename[64]; + + wait(2.0f); + error = sensor.readData(); + if (0 == error) { + c = sensor.ReadTemperature(CELCIUS); + f = sensor.ReadTemperature(FARENHEIT); + h = sensor.ReadHumidity(); + dp = sensor.CalcdewPoint(c, h); + sprintf(filename, "/sd/DHT/%02d%02d%02d%02d%02d.txt",t.tm_year-100,t.tm_mon,t.tm_mday,t.tm_hour,t.tm_min); + FILE *fp = fopen(filename, "a"); + fprintf(fp,"%d\t",c); + fprintf(fp,"%d\t",f); + fprintf(fp,"%d\t",h); + fprintf(fp,"%4.2f\r\n",dp); + fclose(fp); + printf("Temperature in Celcius: %d, Farenheit %d\r\n", c, f); + printf("Humidity is %d, Dewpoint: %4.2f\r\n\n", h, dp); + } else { + printf("Error: %d\r\n", error); + } +} +//----------------------------------------------- +void task_current(){ +int i,j,temp; +char filename[64]; +int test[11240]; + for(i=0;i<11240;i++) + { + test[i] = adc.read_u16(); + } + for(j=0;j<11239;j++){ + if(test[j]>test[j+1]){ + temp=test[j]; + test[j+1]=test[j]; + test[j+1]=temp; + } + } + sprintf(filename, "/sd/current/%02d%02d%02d%02d%02d.txt",t1.tm_year-100,t1.tm_mon,t1.tm_mday,t1.tm_hour,t1.tm_min); + FILE *fp = fopen(filename, "a"); + fprintf(fp,"%.3f\r\n",(test[11239]*3.3/65535)); + fclose(fp); + printf("%f \r\n", (test[11239]*3.3/65535)); + wait(1); +} +//------------------------------------- +void task_GPS(){ + int ret; + char filename[64]; +#ifdef LARGE_DATA + char buf[2048] = ""; +#else + char buf[512] = ""; +#endif +#if 1 + GPSI2C gps; +#else + GPSSerial gps; +#endif + int count=0; + + while (count==0) { +#ifndef CELLOCATE + while ((ret = gps.getMessage(buf, sizeof(buf))) > 0) + { + int len = LENGTH(ret); + if ((PROTOCOL(ret) == GPSParser::NMEA) && (len > 6)) + { + if ((buf[0] == '$') || buf[1] == 'G') { + #define _CHECK_TALKER(s) ((buf[3] == s[0]) && (buf[4] == s[1]) && (buf[5] == s[2])) + if (_CHECK_TALKER("GLL")) { + double la = 0, lo = 0; + char ch; + if (gps.getNmeaAngle(1,buf,len,la) && + gps.getNmeaAngle(3,buf,len,lo) && + gps.getNmeaItem(6,buf,len,ch) && ch == 'A') + { + sprintf(filename, "/sd/GPS/%02d%02d%02d%02d%02d.txt",t.tm_year-100,t.tm_mon,t.tm_mday,t.tm_hour,t.tm_min); + FILE *fp = fopen(filename, "a"); + fprintf(fp,"%.5f %.5f\r\n", la, lo); + fclose(fp); + printf("GPS Location: %.5f %.5f\r\n", la, lo); + } + } else if (_CHECK_TALKER("GGA") || _CHECK_TALKER("GNS") ) { + double a = 0; + if (gps.getNmeaItem(9,buf,len,a)) // altitude msl [m] + { + sprintf(filename, "/sd/GPS/%02d%02d%02d%02d%02d.txt",t.tm_year-100,t.tm_mon,t.tm_mday,t.tm_hour,t.tm_min); + FILE *fp = fopen(filename, "a"); + fprintf(fp,"%.1f\r\n", a); + fclose(fp); + printf("GPS Altitude: %.1f\r\n", a); + } + } + } + count++; + } + } + if((ret = gps.getMessage(buf, sizeof(buf))) < 0) + { + + } +#endif + } +} +//--------------------------- +void task_extend(){ + sprintf(filename, "/sd/extend/%02d%02d%02d%02d%02d.txt",t1.tm_year-100,t1.tm_mon,t1.tm_mday,t1.tm_hour,t1.tm_min); + FILE *fp = fopen(filename, "a"); + fprintf(fp,"%.3f\r\n",adc.read_u16()*3.3/65535/0.29); + fclose(fp); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os.lib Tue Dec 12 12:29:05 2017 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#0712b8adf6bbc7eb796d5dac26f95d79d40745ef