変数の更新

解決


たく  2008-02-21 06:35:43  No: 67581

ある機器をシリアル通信で制御しようと思っています。
指令を出力し、300ms間応答が無ければ、04Hを出力し100ms待って、
再度、指令を出力・・・これを3回繰り返し駄目なら通信異常と判断します。
  この部分をforループで繰り返し、300ms、100msのSleepを入れました。
一方、シリアル通信の部分は、ActivXのMS_Commを使いました。
MS_Commでは、受信するとハード割り込みで受信イベントの処理を実行できるようです。

送信前に、フラグを0にして3回のforループに入り、フラグが1になるとループを
抜けるようにしました。
一方、受信するとフラグを1に変更するようにしました。

送受信の履歴を記録したところ
送信1
受信
送信2
送信3
となって、1度目の送信の後に受信されていますが、フラグの方はforループを抜けるまで
変更されていません。
UpdateData(TRUE)をいれてみても駄目でした。

このような状態で変数を更新するには、どうしたら良いでしょうか?
よろしく、お願いいたします。


ゴン  2008-02-22 01:23:45  No: 67582

UpdateData(TRUE)ってCWnd::UpdateData(BOOL)(ダイヤログのコントロールからメンバ変数へ値を取り込むための関数)ですよね?
それとフラグがどうして関係があるんですか?

int nTry = 3;
BOOL bRecieved = FALSE;

while (nTry-- && !bRecieved)
{
    if (<受信>)
        bRecieved = TRUE;

    Sleep(300);
}

とか云うことでは?


たく  2008-02-22 05:51:24  No: 67583

ゴンさま
UpdateDataは関係なかったですね

おっしゃる通り、ループの中で受信処理を書ければ問題ないなくできるのですが
MS_Commを使ってしまったので、受信関数がまったく別の関数になってしまい
こちらの関数はハード割り込みで呼ばれるようなのです。
Sleep(300)の間に実行されているようです。

フラグはpublic変数にしていますが、やはり、ループを抜けるまで関数の
更新はできないでしょうか?


rin  2008-02-22 06:06:07  No: 67584

開発環境や設定の情報は?
”フラグ”とやらがどんな変数でどう宣言されてるのか?
for文のところでどう使われてるのか?
”フラグ”によって、どのようにループを抜けるようにプログラムしたのか?


とーりすがり  2008-02-22 10:05:08  No: 67585

ループ内でフラグ更新してないから最適化で省かれたに一票


・・・。  2008-02-22 18:49:12  No: 67586

該当箇所のソースを提示した方が話は早いかも。。


たく  2008-02-24 03:59:32  No: 67587

少し長いのですが、ソース抜粋です。
①送信後 Sleep(300)の間に
③受信  ④フラグ更新しているようですが?
②に入りません
OnOnCommMscomm1はMSCommアイコンをダブルクリックで自動つかされた関数で、
呼ばれるタイミングも、こちらでは操作していません。

void CServoCntrlView::OnButton3() //送信処理
{
  char SOH = 0x01;
  char STX = 0x02;
  char ETX = 0x03;
  char EOT = 0x04;
  char TAB = 0x09;
    ・
    ・
  CString sendtxt;
  char chr;
  char ctimes;
  m_HandsF = 0;    //0:送信済み 1:受信あり 2:応答チェック済み

  for(int times = 0; times<3; times++)
  {
    //--------------------------------------- 送信
    for(int i=0; i<nn+2; i++)
    {
      chr = sendtxt.GetAt( i );
      SendBinary( &chr );        //①送信
    }

    //--------------------------------------- 履歴追加
    itoa( times+1, &ctimes, 10);

    m_RichEdit1 = m_RichEdit1 + "<Send>" + "(" + ctimes + ")" + TAB + m_Edit1 + TAB
          + m_Edit2 + TAB + m_Edit3 + TAB + m_Edit4 + '\r' + '\n';

    UpdateData(FALSE);

    Sleep(300);

    if(m_HandsF == 1)          //受信ありの場合
    {
      times = 9;          //②ここに入らない
    }
    else if(m_HandsF == 0 && times<3)    //受信が無い場合
    {
      chr = EOT;
      SendBinary( &chr );
      Sleep( 100 );

      m_RichEdit1 = m_RichEdit1 + "<Send> EOT" + '\r' + '\n';
      UpdateData(FALSE);
    }
  }
}

void CServoCntrlView::OnOnCommMscomm1() //OnCommイベント
{
  char TAB = 0x09;

  COleSafeArray aRecvData;  //Byte要素の1次元配列

  LPBYTE pRecvByte;

  int i = 0;
  int j;

  i = m_comm.GetCommEvent(); //イベントの種類を取得
  int nn = 0;
  CString EvnMsg;

  switch( i )
  {    //----------------------------イベントメッセージ
  case 1: //comEvSend
      break;
  case 2: //comEvReceive      //受信イベント
    
    aRecvData = m_comm.GetInput();
    aRecvData.AccessData((void**)&pRecvByte);

    nn = aRecvData.GetOneDimSize();
    
    if( nn )
    {
      m_RichEdit1 = m_RichEdit1 + "<Rece>" + TAB;  //③受信履歴追加
    }
        ・
        内容をm_RichEdit1へ追加
        ・
    m_RichEdit1 = m_RichEdit1 + " " + '\r' + '\n';
    UpdateData( FALSE );

    aRecvData.UnaccessData();

    m_HandsF = 1;            //④フラグ更新

    break;
  case 3: //comEvCTS
      break;
  case 4: //comEvDSR
      break;
  case 5: //comEvCD
      break;
  case 6: //comEvRing
      break;
  case 7: //comEvEOF
      break;
    ・
    ・
    ・
最適化で省かれたとは?


通りがかり  2008-02-24 04:25:02  No: 67588

RThresholdの設定してる?

MSCOMMって使ったことないんだけど、イベントは多分メッセージドリブンだよね?
本当にハード割り込みなら、m_HandsFに排他処理とRichEdit1の設定をPostMessageでやらないとぶつかりそう。


愛飢え男  2008-02-25 18:45:50  No: 67589

if(m_HandsF == 1) //受信ありの場合
  {
    break; // ループから抜ける //②ここに入らない
  }
  else
  {
    chr = EOT;
    SendBinary( &chr );
    Sleep( 100 );

    m_RichEdit1 = m_RichEdit1 + "<Send> EOT" + '\r' + '\n';
    UpdateData(FALSE);
  }

これで抜けなければ、"m_HandsF"を1にする方が間違ってる。


maru  2008-02-25 19:16:12  No: 67590

> ループ内でフラグ更新してないから最適化で省かれたに一票
私も一票。
m_HandsFの宣言にvolatileキーワードが付いていますか?


たく  2008-02-26 06:06:44  No: 67591

volatileを付けて2度目のループで抜けるようになりました。

ありがとうございまいした。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加