GWのガイガーカウンタ自作チャレンジ(2台目) バッテリ駆動版(20)RTC日時合わせ入力

| | トラックバック(0)
今日は、自作ガイガーカウンタを、なんとかスタンドアロンで使えるように、mbedの内蔵RTC日時合わせを、オンボードのプッシュボタンで行えるように、ソフトウェアを修正した。ニックネーム「ドージ・メルたん(Dosemeter)」のステッカーも貼ってみた。

11092402.jpg 11092102.jpg
取り敢えず完成! これで、エクスプレッソへのポーティングが、少し近付いた。現在の回路図は、、、
11092101.jpgこんな感じ。フォームウェアは、、、、

// 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

リンク用バナ画像

Thank you for visitors:

from 7th, May. 2005

2013年11月

          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

MY TWITTER

今月のイラスト/ムービー

応援サイト、その他




Visit RenderSan
<-- script type="text/javascript" src="http://swf.mikunavi.net/miku" width=150 height=44 --><-- /script --><-- br / -->
 

このブログ記事について

このページは、Digi Pontaが2011年9月19日 23:22に書いたブログ記事です。

ひとつ前のブログ記事は「RenderMan Studio 3.0.3/RenderMan for Maya 4.0.3 released 」です。

次のブログ記事は「mbed NXP LPC1768のADC使用メモ」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.01

マイサイト





Trackback People






注)「Calture」の正しい綴りは、「Culture」です。お間違いないように。