2022年04月22日
カテゴリ:ラダー 電気回路
タグ:#b接点 #ノーマルクローズ #電気回路

b接点の使い方

ノーマルクローズ、ノーマルオープンという言葉を聞いたことはあるでしょうか?

リレー、リミットスイッチ、安全スイッチ等の接点回路には、

  • 普段は遮断状態で、スイッチを押すと通電する接点=ノーマルオープン(a接点)
  • 普段は通電していて、スイッチを押すと遮断される接点=ノーマルクローズ(b接点)

両方をもつ物があります。

「普段通電してて、スイッチを押したら切れる!?そんなの何に使うの?」と思う方も多いでしょう。

今回はそんな不思議なノーマルクローズ=b接点についてお話します。

ズバリ、一番多いケースは「非常停止スイッチ」です。
非常停止スイッチは、スイッチを押すことで動力を根元から遮断したり、各機器の安全回路に繋がっているものです。
機械が予期せぬ動きをした時には、非常停止スイッチを押して、確実に止めることが出来なくてはなりません。

ここで、経年劣化等で非常停止の配線が断線していると仮定しましょう。

ノーマルオープン(a接点)を使っている場合

もし非常停止スイッチにノーマルオープンのa接点を使用しているとどうなるでしょうか?
普段は通電していないので、機械は正常に動きます。
非常停止スイッチを押すと……断線しているせいで安全回路が通電しません。
これでは、いざ危険が迫ったときに機械を止めることができず、最悪死亡事故を招きます。

ノーマルクローズ(b接点)を使っている場合

この場合、通電状態でシステムが動くように設計します。
非常停止スイッチを押すと、電気が遮断され安全回路が働きます。
もし配線が断線している場合も、電気が遮断され安全回路が働きます。
つまり、回路に異常があったときに(人が気付けなくても)安全側に倒れてくれるため、安全が確保できるというわけです。

その他にも、工夫次第でたくさんの使い方ができますが、詳細はまた別回にて。

ノーマルクローズ、ノーマルオープンの性質を知っていると、
安全回路をはじめ、様々なケースで適切な回路を組むことができます。
ぜひ性質を正しく理解し、使いこなしましょう!

2022年04月14日
カテゴリ:C#
タグ:#singleton #シングルトン #デザインパターン

C#でシングルトンクラスの作り方

比較的大規模なシステムや、通信を行うシステムを作っていると
システム全体でこの機能を持つインスタンスを1つしか作りたくない
と思うケースに出会います。

たとえば

  • システム全体で他機器との通信状態を一元監視しているクラス
  • ロガーなど、システム全体で使う&ファイルアクセスなのであちこちで競合したら困る

のようなケースです。

昔ながらのC言語ではセマフォといって、プログラム間で資源の排他制御や同期を行うような仕組みが使われたりするのですが(セマフォに関してはまた後日解説します)
C#ではシングルトン(singleton)パターンというデザインパターンを使ってスマートに実現できます。
それにしても変な名前ですよね、シングルトン。

今回はそんなシングルトンパターンについて解説していきます。

それでは今回もまず完成形を掲載しましょう。

完成形の実例

public class SingletonClass
{
    //シングルトンクラスのインスタンス生成
    private static SingletonClass _instance = new SingletonClass();

    //コンストラクタ
    private SingletonClass()
    {
        //初期化処理
    }

    //外部からのインスタンス取得関数
    public static SingletonClass GetInstance()
    {
        //既に生成されているインスタンスへの参照を返す
        return _instance;
    }

    //外部から使いたい機能
    public void func()
    {
        //外部から使いたい機能の内容
    }
}

↑シングルトンパターンを実装したクラス

public class OtherClass
{
    //唯一のインスタンスへの参照をGetする
    SingletonClass singleInstance = SingletonClass.GetInstance();

    //SingletonClassの機能を使う
    singleInstance.func();
}

↑シングルトンクラスの機能を使う外部クラス

なんと、ポイントはたった2つ!

  • コンストラクタのスコープをprivateにする
  • インスタンスはクラス内でprivateとして生成し、外部からはGetInstance()メソッドで参照する

たったこれだけで実現できてしまうんですね!

コンストラクタをprivateにすることで、外部からのnew生成を禁止することができます。
同じくprivateなインスタンスはクラス内でのみ唯一生成されます。
あとは任意のクラスでGetInstance()メソッドを実行することで、上記で唯一生成されたインスタンスへの参照を取得することができます。

普段プログラミングしていてても「何に使うの……?」といまいちピンと来ないかもしれませんが、この記事の冒頭のように通信監視クラスやロガークラスを実装しようとすると、途端に意識しないといけなくなるのがインスタンスのこと。

シングルトンパターンを使いこなして、1段階上のレベルのエンジニアを目指しましょう!

2022年04月12日
カテゴリ:教えて三宅先生
タグ:#Linux #教えて三宅先生

教えて三宅先生「Linux ってなんぞや?」

三宅制御技術が業務提携している株式会社ブリッジ・ソリューションとの連携企画のひとつ
「教えて三宅先生」のコーナー。

今回は「Linux ってなんぞや?」というお話です。

ブリッジ・ソリューションのFacebook投稿へのリンクを埋め込んでおきます。

教えて三宅先生のコーナーでは、技術者の方だけでなく、プログラミング初心者や学生さん達がIT技術の入り口として楽しめるような動画コンテンツを公開しております。
知りたいこと、質問したいことがあれば、気軽にコメント頂ければ幸いです。

ではまた次回!

2022年04月08日
カテゴリ:教えて三宅先生
タグ:#Raspberry Pi #ラズパイ #ラズベリーパイ #教えて三宅先生

教えて三宅先生「Raspberry Pi ってなんぞや?」

三宅制御技術が業務提携している株式会社ブリッジ・ソリューションとの連携企画のひとつ
「教えて三宅先生」のコーナー。

今回は「Raspberry Pi ってなんぞや?」というお話です。

ブリッジ・ソリューションのFacebook投稿へのリンクを埋め込んでおきます。

教えて三宅先生のコーナーでは、技術者の方だけでなく、プログラミング初心者や学生さん達がIT技術の入り口として楽しめるような動画コンテンツを公開しております。
知りたいこと、質問したいことがあれば、気軽にコメント頂ければ幸いです。

ではまた次回!

2022年04月06日
カテゴリ:C#
タグ:#C#でInvokeを使う方法 #C#でサブスレッドからフォームを操作する方法 #C#で長押しボタンを作る方法

C#で長押しボタンを作る方法

産業系・制御系システムを構築する時は、

  • 間違えてワンクリックしただけで機械が動いてしまうと危ない
  • かといって毎回警告のポップアップを出すのは煩わしすぎる

など、「ボタンの長押し」をトリガーにしたいことがよくあります。

三菱製GOTタッチパネル等には最初から長押し機能が入っていますが、昨今はWindowsフォームアプリケーションからロボットを制御したいというケースもよくあります。
ということで、Windowsフォームアプリケーションで長押しボタンを作る方法を解説します。

仕様としては

  • ボタンを1秒間長押ししたら、機能を実行する
  • 1秒以上押し続けても、2回目は実行されない
  • 1秒未満でボタンを離せば、何も起こらない

とします。

サンプルコード

まず先に全体のサンプルコードを記載して、後から個別に解説します。

public partial class FrmMain : Form
{
    //ボタン長押し用タイマ
    private SystemThreading.Timer timer = null;
    //ボタン長押し中フラグ
    private bool flgPressing = false;

    public frmMain()
    {
        InitializeComponent();

        //ボタン長押し用タイマのコールバック登録
        timer = new SystemThreading.Timer(new TimerCallback(Callback_BtnSample), null, Timeout.Infinite, Timeout.Infinite);

        //コールバック関数
        public void Callback_BtnSample(Object obj)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(BtnSample_LongClick));
            }
            else
            {
                BtnSample_LongClick();
            }
        }

        //長押し成立時に実行したい機能
        private void BtnSample_LongClick()
        {
            //任意の処理
        }

        //マウスが押され始めた時に起こるイベント
        private void BtnSample_MouseDown(object sender, MouseEventArgs e)
        {
            //一秒後に一度だけ発動
            timer.Change(1000, Timeout.Infinite);
            flgPressing = true;
        }
        //マウスが離された時に起こるイベント
        private void BtnSample_MouseUp(object sender, MouseEventArgs e)
        {
            //ボタンを離した時にタイマ無効化
            timer.Change(Timeout.Infinite, Timeout.Infinite);
            flgPressing = false;
        }
    }
}

次の項で、個別に解説していきます。

タイマとフラグの宣言

長押しを実現するために、Threading.Timerクラスを使用します。
また、ボタンが押されている状態を表すのにフラグも作っておきます。
「押している間ボタンの色を変える」などの制御がやりやすくなりますね。

//ボタン長押し用タイマ
private SystemThreading.Timer timer = null;
//ボタン長押し中フラグ
private bool flgPressing = false;

タイマのコールバック登録

タイマのコールバック関数を登録します。
ここでポイントとなるのが、第3引数dueTimeと第4引数PeriodをTimeout.Infiniteとしていること。
こうすることで、タイマは一旦、何も起動しない状態として設定されます。

//ボタン長押し用タイマのコールバック登録
timer = new SystemThreading.Timer(new TimerCallback(Callback_BtnSample),null,Timeout.Infinite,Timeout.Infinite);

↓Timer関数のパラメータ仕様は以下URLを参照

https://docs.microsoft.com/ja-jp/dotnet/api/system.threading.timer.-ctor?view=net-6.0#system-threading-timer-ctor(system-threading-timercallback-system-object-system-int32-system-int32)

サブスレッドから扱うための「Invoke」

コールバック関数を見ると、わざわざもうワンクッション置いていることがわかります。
こんなことをしなくても正常に動きそうですが、実際に動かしてみると例外が発生して動かなくなります。
これは「異なるスレッドのオブジェクトを操作しようとしている」から。

Threading.Timerのイベント処理が動作するのはサブスレッド。
フォーム上のボタン等はメインスレッドで生成されています。

このようにスレッドを跨ぐ操作を行いたいときには、特別な手続きが必要です。
それがinvokeです。

  • InvokeRequiredを使い、現在サブスレッドから処理が動いているか(Invokeの必要があるかどうか)を判断する
  • 必要ならばInvoke()関数を使って、”実行したい機能”の関数ポインタを渡す

という流れになっています。

//コールバック関数
public void Callback_BtnSample(Object obj)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new Action(BtnSample_LongClick));
    }
    else
    {
        BtnSample_LongClick();
    }
}

//長押し成立時に実行したい機能
private void BtnSample_LongClick()
{
    //任意の処理
}

MouseDown/MouseUpイベントの登録

最後にマウスのイベントを作成します。
MouseDown時にタイマのdueTimeを1000ミリ秒に設定することで、ボタンが押されてから1秒後にイベントが発火します。
MouseUp時にタイマのdueTimeをInfiniteに戻すことで、1秒未満でボタンを離せば何も起こらないようにできます。
periodはずっとInfiniteなので、押しっぱなしでも何度もイベントが発火することはありません。

※FormのDesigner.csでイベントハンドラの追加をするのを忘れずに!

//マウスが押され始めた時に起こるイベント
private void BtnSample_MouseDown(object sender, MouseEventArgs e)
{
    //一秒後に一度だけ発動
    timerBtnSample.Change(1000, Timeout.Infinite);
    PressingBtnSample = true;
}
       
//マウスが離された時に起こるイベント
private void BtnSample_MouseUp(object sender, MouseEventArgs e)
{
    //ボタンを離した時にタイマ無効化
    timerBtnSample.Change(Timeout.Infinite, Timeout.Infinite);
    PressingBtnSample = false;
}

以上で

  • ボタンを1秒間長押ししたら、機能を実行する
  • 1秒以上押し続けても、2回目は実行されない
  • 1秒未満でボタンを離せば、何も起こらない

という仕様の長押しボタンの完成です!

2022年04月04日
カテゴリ:batファイル
タグ:#batファイル #robocopy #シェルスクリプト

バックアップしたファイルの一括リストア.batの作り方

前回、更新されたファイルだけを一括バックアップするbatファイルの作り方について解説しました。
今回の記事はその続きになります。
前回と合わせてお読みください。

robocopyコマンドの第一引数と第二引数を入れ替えることで、バックアップの逆の操作(リストアと呼びます)も自動化できます。

完成形の実例

スクリプトの全文です。
前回と同様のフォルダに「restore.bat」という名前で上記の内容を記入すればOKです。
各コマンドの解説や、実行方法については、前回の記事をご参照下さい。

batファイル実行時にリストア元(バックアップしてある)ドライブを指定し、それを現在のフォルダにコピーします。このとき、

  • 所定のフォルダの中身をすべて確認し
  • 更新されていなければスキップする
  • 更新されていれば上書きコピーする

という動作をします。

この2つのスクリプトを組み合わせることで、簡単にバックアップとリストアが行えます。
これで、外部ディスクへの単純なバックアップやミラーリング、2台のPCを用いた同期もバッチリですね。

2022年04月01日
カテゴリ:batファイル
タグ:#batファイル #robocopy #シェルスクリプト

更新ファイルだけを上書きする一括バックアップ.batの作り方

PCを使ったお仕事では、バックアップが必要不可欠です。
PCが突然動かなくなるかもしれませんし、メインPCとサブPCで同期したいことも多々あります。

ファイルのバックアップ方法は

  • Git等のバージョン管理システムを使う
  • GoogleDrive等のクラウドストレージサービスを使う
  • 外部ストレージにファイルをコピーする

など様々ですが、今回は一番シンプルかつ確実な、外部ストレージにファイルをコピーする方式について解説します。

さらに、コピーの方法も

  • ひとつひとつ更新されたファイルを確認しコピーしていく→手間がかかりすぎる
  • 保存対象の親フォルダを丸ごと全部コピーする→コピー量が膨大になり、毎回長時間を要する

などの課題がありますが、これら全てを解決する方法が
「robocopyコマンドを用いたbat(バッチ)ファイルを使う」方法です。

完成形の実例

今回もさっそく完成形を掲載して解説します。

まずはバックアップを取りたいファイル群の親フォルダと同じ階層で、右クリック→新規作成→テキストドキュメントを選択し、テキストファイルを新規作成します。

作成したファイルの名前を「backup.bat」に変更します。

「backup.bat」を任意のテキストエディタ(メモ帳でも可)で開き、下記のように記入します。

ソースコードのまま掲載が出来なかったので、キャプチャ画像で掲載します

これで、batファイルをコマンドプロンプトから実行するだけで、

  • 所定のフォルダの中身をすべて確認し
  • 更新されていなければスキップする
  • 更新されていれば上書きコピーする

という、かゆいところに手が届く機能を自動でやってくれます。

実行方法

batファイルと保存対象のフォルダの場所をエクスプローラで開きます。

フォルダのパスが表示されているテキストボックスをクリックし、「cmd」と入力してエンターキーを押します。

図のような黒い画面「コマンドプロンプト」が起動しますので、そこで「backup.bat (保存先ドライブのアルファベット)」と入力し、エンターキーを押します。(例ではFドライブ)

これで自動バックアップが実行されます。
コピー量が多い場合、しばらく画面が何も更新されず止まっているように見えますが、心配ありません。
数分で、もう一度コマンド入力待ちの行が表示されれば、バックアップ処理は完了です。

事項から順番に解説をしていきましょう。

@echo off

これは実行時のログを画面に表示させないようにするコマンドです。

「%1」と「NOT EXIST」

%(数字)は、コマンド実行時の引数を表します。
%1=第一引数、%2=第二引数という具合です。
backup.batの後ろに半角スペースを空けて入力したテキストを引数と言い、今回であれば保存先ドライブのアルファベットです。
つまりここでは、batファイル名の後ろにきちんと保存先ドライブを指定しているかを確認しているわけです。
もし引数が空であれば:PARAM_ERRORラベルに飛び、警告文を表示して動作終了します。
指定されたドライブが存在しない場合は:NOT_FOUND_ERRORラベルに飛び、警告文を表示して動作終了します。

「robocopy」コマンド

今回の主役になるコマンドです。
このrobocopyコマンドは、変更のあったファイルを判断して上書きファイルを自動選別してくれるだけでなく、
「保存元/先にだけ存在するファイルは消す」等のオプションも存在し、単純なファイルの保存だけでなく、完全なミラーコピー状態を保持するような用途にも使えます。

第一引数=保存元フォルダ
第二引数=保存先フォルダ
第三引数以降はオプションになります。

オプションを軽く説明すると

  • /E=保存元/保存先のどちらかにしか無いファイルでも、削除しない
  • /r:=失敗した時のリトライ回数(例では3回)
  • /log+:=実行結果のログ出力先を指定
  • /DCOPY:DAT=属性やタイムスタンプ等のオプション情報を維持する

robocopyコマンド単体の、オプションを含む詳細な解説は、すでに詳しく解説されているサイトを参考にして下さい。
念のため参考URLを貼っておきます。

https://tooljp.com/windows/chigai/html/robocopy/robocopy-mir-e-option-chigai.html

https://n-archives.net/software/robosync/articles/dcopy-dat/

このように、手作業では膨大な手間がかかってしまうような作業も、意外と簡単に自動化することができます。

また自前でプログラムを作るよりも、このようにすでに存在するコマンドを使う事で、思わぬ不具合によるデータ損失も防ぐことができます。

単純作業は積極的に自動化して、本業に集中しましょう!

2022年03月30日
カテゴリ:教えて三宅先生
タグ:#教えて三宅先生

「教えて三宅先生」

三宅制御技術は、次世代SIerの育成事業にも力を入れています。
その1つが、業務提携しているSIer、株式会社ブリッジ・ソリューションでの「教えて三宅先生」のコーナー。

技術者の方だけでなく、プログラミング初心者や学生さん達がIT技術の入り口として楽しめるような動画コンテンツを公開しております。

現在はブリッジ・ソリューション社のInstagramアカウントのみでの公開となっておりますが、近日中に三宅制御技術の各種SNSアカウントでも正式公開し、本ブログでの1コンテンツとして開設予定です。

皆さまぜひお楽しみにお待ちください。

下記にサンプルとしてブリッジ・ソリューション社のInstagramへのリンクを貼っておきます。

https://www.instagram.com/stories/highlights/17851406216733328/

2022年03月28日
カテゴリ:ラダー
タグ:#運転ステップ方式

ラダーの「運転ステップ方式」

PLCを制御するための「ラダー言語」の入門講座。
今回は「運転ステップ方式」の解説をします。(※弊社の造語です)

運転ボタンを一回押したら、あとは全自動で複雑な工程をシーケンシャルにこなしていく……。
自動機システムに一番求められることはコレでしょう。

工程管理には、

  • タイマで制御する
  • 工程の順番は意識せずセンサやリミットの状態のみで判断する
  • 自己保持回路をつかう

など、色々な方法が考えられます。

その中でも

  • 自由度が高く、複雑な工程も組めて
  • いたずらに自己保持リレーを増やすことなく
  • 構造もシンプルに仕上げることができる

そんな方法が弊社の推奨する「運転ステップ方式」です。

百聞は一見に如かず。今回も完成形を掲載します。

完成形の実例

それではポイントを解説していきます。

ポイント1:運転開始はパルスと自己保持を使う

運転ボタンの立ち上がりパルスを使って、1スキャンだけ「運転開始指令」をONにします。
運転開始指令がONになったら「運転中」をONにして自己保持を取り、運転中ステータスを継続させます。
最後に全行程終了した時に「運転完了」によって自己保持を切ることで、運転中を解除できます。

※自己保持回路の解説はこちらの記事で解説しています。

ポイント2:運転ステップ=工程番号

工程を”運転ステップ”と呼ばれる工程番号で管理するというのがポイントです。

  • 運転ボタンを押した時に0に初期化して運転開始
  • 処理1が終われば運転ステップを10にする
  • 処理2が終われば運転ステップを20にする

というように順番に運転ステップをインクリメントしていき、最後まで処理が終われば運転完了信号を出して、運転中ステータスごと落とします。

ここでステップを10ずつ増加させているのは、開発中や運用後の仕様変更によって「既存の工程の間に処理を挟みたい!」という要望が出た時に、手間なく工程を追加できるための一工夫です。

この「運転ステップ方式」を使えば、自己保持用に内部リレーをいくつも消費する事なく、データレジスタ1個で管理できます。
さらにラダーの行数を減らし構造も単純化できるので、可読性の高いメンテナンスしやすいラダーに仕上がります

みんなで良いラダーを書いて、ラダーマスターになろう!

2022年03月24日
カテゴリ:ラダー
タグ:#オルタネイト回路の書き方

オルタネイト回路の書き方

PLCを制御するための「ラダー言語」の入門講座。
今回は「オルタネイト回路」の解説をします。

  • スイッチを一回押したら、モータが動き出す
  • もう一度押したら止まる

こういう事をしたいケースは多々あります。

トグルスイッチやオルタネイトスイッチを使えば解決する場合もありますが、よく採用されるモーメンタリスイッチでは、一工夫する必要があります。
そんな回路を「オルタネイト回路」と呼びます。

今回もさっそく完成形を掲載しましょう。

完成形の実例

オルタネイト回路の実現にはいくつかの実装方法がありますが、パルス命令が使えるCPUやソフトの場合、これが一番シンプルです。

  • スイッチ(X0)を押すと反応する1パルス命令で、自己保持用リレー(M1)をONにする
  • 自己保持リレー(M1)がONの時にスイッチを押すと、自己保持を切る

こうすることで、モーメンタリスイッチ1つで、押すたびにON/OFFを繰り返す回路の完成です。
あとは自己保持リレーM1をトリガーに、コンベアやランプ等の出力をONにすればOKです。

みんなで良いラダーを書いて、ラダーマスターになろう!