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








