Dependencies: ChaNFSSD mbed BMP085 SHT2x
main.cpp
- Committer:
- tosihisa
- Date:
- 2012-02-05
- Revision:
- 5:3a1ce282892c
- Parent:
- 4:879b8dcfee15
- Child:
- 6:4af28d398585
File content as of revision 5:3a1ce282892c:
/* * このソフトウェアは、大阪市立大学と京都大学生存圏ミッション研究の共同研究の成果物です。 * ソースコードそのもののライセンスは、各ソースコードのライセンスに沿って公開します。 * 2012-1-4 Toshihisa T */ #define __MY_VERSION__ "0.83" #define HAVE_TOGGLE_SW #define HAVE_MICROSD #include "mbed.h" #include "NMEA_parse.h" #include "SDFileSystem.h" #include "libT/mbed/tserialbuffer.h" #include "BMP085.h" #include "SHT2x.h" #include "AD7994.h" //#include "TextLCD.h" #include "TextLCD_20X4.h" #include "UBXPacket.h" using namespace libT; #define _USE_FS_NAME "sd" Serial debug(USBTX,USBRX); DigitalIn gps_int0(p24); DigitalOut gps_reset(p25); InterruptIn gps_pps(p26); tSerialBuffer gps(p28,p27); DigitalOut gps_pps_led(LED2); I2C i2c(p9, p10); // sda, scl BMP085 bmp085(p9, p10); int bmp085_find = 0; SHT2x sht25(p9,p10); int sht25_find = 0; AD7994 ad7994(p9,p10); int ad7994_find = 0; TextLCD_20X4 lcd(p15, p16, p17, p18, p19, p20); // rs, e, d4-d7 #ifdef HAVE_TOGGLE_SW /* { */ DigitalIn toggleSW(p22); int toggleSW_scan = 0; int toggleSW_pre = -1; #endif /* } */ int toggleSW_now = 0; Ticker tick; tSerialBuffer CO2(p13,p14); Timer CO2_TMOUT; SDFileSystem sd(p5, p6, p7, p8, _USE_FS_NAME); int avaiableSD = -1; unsigned short logNextCount = 0; FILE *csvFP = NULL; FILE *gpsFP = NULL; int logSW = 0; DigitalOut logled(LED3); DigitalOut myled(LED1); struct UBXPacket_s UBXPacket; int pps_count = 0; void gps_pps_rise() { gps_pps_led = ((pps_count+=1) & 1) ? 1 : 0; } void logFile_Init() { DIR *d; struct dirent *p; unsigned short countCandidate; char *endptr; avaiableSD = 0; d = opendir("/" _USE_FS_NAME); if ( d != NULL ) { while ( (p = readdir(d)) != NULL ) { debug.printf("FILE - %s\x0d\x0a", p->d_name); if (strlen(p->d_name) == (sizeof("ENVxxxxx.CSV")-1)) { if ( ((p->d_name[0] == 'E') || (p->d_name[0] == 'e')) && ((p->d_name[1] == 'N') || (p->d_name[1] == 'n')) && ((p->d_name[2] == 'V') || (p->d_name[2] == 'v'))) { } countCandidate = (unsigned short)strtoul(&(p->d_name[3]),&endptr,10); if (strcasecmp(endptr,".CSV") == 0) { if (countCandidate > logNextCount) { logNextCount = countCandidate; } } } } closedir(d); logNextCount++; avaiableSD = 1; } } int CO2_Read(unsigned short *val) { unsigned char sbuf[] = { 0xFE, 0x04, 0x00, 0x03, 0x00, 0x01, 0xD5, 0xC5 }; unsigned char rbuf[7]; int i; unsigned short crc; extern unsigned short modbus_CRC(unsigned char *DataPtr, unsigned short len); for(i=0;i < sizeof(sbuf);i++){ //debug.printf("0x%02x ",sbuf[i]); CO2.putc(sbuf[i]); } CO2_TMOUT.start(); for(i=0;i < sizeof(rbuf);i++){ while(!CO2.readable()){ if(CO2_TMOUT.read_ms() >= 1000){ return -99; /* TIMEOUT */ } } rbuf[i] = CO2.getc(); } if(rbuf[0] != 0xFE){ return -4; } if(rbuf[1] != 0x04){ return -1; } if(rbuf[2] != 0x02){ return -2; } crc = rbuf[6]; crc = (crc << 8) | rbuf[5]; if(crc != modbus_CRC(rbuf,5)){ return -3; } *val = rbuf[3]; *val = (*val << 8) | rbuf[4]; return 0; } // BMP085 0xee // AD7994 0x44 // SHT2x 0x80 int i2c_found() { int count = 0; lcd.locate(0,0); lcd.printf("%-19s","I2C Dev:"); lcd.locate(8,0); for (int address=0; address<256; address+=2) { if (!i2c.write(address, NULL, 0)) { // 0 returned is ok switch(address){ case 0xee: bmp085_find = 1; break; case 0x44: ad7994_find = 1; break; case 0x80: sht25_find = 1; break; default: break; } lcd.printf("%02X ",address); count++; } } return count; } unsigned char NMEA_CalcSum(unsigned char *str,int len) { unsigned char sum = 0; int i; for(i = 0;i < len;i++){ sum = sum ^ (*(str + i)); } return sum; } void UBX_CalcSum(unsigned char *str,int len,unsigned char *sum) { int i; *(sum + 0) = *(sum + 1) = 0; for(i = 0;i < len;i++){ *(sum + 0) = *(sum + 0) + *(str+i); *(sum + 1) = *(sum + 1) + *(sum + 0); } } int UBX_WaitAck(struct UBXPacket_s *info) { UBXPacket.cjobst = 0; while(1){ while(gps.readable()) { if(UBXPacket_Parse(&UBXPacket,gps.getc()) == 100){ if((UBXPacket.cls == 0x05) && (UBXPacket.id == 0x01)){ return 1; /* ACK */ } else if((UBXPacket.cls == 0x05) && (UBXPacket.id == 0x00)){ return 0; /* NAK */ } else { UBXPacket.cjobst = 0; } } } } } unsigned long scanCount = 0; unsigned long tickCount = 0; unsigned long hzCount = 0; unsigned long hzCount_tmp = 0; void tickHandler() { scanCount++; tickCount++; hzCount_tmp++; if(hzCount_tmp >= 50){ hzCount_tmp = 0; hzCount++; } #ifdef HAVE_TOGGLE_SW /* { */ int nowRead; nowRead = toggleSW.read(); if(nowRead != toggleSW_pre){ toggleSW_pre = nowRead; toggleSW_scan = 0; } else { toggleSW_scan++; if(toggleSW_scan >= 3){ toggleSW_now = toggleSW_pre; toggleSW_scan = 0; } } #endif } void logCheckProc() { if((logSW == 0) && (toggleSW_now != 0)){ if(csvFP != NULL){ fclose(csvFP); csvFP = NULL; if(gpsFP != NULL){ fclose(gpsFP); gpsFP = NULL; } logled = 0; /* No logging */ logNextCount++; } else { char name[64]; sprintf(name,"/%s/ENV%05d.CSV",_USE_FS_NAME,logNextCount); csvFP = fopen(name,"w+b"); sprintf(name,"/%s/ENV%05d.GPS",_USE_FS_NAME,logNextCount); gpsFP = fopen(name,"w+b"); if((csvFP != NULL) && (gpsFP != NULL)){ logled = 1; /* logging */ } else { if(csvFP) fclose(csvFP); if(gpsFP) fclose(gpsFP); logled = 0; /* Cannot start logging */ } } } logSW = toggleSW_now; } unsigned char wbuf[1024]; int widx = 0; void ClearScreen(void) { lcd.locate(0,0); lcd.printf("%20s"," "); lcd.locate(0,1); lcd.printf("%20s"," "); lcd.locate(0,2); lcd.printf("%20s"," "); lcd.locate(0,3); lcd.printf("%20s"," "); } int main() { int ret = 0; float p, t1; float h, t2; int temp; unsigned short CO2_val = 0; char c; unsigned long UBXCount = 0; int GPS_isRaw = 0; int CO2_find = 0; int year=0; int mon=0; int day=0; int hour=0; int min=0; int sec=0; int pre_sec = -1; p = -99.0; t1 = -99.0; t2 = -99.0; h = -99.0; tick.attach_us(&tickHandler,(10*1000)); debug.format(8,Serial::None,1); debug.baud(115200); debug.printf("ENV Logger \"%s\" Start (BUILD:[" __DATE__ "/" __TIME__ "])\n",__MY_VERSION__); lcd.locate(0,0); lcd.printf("ENV Logger \"%s\"",__MY_VERSION__); lcd.locate(0,1); lcd.printf("WAKE UP I/O..."); wait(5.0); ClearScreen(); //=================================================== i2c_found(); //=================================================== CO2.format(8,Serial::None,1); CO2.baud(9600); CO2.recvStart(); lcd.locate(0,1); lcd.printf("Check CO2:"); CO2_find = 0; ret = CO2_Read(&CO2_val); switch(ret){ case 0: lcd.printf("OK"); CO2_find = 1; break; case -99: lcd.printf("NOT FOUND"); break; default: lcd.printf("NG"); break; } CO2_val = 0; //=================================================== lcd.locate(0,2); lcd.printf("Initalize GPS:"); UBXPacket.cjobst = 0; gps_pps.rise(gps_pps_rise); gps.format(8,Serial::None,1); gps.baud(9600); gps_reset = 1; wait(0.5); gps_reset = 0; wait(0.5); if(1){ //unsigned char modeStr[] = "PUBX,41,1,0007,0003,115200,0"; unsigned char modeStr[] = "PUBX,41,1,0007,0001,115200,0"; unsigned char sum = NMEA_CalcSum(modeStr,strlen((char *)modeStr)); debug.printf("SEND:[%s](0x%02X)\n",modeStr,sum); gps.printf("$%s*%02X%c%c",modeStr,sum,0x0d,0x0a); debug.printf("CHG BAUD:115200\n"); gps.format(8,Serial::None,1); gps.baud(115200); } gps.recvStart(); wait(0.5); GPS_isRaw = 1; if(1){ unsigned char chkStr[][11] = { { 0xB5,0x62,0x06,0x01,0x03,0x00,0x02,0x10,0x01,0xFF,0xFF }, //RXM-RAW (0x02 0x10) { 0xB5,0x62,0x06,0x01,0x03,0x00,0x02,0x30,0x01,0xFF,0xFF }, //RXM-ALM (0x02 0x30) { 0xB5,0x62,0x06,0x01,0x03,0x00,0x02,0x31,0x01,0xFF,0xFF }, //RXM-EPH (0x02 0x31) //{ 0xB5,0x62,0x06,0x01,0x03,0x00,0x02,0x41,0x02,0xFF,0xFF }, { 0xB5,0x62,0x06,0x01,0x03,0x00,0x02,0x11,0x01,0xFF,0xFF }, //RXM-SFRB (0x02 0x11) { 0xB5,0x62,0x06,0x01,0x03,0x00,0x02,0x20,0x01,0xFF,0xFF }, //RXM-SVSI (0x02 0x20) { 0xB5,0x62,0x06,0x01,0x03,0x00,0x01,0x21,0x01,0xFF,0xFF }, //NAV-TIMEUTC (0x01 0x21) { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF }, //END }; int i,j; int isAck; for(j=0;chkStr[j][0] != 0x00;j++){ UBX_CalcSum(&chkStr[j][2],7,&chkStr[j][9]); for(i = 0; i < sizeof(chkStr[0]);i++){ gps.putc(chkStr[j][i]); } isAck = UBX_WaitAck(&UBXPacket); debug.printf("%d : SET UBX Rate : %s\n",j,(isAck == 1) ? "ACK" : "NAK"); if(isAck != 1){ GPS_isRaw = 0; } } } UBXPacket.cjobst = 0; lcd.locate(0,2); lcd.printf("Initalize GPS:%s",(GPS_isRaw) ? "OK" : "NG"); // ad7994.Start(); //=================================================== #ifdef HAVE_MICROSD lcd.locate(0,3); lcd.printf("Check MicroSD:"); logFile_Init(); #endif lcd.locate(0,3); switch(avaiableSD){ case 0: lcd.printf("Check MicroSD:NG"); break; case 1: lcd.printf("Check MicroSD:OK"); break; default: lcd.printf("Check MicroSD:DO\'NT USE"); break; } //=================================================== wait(3.0); ClearScreen(); pre_sec = -1; while(1) { //lcd.cls(); //lcd.locate(0,0); //lcd.printf("SCAN:%-10ld",scanCount); logCheckProc(); while(gps.readable()) { c = gps.getc(); if(UBXPacket_Parse(&UBXPacket,c) == 100){ UBXCount++; if((UBXPacket.cls == 0x01) && (UBXPacket.id == 0x21)){ /* NAV-TIMEUTC */ year = (((unsigned short)UBXPacket.body[13]) << 8) | UBXPacket.body[12]; mon = UBXPacket.body[14]; day = UBXPacket.body[15]; hour = UBXPacket.body[16]; min = UBXPacket.body[17]; sec = UBXPacket.body[18]; } debug.printf("%ld : GET UBX Packet (Class=0x%02X,ID=0x%02X,LEN=%d)\n", scanCount, UBXPacket.cls, UBXPacket.id, UBXPacket.len ); UBXPacket.cjobst = 0; } if(gpsFP != NULL){ wbuf[widx] = c; widx++; if(widx >= sizeof(wbuf)){ fwrite(&wbuf,sizeof(wbuf[0]),widx,gpsFP); widx = 0; } } } lcd.locate(0,0); lcd.printf("%c%04d-%02d-%02d %02d:%02d:%02d",(gpsFP) ? '*' : ' ',year,mon,day,hour,min,sec); if(pre_sec != sec){ pre_sec = sec; if(bmp085_find){ float tmp1,tmp2; bmp085.update(); tmp1 = bmp085.get_pressure(); tmp2 = bmp085.get_temperature(); if(tmp2 < 100.0){ p = tmp1; t1 = tmp2; } } lcd.locate(0,1); lcd.printf("%-8.2fhPa %-6.2fC", p, t1); if(sht25_find){ if(sht25.SHT2x_MeasurePoll(TEMP,&temp) == 0){ t2 = sht25.SHT2x_CalcTemperatureC(temp); } if(sht25.SHT2x_MeasurePoll(HUMIDITY,&temp) == 0){ h = sht25.SHT2x_CalcRH(temp); } sht25.SHT2x_SoftReset(); } lcd.locate(0,2); lcd.printf("%-6.2fC %-6.2fRH", t2, h); if(CO2_find){ if((ret = CO2_Read(&CO2_val)) != 0){ CO2_val = 0; CO2_find = 0; } } lcd.locate(0,3); lcd.printf("CO2:%5d.%1dppm\n",CO2_val/10,CO2_val%10); if(csvFP){ fprintf(csvFP,"%04d-%02d-%02d %02d:%02d:%02d,",year,mon,day,hour,min,sec); fprintf(csvFP,"%-8.2f,hPa,%-6.2f,C,%-6.2f,C,%-6.2f,RH,%5d.%1d,ppm\x0d\x0a", p, t1, t2, h,CO2_val/10,CO2_val%10); } } #if 0 ad7994.update(); lcd.locate(0,3); lcd.printf("A/D:%04X/%04X", ad7994.readChn(0), ad7994.readChn(1)); #endif myled = (hzCount & 1); //wait(0.1); } } /* * 2012-2-5 V0.83 * センサー、I/Oの検出順番を変更(H/W 組立時の試験を兼ねる) * 下記の順番でセンサーやI/Oの検出をする。 * I2C → CO2センサー → U-Blox(raw-mode) → マイクロSD * マイクロSD が未装着でも U-Blox の raw-mode までは * 進めるので、H/W 組立後の基本チェックが可能。 */ /* * 2012-2-5 V0.82 * バイクによる実走試験での結果を反映。 * 1) ログボタンのON/OFFでLEDも光らせるが、ケースに収めると * LED だと分からなくなるので、液晶画面でもログのON/OFFが * 分かるようにした。ログをONすると、画面左上に'*'を出す。 * 2) SHT25 が、時々オフセットがかかったかの様な値を返すので、 * 下記の修正を行った。但しこの修正が確実かはまだ分からない。 * a) 関数の戻り値が正常な場合に値を採用する。これは必要。 * b) 温湿度の取得後、SHT25 に対してソフトリセット命令を * 毎回送る。これでうまく行くようならこれでいく。 */ /* * 2012-2-5 V0.81 * 気圧センサーが時々不正な値を出力する。気温が100度を超える値になる。 * ソフトバグか、センサー自身の問題かは切り分けていないが、気温が100度を * 超えることはあり得ないので、100度を超える気温は値として採用しない様に * した。 */ /* * 2012-2-5 V0.8 * 1) GPS レシーバ受信バッファが少ないので拡大(512->8K) * 2) 起動時に、各センサーの接続チェックを行い、起動時に見つかった * センサーとだけ通信するようにした。これにより CO2 センサーが * 無くても動きます。 * 3) NAV-TIMEUTC を受信し、表示するようにした。 * 4) センサーデータのスキャンタイミングを、NAV-TIMEUTC の * 秒が変わった直後とした。つまり1秒おきにセンサーデータを * スキャンする。 * 5) センサーデータの保存データ(ENVnnnnn.CSV) の先頭に * NAV-TIMEUTC の日付時刻を入れるようにした。 * これで何時何分のセンサーデータか分かるようにした。 */ /* * 2012-1-29 V0.7 * ログ機能の追加。スイッチを押すとログのON/OFFが出来る。 * ログ収集中は、mbed LED3 が点灯する。 */ /* * 2012-1-29 V0.6 * 1) スキャンカウントの変更。今までは1秒周期だったが、 * 100ミリ秒周期でセンサーデータを得るようにした。 * 2) モーメンタリSW対応。 */ /* * 2012-1-23 V0.5 * U-Blox,気圧センサー,温度センサー,CO2センサーの値を表示するようにした。 * U-Blox は受信できたパケット数を表示する。 * マイクロSDへの保存機能はまだ(H/W的に動くのは確認済み) */