GWのガイガーカウンタ自作チャレンジ(2台目) バッテリ駆動版(20)RTC日時合わせ入力
今日は、自作ガイガーカウンタを、なんとかスタンドアロンで使えるように、mbedの内蔵RTC日時合わせを、オンボードのプッシュボタンで行えるように、ソフトウェアを修正した。ニックネーム「ドージ・メルたん(Dosemeter)」のステッカーも貼ってみた。
取り敢えず完成! これで、エクスプレッソへのポーティングが、少し近付いた。現在の回路図は、、、
こんな感じ。フォームウェアは、、、、
こんな感じ。
// GM Counter firmware made by H. Inomata, (C) 2011 #include "mbed.h" #include "string.h" #include "SDFileSystem.h" #include "PowerControl/PowerControl.h" #include "EthernetPowerControl.h" #include "ClockControl.h" #include "TextLCD.h" DigitalOut cntRst(p15); DigitalOut pw400V(p16); DigitalOut ledActive(p18); DigitalOut ledEject(p19); DigitalOut LCD_wr(p27); InterruptIn intrQ01(p11); InterruptIn intrQ04(p12); InterruptIn intrQ08(p13); InterruptIn intrQ12(p14); DigitalOut rstCNT(p15); InterruptIn swAdjust(p28); DigitalIn swSd(p29); InterruptIn swEject(p30); InterruptIn swUp(p9); // InterruptIn swDown(p10); struct tm adjTm; Serial pc(USBTX, USBRX); // tx, rx SDFileSystem sd(p5,p6,p7,p8, "gm"); TextLCD lcd( p26, p25, p24, p23, p22, p21, TextLCD::LCD20x4 ); // rs, e, d4, d5, d6, d7 time_t seconds_prev; time_t seconds_begin; int need_mark = 0; Timer myTimer; Ticker myTicker; void nrm_handler_intrQ04 (void); void handler_swAdjust (void); void nrm_handler_swEject (void); void handler_ticker (void); void adj_handler_swEject(void); // input void adj_handler_swUp(void); void adj_handler_swDown(void); void nrm_set_intr_handlers(void); void adj_set_intr_handlers(void); int statDetect; int statEject; int statAdjust; // 1: Year, 2: Month, 3: Day, // 4: Hour, 5: Min #define USR_POWERDOWN (0x104) int semihost_powerdown() { uint32_t arg; return __semihost(USR_POWERDOWN, &arg); } class Watchdog { public: void kick(float s) { LPC_WDT->WDCLKSEL = 0x1; // Set CLK src to PCLK uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4 LPC_WDT->WDTC = s * (float)clk; LPC_WDT->WDMOD = 0x3; // Enabled and Reset kick(); } void kick() { LPC_WDT->WDFEED = 0xAA; LPC_WDT->WDFEED = 0x55; } }; Watchdog w; void updateLEDs(void) { if (statDetect || statEject || statAdjust ) { ledActive = 1; } else { ledActive = 0; } if (statEject) { ledEject = 1; } else { ledEject = 0; } } int main() { LCD_wr = 0; statDetect = 0; statEject = 0; statAdjust = 0; updateLEDs(); need_mark = 0; lcd.cls(); lcd.printf( " d(^_^)b "); lcd.locate(0,1); lcd.printf( "A GM Counter goes, " ); lcd.locate(0,2); lcd.printf( " designed by Digi-P"); lcd.locate(0,3); lcd.printf( " (C)2011 "); setSystemFrequency( 0x3, 0x1, 6, 1 ); // need a change to 4800bps PHY_PowerDown(); Peripheral_PowerDown( LPC1768_PCONP_PCADC | // LPC1768_PCONP_PCUART0 | LPC1768_PCONP_PCUART1 | LPC1768_PCONP_PCUART2 | LPC1768_PCONP_PCUART3 | // LPC1768_PCONP_PCSSP0 | // LPC1768_PCONP_PCSSP1 | LPC1768_PCONP_PCCAN1 | LPC1768_PCONP_PCCAN2 | LPC1768_PCONP_PCENET | LPC1768_PCONP_PCUSB | // LPC1768_PCONP_PCI2C0 | LPC1768_PCONP_PCI2C1 | LPC1768_PCONP_PCI2C2 | LPC1768_PCONP_PCPWM1 | LPC1768_PCONP_PCMCPWM ); semihost_powerdown(); w.kick(180.0); seconds_begin = seconds_prev = time(NULL); myTimer.reset(); myTimer.start(); nrm_set_intr_handlers(); myTicker.attach( &handler_ticker, 60.0); rstCNT = 0; // go counter pc.printf( "\rBegin Geiger Counter!\n" ); while(1) { Sleep(); // DeepSleep(); } } void nrm_set_intr_handlers(void) { swAdjust.fall( handler_swAdjust ); swEject.fall( nrm_handler_swEject ); intrQ04.fall( nrm_handler_intrQ04 ); swUp.fall( NULL ); swDown.fall( NULL ); } void adj_set_intr_handlers(void) { swAdjust.fall( handler_swAdjust ); swEject.fall( adj_handler_swEject ); swUp.fall( adj_handler_swUp ); swDown.fall( adj_handler_swDown ); intrQ04.fall( NULL ); } void handler_ticker (void) { time_t seconds = time(NULL); struct tm *tc = localtime( &seconds ); int min = tc->tm_min; pc.printf( "\r--- %d --- \n", min ); if ( (min % 10) == 0 ) { need_mark = 1; } } void nrm_handler_intrQ04 (void) { FILE *fp; time_t seconds; struct tm *tc; int myYear, myMon, myDay; int myHour, myMin, mySec; char fName[256]; int diff_msec; float cpm; statDetect = 1; diff_msec = myTimer.read_ms(); myTimer.reset(); seconds = time(NULL); seconds_prev = seconds; tc = localtime( &seconds ); myYear = tc->tm_year; myMon = tc->tm_mon; myDay = tc->tm_mday; myHour = tc->tm_hour; myMin = tc->tm_min; mySec = tc->tm_sec; updateLEDs(); if (1) // if (need_mark == 1) { need_mark = 0; if ( (swSd == 0) && (statEject == 0) ) { SDFileSystem sd(p5,p6,p7,p8, "gm"); sprintf( fName, "/gm/%04d%02d%02d.csv", myYear+1900, myMon+1, myDay ); fp = fopen ( fName, "a" ); // fp = fopen ( "/gm/test.txt", "a" ); if (fp != NULL ){ fprintf( fp , "%04d/%02d/%02d %02d:%02d:%02d, %d, %d, %d\n", myYear+1900, myMon+1, myDay, myHour, myMin, mySec, seconds, diff_msec, (16*60*1000*10)/(diff_msec) ); fclose( fp ); pc.printf( "\r%04d/%02d/%02d %02d:%02d:%02d, %d, %d, %d ", myYear+1900, myMon+1, myDay, myHour, myMin, mySec, seconds, diff_msec, (16*60*1000*10)/(diff_msec) ); lcd.cls(); lcd.printf( "GM Counter works ..." ); lcd.locate(0,1); cpm = (16.0*60.0*1000.0)/(diff_msec); lcd.printf( " %8.2f CPM (L)", cpm ); lcd.locate(0,2); lcd.printf( " %7d sec passed", seconds - seconds_begin); lcd.locate(0,3); lcd.printf(" %04d/%02d/%02d (%02d:%02d)", myYear+1900, myMon+1, myDay, myHour, myMin ); } else { pc.printf( "\rcan't open sd " ); lcd.cls(); lcd.printf( "GM Counter works ..." ); lcd.locate(0,1); lcd.printf("can't open sd-mem!"); } } else { pc.printf( "\rnone of sd or skip writeing it " ); lcd.cls(); lcd.printf( "GM Counter works ..." ); lcd.locate(0,1); lcd.printf("skip to log it!"); if ( (swSd != 0) && (statEject != 0) ) statEject = 0; } } else { pc.printf( "\rskip - %04d/%02d/%02d %02d:%02d:%02d, %d, %d, %d ", myYear+1900, myMon+1, myDay, myHour, myMin, mySec, seconds, diff_msec, (16*60*1000*10)/(diff_msec) ); lcd.cls(); lcd.printf( "GM Counter works ..." ); lcd.locate(0,1); cpm = (16.0*60.0*1000.0)/(diff_msec); lcd.printf( " %8.2f CPM (_)", cpm ); lcd.locate(0,2); lcd.printf( " %7d sec passed", seconds - seconds_begin); lcd.locate(0,3); lcd.printf(" %04d/%02d/%02d (%02d:%02d)", myYear+1900, myMon+1, myDay, myHour, myMin ); } if ( statAdjust != 0 ) { pc.printf( "- sw H - " ); } else { pc.printf( "- sw L - " ); } if ( statEject != 0 ) { pc.printf( "- ej H - " ); } else { pc.printf( "- ej L - " ); } if ( swSd != 0 ) { pc.printf( "- sd H - \n" ); } else { pc.printf( "- sd L - \n" ); } statDetect = 0; updateLEDs(); w.kick(); } void handler_swAdjust (void) { rstCNT = 1; adj_set_intr_handlers(); statAdjust = 1; updateLEDs(); time_t curTime = time(NULL); struct tm *curTm; curTm = localtime( &curTime ); adjTm.tm_year = curTm->tm_year; if ( (adjTm.tm_year + 1900) < 2011 ) { adjTm.tm_year = (2011 - 1900); } adjTm.tm_mon = curTm->tm_mon; adjTm.tm_mday = curTm->tm_mday; adjTm.tm_hour = curTm->tm_hour; adjTm.tm_min = curTm->tm_min; adjTm.tm_sec = 0; // default lcd.cls(); lcd.printf( "Input : Year (U/D)\n" ); lcd.printf( " %04d/%02d/%02d %02d:%02d\n", adjTm.tm_year + 1900, adjTm.tm_mon + 1, adjTm.tm_mday, adjTm.tm_hour, adjTm.tm_min ); } void adj_handler_swEject(void) { // to next time_t newTime; lcd.cls(); switch( statAdjust++ ) { case 1: // set year lcd.printf( "Input : Month (U/D)\n" ); break; case 2: // set month lcd.printf( "Input : Day (U/D)\n" ); break; case 3: // set day lcd.printf( "Input : Hour (U/D)\n" ); break; case 4: // set hour lcd.printf( "Input : Min (U/D)\n" ); break; case 5: // set min newTime = mktime( &adjTm ); set_time( newTime ); statAdjust = 0; nrm_set_intr_handlers(); rstCNT = 0; // go couting updateLEDs(); lcd.printf( "set to RTC:\n" ); if (statEject == 1) { lcd.printf( " You can eject a SD!\n" ); } else { lcd.printf( " waiting for a one!\n" ); } break; default: ; } lcd.printf( " %04d/%02d/%02d %02d:%02d\n", adjTm.tm_year + 1900, adjTm.tm_mon + 1, adjTm.tm_mday, adjTm.tm_hour, adjTm.tm_min ); } void adjTimeValue( int val ) { lcd.cls(); switch( statAdjust ) { case 1: // year adjTm.tm_year += val; if ( (adjTm.tm_year + 1900) < 2011 ) adjTm.tm_year = (2011 - 1900); if ( (adjTm.tm_year + 1900) > 2021 ) adjTm.tm_year = (2021 - 1900); lcd.printf( "Input : Year (U/D)\n" ); break; case 2: // month adjTm.tm_mon += val; if (adjTm.tm_mon < 0 ) adjTm.tm_mon = 11; if (adjTm.tm_mon > 11) adjTm.tm_mon = 0; lcd.printf( "Input : Month (U/D)\n" ); break; case 3: // Day adjTm.tm_mday += val; if (adjTm.tm_mday < 1 ) adjTm.tm_mday = 31; if (adjTm.tm_mday > 31 ) adjTm.tm_mday = 1; lcd.printf( "Input : Day (U/D)\n" ); break; case 4: // Hour adjTm.tm_hour += val; if ( adjTm.tm_hour < 0 ) adjTm.tm_hour = 23; if ( adjTm.tm_hour > 23 ) adjTm.tm_hour = 0; lcd.printf( "Input : Hour (U/D)\n" ); break; case 5: // Min adjTm.tm_min += val; if ( adjTm.tm_min < 0 ) adjTm.tm_min = 59; if ( adjTm.tm_min > 59 ) adjTm.tm_min = 0; lcd.printf( "Input : Min (U/D)\n" ); break; default: lcd.printf( "Input: Error (NOP)\n" ); } lcd.printf( " %04d/%02d/%02d %02d:%02d\n", adjTm.tm_year + 1900, adjTm.tm_mon + 1, adjTm.tm_mday, adjTm.tm_hour, adjTm.tm_min ); } void adj_handler_swUp(void) { adjTimeValue( 1 ); } void adj_handler_swDown(void) { adjTimeValue( -1 ); } void nrm_handler_swEject (void) { lcd.cls(); if (statEject == 1) { statEject = 0; lcd.printf( "GM Counter works,...\n" ); lcd.printf( " waiting for a one.\n"); } else { statEject = 1; lcd.printf( "You can eject a SD!\n" ); } updateLEDs(); }
こんな感じ。
トラックバック(0)
このブログ記事を参照しているブログ一覧: GWのガイガーカウンタ自作チャレンジ(2台目) バッテリ駆動版(20)RTC日時合わせ入力
このブログ記事に対するトラックバックURL: http://the.nerd.jp/blogs/cgi-bin/mt-tb.cgi/4690