0
0

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 1 year has passed since last update.

SpresenseでOpenPLCを動かしてみた

Last updated at Posted at 2023-01-13

マイコンボードでPLCのプログラムを動かすOpenPLCは色々なマイコンに対応していますが
標準ではSONY Spresenseには対応していません。
OpenPLCの公式のフォーラム
SpresenseでOpenPLCを使えるようにできないか という質問をしたら
Arduino IDEで開発できるマイコンであれば移植は簡単だという返事を頂きました

それで、他のマイコンの設定を参考に Spresense+Extension board に移植しました。
(とりあえず動くようになったレベルで細かな検証は行っていません。)

必要なハードウエアー
Spresense MAIN Board
Spresense Extension board

必要な開発環境
Arduino IDE + Spresense Arduino board package
(arduino IDEにSpresense環境のセットアップはこちらを参照してください)
OpenPLC Editer

移植の内容
※フォルダーは自分の環境で書いていますので、ご自身の環境に書き直してください。

  1. C:\Users\USER\OpenPLC_Editor\editor\arduino\src\halフォルダへの .hal ファイルの追加
  2. C:\Users\USER\OpenPLC_Editor\editor\arduino\src\halフォルダへの .cpp ファイルの追加
  3. C:\Users\USER\OpenPLC_Editor\editor\arduino\examples\Baremetal\hals.json ファイルにエントリを追加
  4. C:\Users\USER\OpenPLC_Editor\editor\arduino\builder.py の修正
    となります。

1. .hal ファイルの追加

spresense_extention.hal
# HAL configuration
# Format :
# Board type, FQBN
Spresene extention, SPRESENSE:spresense:spresense

2. .cpp ファイルの追加

入出力の設定(定義)は次のようにしています。
image.png

spresense_extention.cpp
#include <stdlib.h>
extern "C" {
#include "openplc.h"
}
#include "Arduino.h"

//OpenPLC HAL for Spresense Extension

/******************PINOUT CONFIGURATION*******************
Digital In: 0, 1, 2, 4, 7           (%IX0.0 - %IX0.4)
Digital Out: 8, 10, 11, 12, 13      (%QX0.0 - %QX0.4)
Analog In: A0, A1, A2, A3, A4, A5   (%IW0 - %IW5)
Analog Out: 3, 5, 6, 9              (%QW0 - %QW3)
**********************************************************/

//Define the number of inputs and outputs for this board (mapping for the Arduino Uno)
#define NUM_DISCRETE_INPUT          5
#define NUM_ANALOG_INPUT            6
#define NUM_DISCRETE_OUTPUT         5
#define NUM_ANALOG_OUTPUT           4

//Create the I/O pin masks
uint8_t pinMask_DIN[] = {0, 1, 2, 4, 7};
uint8_t pinMask_AIN[] = {A0, A1, A2, A3, A4, A5};
uint8_t pinMask_DOUT[] = {8, 10, 11, 12, 13};
uint8_t pinMask_AOUT[] = {3, 5, 6, 9};

void hardwareInit()
{
    for (int i = 0; i < NUM_DISCRETE_INPUT; i++)
    {
		uint8_t pin = pinMask_DIN[i];
        pinMode(pin, INPUT);
    }
    
    for (int i = 0; i < NUM_ANALOG_INPUT; i++)
    {
		uint8_t pin = pinMask_AIN[i];
        pinMode(pin, INPUT);
    }
    
    for (int i = 0; i < NUM_DISCRETE_OUTPUT; i++)
    {
		uint8_t pin = pinMask_DOUT[i];
        pinMode(pin, OUTPUT);
    }

    for (int i = 0; i < NUM_ANALOG_OUTPUT; i++)
    {
		uint8_t pin = pinMask_AOUT[i];
        pinMode(pin, OUTPUT);
    }
}

void updateInputBuffers()
{
    for (int i = 0; i < NUM_DISCRETE_INPUT; i++)
    {
		uint8_t pin = pinMask_DIN[i];
        if (bool_input[i/8][i%8] != NULL) 
            *bool_input[i/8][i%8] = digitalRead(pin);
    }
    
    for (int i = 0; i < NUM_ANALOG_INPUT; i++)
    {
		uint8_t pin = pinMask_AIN[i];
        if (int_input[i] != NULL)
            *int_input[i] = (analogRead(pin) * 64);
    }
}

void updateOutputBuffers()
{
    for (int i = 0; i < NUM_DISCRETE_OUTPUT; i++)
    {
		uint8_t pin = pinMask_DOUT[i];
        if (bool_output[i/8][i%8] != NULL) 
            digitalWrite(pin, *bool_output[i/8][i%8]);
    }
    for (int i = 0; i < NUM_ANALOG_OUTPUT; i++)
    {
		uint8_t pin = pinMask_AOUT[i];
        if (int_output[i] != NULL) 
            analogWrite(pin, (*int_output[i] / 256));
    }
}

3. hals.json ファイルにエントリを追加

,
    "Spresense Extention": {
        "platform": "SPRESENSE:spresense:spresense",
        "define": "BOARD_SPRESENSE",
        "source": "spresense_extention.cpp"
    } 

一番上の , は追加するエントリーの前の
} の 後ろに付けてください。

4. builder.py の修正

image.png
builder.pyファイルに188行~194行を追加します。

        
        // For Spresense
        compiler_logs += runCommand(cli_command +
                                    ' core install spresense:spresense')
        wx.CallAfter(txtCtrl.SetValue, compiler_logs)
        wx.CallAfter(scrollToEnd, txtCtrl)


以上の修正・追加を行った後に Spresense を接続して、接続されたCOMポートを確認してください。
OpenPLC Editer を起動して
ファイル → Tutorials Exampls → 2.Blink
を開きます。
ビットの設定の Blink_led のLocation に %QX0.4 を設定します。
image.png
Arduinoアイコンをクリックするとビルドが始り、成功すると、
Upload to Arduino Board ダイアログが表示されます。
image.png
ここで Board TypeSpresense Extention が追加されているはずです。
Board TypeSpresense Extentionを選択して、COM Port:を先ほど確認したポートに合わせます。

image.png
Uploadボタンを押すとコンパイルが始まります。
Compilation output: に
Restarting the board ...
reboot

Done!
と表示されると、コンパイルとアップロードが正常に終了しました。
image.png

これで Spresense で OpenPLCで作成したラダープログラムが走ります。

以上速足での説明となりましたが、SpresenseでOpenPLCが走ることが確認出来ました。
OpenPLCに関して深堀をしていないので不具合があるかもしれません、
お気付きの点はご指摘下さい。

またModbusに関してはテストしていませんので今後の課題とさせてください。

ソースコードはこちらで公開しています。
https://github.com/kaz19610303/OpenPLC_test_bench/tree/main/Spresense

なおArduino UNE用に作ったテストベンチボードをSpresense用に作り直していますので
コチラは出来上がり次第公開します。

自分的にはSpresenseの開発環境にOpenPLCが加わったのでちょっとうれしいです。
Spresense、OpenPLCどちらからも公式に認定されているわけではありませんが(笑)
いままで Youtube にOpenPLCに関してArduino UNOをベースにした動画をアップしていましたが、
これからはSpresenseベースの動画に切り替えたいと思っています。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?