10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Groveと産業機器をつないでみよう

Last updated at Posted at 2020-12-21

#1.はじめに

工場などで使われる産業機器を、GROVEコネクタに接続して、制御できるようにしてみました。

昨年のアドベントカレンダーにも同様の記事を投稿していましたが、Grove対応版が結局間に合わず、1年経ってしまいました・・・今回改めて作り直しましたので、紹介します。

#2.ハードウェア

SeeedさんのGroveシリーズには、接続インターフェースのラインナップがありませんので、自作してみました。
外観はこんな感じです。(左:出力用、右:入力用)
image.png
Grove Base HAT経由でRaspberryPiに接続します。
image.png

##(1)考え方

GROVEの制御電圧はDC3.3VあるいはDC5Vです。
一方、産業機器の多くはDC24Vで動作しますので、GROVEコネクタとは直結できません。
「電圧レベルの変換」と呼ばれる工夫が必要です。

今回のユニットでは、フォトカプラを使っています。
TLP627TLP222は、定格電流が100mA以上流せるので、ランプやリレーは直結して駆動ができます。

NOTE
リレーなどコイルを使用しているものをトランジスタ・FETなどに接続する際は、コイルOFF時の逆起電力による破損防止のため「還流ダイオード」1の接続が必要です。
市販のリレーには、始めからダイオードが内蔵されているものもありますので、購入する際に予め型式を指定しておきましょう。

例)

##(2)基板を作ってみる

KiCADを使って基板を設計してみました。
ガーバデータや回路図含め、データ一式はGitHubに公開しています。

READMEで紹介しているとおり、基板裏面のジャンパーを切り替えることで、シンク(NPN)/ソース(PNP)駆動を切り替えることができますので、国内外問わず使用可能です。

基板の製造については、一例としてSeeedさんが運営の「Fusion PCB」での発注の例を、下記にまとめていますのでご参考ください。

#3.ソフトウェア

Pythonは多くの例があるので、ここでは敢えてそれ以外の言語で操作してみました。

言語 制御ライブラリ
Go GOBOT
Rust rppal
Elixir Elixir Circuits

##配線の接続

下記の様に繋いでいます。

HATのコネクタ GPIO(BCM番号) 接続先
D5 5 押しボタン
D16 16 ランプ

##(1)Golang

入出力制御のライブラリ gobotを使います。
インストールは上記リンク先の「How to Install」か、別記事で紹介しているものを参考願います。

ソースコード

押しボタンを押すと、ランプが点灯します。

ピン番号指定の注意!!

gobotでの入出力ピン番号指定は**物理ピン番号(Physical)**です。
BCM番号ではありませんのでご注意ください。

led.go
package main

import (
	"fmt"

	"gobot.io/x/gobot"
	"gobot.io/x/gobot/drivers/gpio"
	"gobot.io/x/gobot/platforms/raspi"
)

// GPIOを物理ピン番号で指定
const GPIO_LED = "36" //BCM16→Pin36
const GPIO_BTN = "29" //BCM5 →Pin29

func main() {
	r := raspi.NewAdaptor()
	//定義
	led := gpio.NewLedDriver(r, GPIO_LED)
	button := gpio.NewButtonDriver(r, GPIO_BTN)

	//イベントを定義
	work := func() {

		//ボタンがONの時
		button.On(gpio.ButtonPush, func(data interface{}) {
			fmt.Println("button pressed")
			//点灯
			led.On()
		})

		//ボタンがOFFの時
		button.On(gpio.ButtonRelease, func(data interface{}) {
			fmt.Println("button released")
			//消灯
			led.Off()
		})
	}

	//スタート
	robot := gobot.NewRobot("buttonBot",
		[]gobot.Connection{r},
		[]gobot.Device{button, led},
		work,
	)
	robot.Start()
}

実行

$ go run led.go
2020/12/20 11:02:18 Initializing connections...
2020/12/20 11:02:18 Initializing connection RaspberryPi-2B0CDE57 ...
2020/12/20 11:02:18 Initializing devices...
2020/12/20 11:02:18 Initializing device Button-649D051A ...
2020/12/20 11:02:18 Initializing device LED-7FCF738D ...
2020/12/20 11:02:18 Robot buttonBot initialized.
2020/12/20 11:02:18 Starting Robot buttonBot ...
2020/12/20 11:02:18 Starting connections...
2020/12/20 11:02:18 Starting connection RaspberryPi-2B0CDE57...
2020/12/20 11:02:18 Starting devices...
2020/12/20 11:02:18 Starting device Button-649D051A on pin 29...
2020/12/20 11:02:18 Starting device LED-7FCF738D on pin 36...
2020/12/20 11:02:18 Starting work...
button pressed
button released
button pressed
button released
button pressed
button released

[Ctrl-C]で終了

##(2)Rust

RaspberryPiの入出力制御のクレート rppalを使います。

ソースコード

はじめはランプが0.5sec間隔で点滅している状態になっていて、押しボタンを押すと、ランプの点滅速度が速くなります。

cargo.toml(抜粋)
・・・(省略)
[dependencies]
rppal = "0.11.3"
src/main.rs
use std::error::Error;
use std::thread;
use std::time::Duration;
use rppal::gpio::Gpio;

// GPIOをBCM番号で指定
const GPIO_LED: u8 = 16;
const GPIO_BTN: u8 = 5;

//メイン
fn main() -> Result<(), Box<dyn Error>> {
    // GPIOの設定・出力
    let mut pin_led = Gpio::new()?.get(GPIO_LED)?.into_output();
    // GPIOの設定・入力
    let pin_btn = Gpio::new()?.get(GPIO_BTN)?.into_input();

    //無限ループ
    loop {
        if pin_btn.is_low() {
            //ボタンを離しているときは0.5sec間隔で点滅
            pin_led.toggle();
            thread::sleep(Duration::from_millis(500));
        } else {
            //ボタンを押しているときは0.1sec間隔で点滅
            pin_led.toggle();
            thread::sleep(Duration::from_millis(100));    
        }       
    }
}

実行

$ cargo run
   Compiling led v0.1.0 (/home/pi/gitwork/rust/led)
    Finished dev [unoptimized + debuginfo] target(s) in 1.41s
     Running `target/debug/led`

[Ctrl-C]で終了

##(3)Elixir

入出力制御のライブラリ Elixir Circuitsを使います。

ソースコード

押しボタンを押すと、ランプが1秒だけ点灯してから消灯します。

buttonlamp.ex
defmodule ButtonLamp do
  @moduledoc """
  Documentation for `Button`.
  WebAPI送信とボタン・LEDの連携
  ## Examples
  """

  # 関連するライブラリを読み込み
  use GenServer
  require Logger

  alias Circuits.GPIO
 
  # 定数
  # 押しボタン接続のBCM番号
  @button 5
  # ランプ接続のBCM番号
  @led 16

  @doc """
  GenServer起動
  """
  def start_link() do
    GenServer.start_link(__MODULE__, [])
  end

  @doc """
  初期化の処理
  """
  def init(_) do
    # GPIO入力の初期化(押しボタン用)
    {:ok, button} = GPIO.open(@button, :input, pull_mode: :pullup)
    # 押しボタン入力の割込を許可(押しボタンを押すとhandle_info関数を呼び出し)
    GPIO.set_interrupts(button, :rising)

    # GPIO出力の初期化(ランプ用)
    {:ok, led} = GPIO.open(@led, :output)

    {:ok, %{button: button, led: led}}
  end

  @doc """
  押しボタン入力の割込の処理
  """
  def handle_info({:circuits_gpio, @button, _timestamp, value}, state) do
    IO.puts(" Button On")
    # ランプを点灯
    GPIO.write(state.led, 1)
    # 待機(単位ms)
    Process.sleep(1000)
    # ランプを消灯
    GPIO.write(state.led, 0)

    {:noreply, state}
  end
end

mix.exsには、circuits_gpioを追記します。

mix.exs(抜粋)
・・・(省略)・・・
  defp deps do
    [
      {:dep_from_hexpm, "~> 0.3.0"},    #ここのコメントを外す
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
      {:circuits_gpio, "~> 0.4"}        #ここを追加
    ]
  end
・・・(省略)・・・

実行

$ mix deps.get
$ iex -S mix
・・・
iex(1)>  ButtonLamp.start_link
{:ok, #PID<0.289.0>}
 Button On
 Button On
 ・・・

[Ctrl-C]二回押し、あるいは[Ctrl-]で終了。

#4.おわりに

Grove Base HAT経由でRaspberryPiに接続が可能な、産業機器用制御インターフェースを作ってみました。
PLCに取って代わる・・・まではいかないにしても、IT系の方々が気軽にFACTORY系の機器を作れるようになることを願って製作しました。
今後、少しずつ作例を増やしていきますので、お待ちくださいね~

  1. 参考資料例 http://sudoteck.way-nifty.com/blog/2010/07/post-c24f.html

10
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?