CodeZine(コードジン)

特集ページ一覧

C#で学ぶインターネット時代のシリアル通信(後編)

C#によるシリアル通信を使ったより実践的なアプリケーション作成

  • LINEで送る
  • このエントリーをはてなブックマークに追加
目次

抽選用ソフト

 このプログラムは大きく分けて2つの処理がほぼ同時に進行しています。1つはタイマー割り込み、1つはボタンを押してからの処理です。Windowsになって複数の処理がほぼ同時に動けるようになりました(ほぼとかいたのは、厳密に言うと短い時間でそれぞれの処理を少しずつ行っていて、人がみると同時に動いているように見えるからです)。

 抽選ボタンを押すと当選発表用パソコンに抽選中(指令「9」)を送ります。タイマー割り込みを使って約4秒の間(4秒という数値は体験的に出した数値です)ランダムで抽選データを抽出します。時間が来たときの最終データを当選発表用パソコンへ送り、処理を終了します。

(1)タイマー割り込み

 具体的なコードは、次のとおりです。

[リスト3]Form1.cs(tyuusenプロジェクト)
//*********************************************
//タイマー割り込み200msごとにこの処理が動く
//*********************************************
private void timer1_Tick(object sender, EventArgs e)
{
  int i,j;
  //抽選開始ボタンが押された時
  if (timer_sw == 1)
  {
      count++;
      if (count > 22)
      {
          //終了処理
          timer_sw = 9;
          //画像表示
          this.pictureBox1.Image = Image.FromFile(Application.StartupPath + "\\img\\" + "終了.bmp");
          return;
      }
      //0-99までのランダム。プログラムの開始時に
      //Random rnd = new Random();の宣言が必要
      i = rnd.Next(100);
      //0 特賞1% 99が出たとき
      //1 1等5% 98 97 96 95 94 が出たとき
      //2 2等10%80-89が出たとき
      //3 3等20%60-79が出たとき
      //8 4等64%その他
      atari_sw = 8;
      if (i == 99)
      {
          atari_sw = 0;
      }
      else
      {
          if (i <= 98 && i >= 94)
          {
              atari_sw = 1;
          }
          else
          {
              if (i >= 80 && i <= 89)
              {
                  atari_sw = 2;
              }
              else
              {
                  if (i >= 60 && i <= 79)
                  {
                      atari_sw = 3;
                  }
              }
          }
      }
      //画像表示 回転0.bmp から 回転3.bmpまでの画像を順次表示
      if (count == 22)
      {
          j = 0;
      }
      else
      {
          j = (count - 1) % 4;
      }
      this.pictureBox1.Image = Image.FromFile(Application.StartupPath + "\\img\\"+"回転"+j.ToString("0")+".bmp");
  }
  if (timer_sw == 0)
  {
      this.pictureBox1.Image = Image.FromFile(Application.StartupPath + "\\img\\" + "待機.bmp");
  }
   //終了画像表示を少し長く表示するため
  if (timer_sw == 8) timer_sw = 7;
  if (timer_sw == 7) timer_sw = 6;
  if (timer_sw == 6) timer_sw = 5;
  if (timer_sw == 5) timer_sw = 4;
  if (timer_sw == 4) timer_sw = 3;
  if (timer_sw == 3) timer_sw = 2;
  if (timer_sw == 2) timer_sw = 0;
}

 タイマー割り込みとは、「指定した時間(ms/ミリ秒)ごとにこの処理ルーチンを動かす」ということです。今回200msごとに処理をするよう設定しました。4400ms間(約4秒間強)乱数を出したいので、「4400ms/200ms=22」で22回この処理を動かすことになります。

 2つの処理の会話のため変数を作りました。

  • timer_sw
    通常は0をセットしておきます。抽選ボタンが押されたらボタン処理側で1にセットします。タイマー処理側は、22回まわって終わったら9にします。ボタン処理側は9を見て抽選結果を表示用パソコンに送ります。送ったあと、8をセットします。タイマー割り込み側では8→2までダウンさせ、送ったときの画像を保持させます。2になると次は0にして、タイマー割り込みは待機の画像になります。
  • atari_sw
    今回は8(四等)、3(三等)、2(二等)、1(一等)、0(特賞)にしています。
  • count
    抽選中のカウント。22回をカウントします

 タイマー割り込みの処理の内容説明をします。

 プログラム開始時はtimer_swは0になっています。

 もし、timer_sw=0なら「待機.bmp」を画面に表示します。抽選ボタンが押されるとtimer_sw=1になり、count変数も0になります。ここからcountをUPして22が来るまで、「回転0.bmp」から「回転3.bmp」までを順に表示します。このときに毎回、ランダム変数で抽選データを設定しておきます。

 今回は当たりを%で出すようにしました。特賞(1%) 一等(5%) 二等(10%) 三等(20%) 四等(64%)となります。0-99までのランダム変数(100と指定すると0-99までの数値を返してくれます)にしたので、99が出ると特賞、94から98(5種)が出ると一等、80から89(10種)が出ると二等、60から79(20種)が出ると三等、その他(64種)がでると四等としました。これをatari_swに設定します。

 22回終わると、timer_sw=9にして抽選ボタン処理に連絡します。抽選ボタン処理は結果を送ったあと8に設定するので、「終了.BMP」を表示したまま8→7→→→2とカウントダウンして、2になったとき0を設定します。

図5 表示画像とファイル名
図5 表示画像とファイル名

(2)抽選ボタンの処理

 抽選ボタンの処理は、次のとおりです。

送信
送信

 具体的なコードは、次のとおりです。

[リスト4]Form1.cs(tyuusenプロジェクト)
//抽選ボタン
private void button1_Click(object sender, EventArgs e)
{
  if (timer_sw == 1) return;          //二度押し防止
  //RS232C OPEN
  SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
  port.DtrEnable = true;
  port.RtsEnable = true;
  port.Open();

  //抽選開始を知らせる
  port.Write("9\n");           //開始=9

  timer_sw = 1;
  count = 0;
  while (true)
  {
      Application.DoEvents();
      if (timer_sw == 9) break;
  }
  //抽選データを パソコンへ送る
  port.Write(atari_sw.ToString() + "\n");
  timer_sw = 8;

  //RS232C クローズ
  port.Close();
}

 抽選ボタンの処理の内容説明をします。

 まず、抽選ボタンを押して抽選中にまた押されるとこまるので、変数timer_swが1の時は処理をしません。

 次にRS232Cのオープンです。オープンした後、9(抽選開始)を表示パソコンに知らせます。ここからはタイマー割り込みで変数timer_swが9になるまでwhile文で待ちます。このループの中に入れているApplication.DoEventsメソッドは、ループ処理中に画面終了(画面右上の[×]を押したとき)や他のソフトを動かすなどの処理があるときはWindowsに「同時に動かしてください」という指令になります。

 変数timer_swが9の状態でwhileループを抜けると、変数atari_swのデータ0,1,2,3,8を送り、RS232Cをクローズして終わります。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:C#で学ぶインターネット時代のシリアル通信

著者プロフィール

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

  • WINGSプロジェクト 横塚 利津子(ヨコツカ リツコ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5