none
プログラムの起動時間について RRS feed

  • 質問

  • c++で長期間(2,3ヶ月)に渡り起動し続けるADDA変換プログラムを作成しました。

    しかし、一ヶ月後に確認した所プログラムが自動的に終了しておりました。

    Visual Studioで作成したプログラムに時間制限等はあるのでしょうか?

    ↓以下プログラム

    // ADinputView.cpp : CADinputView クラスの実装

    //

    #include "stdafx.h"
    #include "ADinput.h"
    #include "ADinputDoc.h"
    #include "ADinputView.h"

    #include "fbiad.h"
    #include "fbida.h"
    #include <math.h>
    #include <windows.h>
    #include <stdio.h>
    #include <conio.h>
    #include <mmsystem.h>
    #pragma comment(lib, "winmm.lib")


    #ifdef _DEBUG
    #define new DEBUG_NEW
    #define CLAMP(x, low, high) (x > high)? high : (x < low)? low : x
    #endif


    // CADinputView

    IMPLEMENT_DYNCREATE(CADinputView, CView)

    BEGIN_MESSAGE_MAP(CADinputView, CView)
    // 標準印刷コマンド
    ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CADinputView::OnFilePrintPreview)
    ON_COMMAND(ID_INPUTSINGLE, &CADinputView::OnInputsingle)
    ON_COMMAND(ID_STOP, &CADinputView::OnStop)
    END_MESSAGE_MAP()

    // CADinputView コンストラクション/デストラクション

    CADinputView::CADinputView()
    {
    // TODO: 構築コードをここに追加します。

    }

    CADinputView::~CADinputView()
    {
    }

    BOOL CADinputView::PreCreateWindow(CREATESTRUCT& cs)
    {
    // TODO: この位置で CREATESTRUCT cs を修正して Window クラスまたはスタイルを
    //  修正してください。

    return CView::PreCreateWindow(cs);
    }

    // CADinputView 描画

    void CADinputView::OnDraw(CDC* /*pDC*/)
    {
    CADinputDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
    return;

    // TODO: この場所にネイティブ データ用の描画コードを追加します。
    }


    // CADinputView 印刷


    void CADinputView::OnFilePrintPreview()
    {
    AFXPrintPreview(this);
    }

    BOOL CADinputView::OnPreparePrinting(CPrintInfo* pInfo)
    {
    // 既定の印刷準備
    return DoPreparePrinting(pInfo);
    }

    void CADinputView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
    // TODO: 印刷前の特別な初期化処理を追加してください。
    }

    void CADinputView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
    // TODO: 印刷後の後処理を追加してください。
    }

    void CADinputView::OnRButtonUp(UINT nFlags, CPoint point)
    {
    ClientToScreen(&point);
    OnContextMenu(this, point);
    }

    void CADinputView::OnContextMenu(CWnd* pWnd, CPoint point)
    {
    theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
    }


    // CADinputView 診断

    #ifdef _DEBUG
    void CADinputView::AssertValid() const
    {
    CView::AssertValid();
    }

    void CADinputView::Dump(CDumpContext& dc) const
    {
    CView::Dump(dc);
    }

    CADinputDoc* CADinputView::GetDocument() const // デバッグ以外のバージョンはインラインです。
    {
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CADinputDoc)));
    return (CADinputDoc*)m_pDocument;
    }
    #endif //_DEBUG

        HANDLE hAdDeviceHandle;
        HANDLE hDaDeviceHandle;

        char cDisp1[200];           // メッセージ配列
        char cDisp2[200]; 
        char cDisp3[200]; 
        char cDisp4[200]; 
        WORD wData1[1];             // データ配列
        WORD wData2[1];   
        WORD wData3[1];  
        double dVolt1;              // 電圧値
        double dVolt2; 
        double dVolt3; 
        ADBOARDSPEC AdDeviceInfo;     // ADBOARDSPEC 構造体
        ADSMPLREQ   AdSmplConfig;
    ADSMPLCHREQ SmplChReq[3];     // ADSMPLCHREQ 構造体
    DABOARDSPEC DaDeviceInfo;
        DASMPLREQ   DaSmplConfig;
    DASMPLCHREQ DaSmplChConfig[16];

    int flg=0;

    double soutai;//相対速度
        double soutaiA;//相対速度の絶対値
        double Fc;//要求出力
        double FcSaved;//要求出力制限
        double CoeV; //速度の係数
        double CoeD; //変位の係数
    double c; //減衰
    double h;
    double Scontrol; //速度比例
        double Seigyo1; //実験室_電流出力
        double Seigyo2; //住吉_電流出力
        double Saved1; //実験室_電流出力制限
        double Saved2; //住吉_電流出力制限
        WORD Vhenkan1;
        WORD Vhenkan2;

    //----------------------------------------------------------
    //AD初期化//
    //----------------------------------------------------------
    int InitializationAD(HANDLE *hDeviceHandle)
    { HANDLE tmp;
      int nRet;
      tmp= AdOpen ("FBIAD1");
        if (tmp == INVALID_HANDLE_VALUE)
            {
            AfxMessageBox("デバイスのオープンに失敗しました", MB_OK, 0);
            return -1;
            } 
    *hDeviceHandle=tmp;
        //デバイスの情報取得
            nRet = AdGetDeviceInfo( *hDeviceHandle, &AdDeviceInfo );
            if(nRet != AD_ERROR_SUCCESS)
    {
                AfxMessageBox("デバイスの情報取得に失敗しました", MB_OK, 0);
    return -1;
            }
            nRet = AdGetSamplingConfig( *hDeviceHandle, &AdSmplConfig );
            if(nRet != AD_ERROR_SUCCESS)
    {
                AfxMessageBox("デバイスの情報取得に失敗しました", MB_OK, 0);
    return -1;
            }


    return 0;

    }
    //---------------------------------------------------------------------------
    //DA初期化
    //---------------------------------------------------------------------------
    int InitializationDA(HANDLE *hDeviceHandle)
    {
    HANDLE tmp;
    int nRet;
    tmp = DaOpen("FBIDA1");
    if(tmp == INVALID_HANDLE_VALUE)
    {
    AfxMessageBox("デバイスのオープンに失敗しました",MB_OK,0);
    return -1;
    }
    *hDeviceHandle=tmp;
    //アナログ出力設定情報読み出し
    nRet = DaGetDeviceInfo(*hDeviceHandle,&DaDeviceInfo);
    if(nRet != DA_ERROR_SUCCESS){
    DaClose(hDeviceHandle);
    AfxMessageBox("アナログ入力更新1に失敗しました");
    return -1;
    }

    nRet = DaGetSamplingConfig(*hDeviceHandle,&DaSmplConfig);
    if(nRet != DA_ERROR_SUCCESS){
    DaClose(hDeviceHandle);
    AfxMessageBox("アナログ入力更新2に失敗しました");
    return -1;
    }

    //ボードの設定
    nRet = DaSetBoardConfig(*hDeviceHandle,200,NULL,NULL,0);
    if(nRet != DA_ERROR_SUCCESS){
    AfxMessageBox("ボードの設定に失敗しました");
    return -1;
    }
    return 0;
    }

    //----------------------------------------------------------------------------------
    //取得
    //----------------------------------------------------------------------------------

    int GetData(HANDLE hDeviceHandle)
    {
    int nRet;                  // 関数の実行結果
        SmplChReq[0].ulChNo = 1;
        SmplChReq[0].ulRange = AD_10V; // インタフェースモジュールの初期化を行います
        SmplChReq[1].ulChNo = 2;
        SmplChReq[1].ulRange = AD_10V; // インタフェースモジュールの初期化を行います
        SmplChReq[2].ulChNo = 3;
        SmplChReq[2].ulRange = AD_10V; // インタフェースモジュールの初期化を行います

            //サンプリング1
            nRet = AdInputAD( hDeviceHandle, 1, AD_INPUT_SINGLE, &SmplChReq[0], wData1);
            if(nRet != AD_ERROR_SUCCESS)
    {
                AfxMessageBox("アナログ入力に失敗しました", MB_OK, 0);
            }
    else{
                //電圧算出
    dVolt1 =( 10/pow(2.0, (int)AdDeviceInfo.ulResolution)*wData1[0] - 5)*2/5;
                sprintf_s(cDisp1, "Ch1入力速度は%1.5fm/sです", dVolt1);
                //AfxMessageBox(cDisp1, MB_OK, 0);
            }
            //サンプリング2
            nRet = AdInputAD( hDeviceHandle, 1, AD_INPUT_SINGLE, &SmplChReq[1], wData2);
            if(nRet != AD_ERROR_SUCCESS)
    {
                AfxMessageBox("アナログ入力に失敗しました", MB_OK, 0);
            }
    else{
                //電圧算出
    dVolt2 =( 10/pow(2.0, (int)AdDeviceInfo.ulResolution)*wData2[0] - 5)*2/5;
                sprintf_s(cDisp2, "Ch2入力速度は%1.5fm/sです", dVolt2);
                //AfxMessageBox(cDisp2, MB_OK, 0);
            }
            //サンプリング3
            nRet = AdInputAD( hDeviceHandle, 1, AD_INPUT_SINGLE, &SmplChReq[2], wData3);
            if(nRet != AD_ERROR_SUCCESS)
    {
                AfxMessageBox("アナログ入力に失敗しました", MB_OK, 0);
            }
    else{
                //電圧算出
    dVolt3 =( 10/pow(2.0, (int)AdDeviceInfo.ulResolution)*wData3[0] - 5)*2/20;
                sprintf_s(cDisp3, "Ch3入力変位は%1.5fmです", dVolt3);
               //AfxMessageBox(cDisp3, MB_OK, 0);
            }

    ///入力はm,m/s
    soutai=dVolt1;
    soutaiA=abs(soutai);


    /////最適制御//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    CoeD=967675;////解析での左
    CoeV=-2006249;///解析での右
    Fc =(-CoeV*soutai-CoeD*dVolt3)/1000;
    FcSaved =abs(min(max(Fc, -400), 400)); 
    Seigyo1 =abs((-(-33.49-0.113*soutaiA)-pow(pow((-33.49-0.113*soutaiA),2)-4*1.58*(-10.50-0.024*soutaiA+FcSaved*1000),0.5))/3.16);///実験室N,m/s
    Seigyo2 =abs((63.86-pow((pow(63.86,2)+4*0.58*(133*soutaiA-FcSaved)),0.5))/1.16);//住吉ダンパーkN,m/s
    Saved1 =min(max(Seigyo1, 0), 3)*2; 
    Saved2 =min(max(Seigyo2, 0), 5)*4*2/3.0;
    Vhenkan1=(Saved1+10)/0.00030517;

    if(Saved2< 0.5){
     Vhenkan2=(0*2+10)/0.00030517;
    }
    else if(Saved2>= 0.5){
     Vhenkan2=(Saved2+10)/0.00030517;
    }
    else{
    ;
    }
    sprintf_s(cDisp4, "Ch1出力電流は%1.9fAです", Seigyo2);
    //AfxMessageBox(cDisp4, MB_OK, 0);
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    ////スカイフック制御////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //if(((soutai+dVolt2)*dVolt2) < 0){
    //    Vhenkan1=(0*2+10)/0.00030517;
    //}
    //else if(soutaiA > 0 && soutaiA <= 0.05){
    // Vhenkan1=(0*2+10)/0.00030517;
    //}
    //else if(soutaiA > 0.05 && soutaiA <= 0.05){
    // Vhenkan1=(1.5*2+10)/0.00030517;
    //}
    //else if(soutaiA > 0.05){
    // Vhenkan1=(1.5*2+10)/0.00030517;
    //}
    //else{
    // ;
    //}
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    ///////速度比例制御//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //h=0.5;
    //c=2*h*pow((109.91*9.8*1085),0.5);
    //Scontrol=abs(c*soutai);
    //Seigyo1 =(-(-33.49-0.113*soutaiA)-pow(pow((-33.49-0.113*soutaiA),2)-4*1.58*(-10.50-0.024*soutaiA+Scontrol),0.5))/3.16;///実験室N,m/s
    //Seigyo2 =pow((63.86-pow(63.86,2)+4*0.58*(133*soutaiA-Scontrol/1000.0)),0.5)/3.16;//住吉ダンパーkN,m/s    Scontrolの倍率??????
    //Saved1 =min(max(Seigyo1, 0), 3)*2; 
    //Saved2 =min(max(Seigyo2, 0), 5)*2;
    //Vhenkan1=(Saved1+10)/0.00030517;
    //Vhenkan2=(Saved2+10)/0.00030517;
    //sprintf_s(cDisp4, "Ch1出力電流は%1.3fAです", Seigyo1);
    ////AfxMessageBox(cDisp4, MB_OK, 0);
    //
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    return 0;
    }

    //-------------------------------------------------------------------------------------
    //出力(WORD型で)
    //-------------------------------------------------------------------------------------
    int SetData(HANDLE hDeviceHandle)
    {
    INT nRet;
    //出力設定
    DaSmplChConfig[0].ulChNo = 1; //出力チャンネル= チャンネル1
    DaSmplChConfig[0].ulRange = DA_10V; //出力レンジ= ±10V

    nRet = DaOutputDA(hDeviceHandle, 1,DaSmplChConfig,&Vhenkan2);
    if(nRet != DA_ERROR_SUCCESS){
    AfxMessageBox("アナログ出力更新に失敗しました");


    return -1;
    }
    return 0;
    }

    //-----------------------------------------------------------------------------
    //AD終了
    //-----------------------------------------------------------------------------

    int EndAD(HANDLE hDeviceHandle)
    {
     int nRet;
     nRet = AdClose( hDeviceHandle );
     if (nRet != AD_ERROR_SUCCESS) {
     AfxMessageBox("デバイスのクローズに失敗しました");
        }
     return 0;
    }

    //-----------------------------------------------------------------------------
    //DA終了
    //-----------------------------------------------------------------------------

    int EndDA(HANDLE hDeviceHandle)
    {
     int nRet;
     nRet = DaClose( hDeviceHandle );
     if (nRet != DA_ERROR_SUCCESS) {
     AfxMessageBox("デバイスのクローズに失敗しました");
        }
     return 0;
    }

    //-----------------------------------------------------------------------------
    //タイムハンドラ
    //-----------------------------------------------------------------------------

    void CALLBACK
    cyclic(UINT uTimerID, UINT uMsg, DWORD * dwUser, DWORD * dw1, DWORD * dw2)
    {
    int nRet;
    if(flg){
    //取得
    nRet=GetData(hAdDeviceHandle);
    if(nRet != 0){
    return;
    }
    //出力
    nRet=SetData(hDaDeviceHandle);
    if(nRet != 0){
    return;
    }
    }
    }

    //-----------------------------------------------------------------------------
    //メイン
    //-----------------------------------------------------------------------------
    void CADinputView::OnInputsingle()
    {
    int nRet;
    UINT TimerId;
    //初期化
    nRet = InitializationAD(&hAdDeviceHandle);
    if(nRet != 0){
    AdClose(hAdDeviceHandle);
    return ;
    }
    nRet = InitializationDA(&hDaDeviceHandle);
    if(nRet != 0){
    AdClose(hDaDeviceHandle);
    return ;
    }
    TimerId = timeSetEvent(10,0,(LPTIMECALLBACK)cyclic,0,TIME_PERIODIC);
    if(TimerId==0){
    printf("timeSetEvent error");
         AdClose(hAdDeviceHandle);
         DaClose(hDaDeviceHandle);
         return ;
    }
    flg =1;

    //待機
    printf("Hit any key\n");
    while(!_kbhit());
    //タイマイベント解除
    timeKillEvent(TimerId);

    //終了
    nRet = EndAD(hAdDeviceHandle);
    if(nRet != 0){
    AdClose(hAdDeviceHandle);
    DaClose(hDaDeviceHandle);
    return ;
    }
    nRet = EndDA(hDaDeviceHandle);
    if(nRet != 0){
    DaClose(hDaDeviceHandle);
    return ;
    }
    return ;
    }






    void CADinputView::OnStop()
    {  
    }

          
    2012年6月27日 4:52

回答

  • >Visual Studioで作成したプログラムに時間制限等はあるのでしょうか?

    特に定められているわけではないです。

    プログラムが終了した理由(=メモリ不足、リソース不足、例外など)はつかめてないんですか?

    • 回答の候補に設定 山本春海 2012年7月11日 8:49
    • 回答としてマーク 山本春海 2012年8月1日 8:24
    2012年6月27日 5:38
  • 処理が終わっていたというのなら、誰かがキーボードに触ったとか。プロセスが終わっていたというのなら、異常終了したか、OSが再起動(セキュリティパッチで自動的にOS再起動するときあります)か、かなぁ。

    結局は、ログを出力するようにしたりして、終わったときの流れを調べないと分からないかな。

    • 回答の候補に設定 山本春海 2012年7月11日 8:49
    • 回答としてマーク 山本春海 2012年8月1日 8:24
    2012年6月27日 14:09

すべての返信

  • >Visual Studioで作成したプログラムに時間制限等はあるのでしょうか?

    特に定められているわけではないです。

    プログラムが終了した理由(=メモリ不足、リソース不足、例外など)はつかめてないんですか?

    • 回答の候補に設定 山本春海 2012年7月11日 8:49
    • 回答としてマーク 山本春海 2012年8月1日 8:24
    2012年6月27日 5:38
  • 処理が終わっていたというのなら、誰かがキーボードに触ったとか。プロセスが終わっていたというのなら、異常終了したか、OSが再起動(セキュリティパッチで自動的にOS再起動するときあります)か、かなぁ。

    結局は、ログを出力するようにしたりして、終わったときの流れを調べないと分からないかな。

    • 回答の候補に設定 山本春海 2012年7月11日 8:49
    • 回答としてマーク 山本春海 2012年8月1日 8:24
    2012年6月27日 14:09
  • こんにちは、junglemeji さん。

    MSDN フォーラムのご利用ありがとうございます。オペレーターの山本です。

    問題の切り分けに参考になるアドバイスをいただいているかと思われましたので、勝手ながら私のほうで一旦回答としてマークさせていただきました。
    アドバイスくださったみなさん、情報ありがとうございます。

    今後とも MSDN フォーラムをよろしくお願いいたします。
    __________________________
    日本マイクロソフト株式会社 フォーラム オペレーター 山本 春海

    2012年8月1日 8:24