いつもPCとマイコンを繋げてシリアル通信で値を取ることしかしていませんでしたが、値を送って何かを動かすことを試してみました。

 

動かしている様子はこちら。

 

 

シンプルに下記2つの構成で実験しました。

  • Arduino
  • サーボモーター(SG90)

この2つは3本の線で接続します。

配線図は下記のようになります。

 

 

信号線は自由に変更しても大丈夫です。

見づらいですが、念のため画像でも残しておきます。

 

 

プログラムは、Arduino側のプログラムと、PC側のプログラムの2つ用意します。

Arduino側は下記のようにしました。

#include <Servo.h>

 

Servo servo1;

String data;

 

void setup()

{

    Serial.begin(9600);

    servo1.attach(9); //D9

    servo1.write(90); //初期値は90°

}

 

void loop()

{

    if(Serial.available())

    {

        data = Serial.readStringUntil('\n');

 

        if(data.startsWith("ANGLE:"))

        {

            String angleString = data.substring(6);

            int angle = angleString.toInt();

 

            if(angle < 0)

                angle = 0;

 

            if(angle > 180)

                angle = 180;

 

            servo1.write(angle);

        }

    }

}

 

PC側は、Pythonを使ってプログラムを作成しました。

tkinterpyserialの2つのライブラリを事前にインストールしておきます。

pip install pyserial

 

Pythonのプログラムは下記のようにしました。

 

import tkinter as tk

import serial

 

#----------------------------

# Arduinoとの接続

#----------------------------

 

ser = serial.Serial("COM7",9600)

 

#----------------------------

# スライダーを動かした場合

#----------------------------

 

def slider_changed(value):

 

    angle = int(float(value))

 

    entry.delete(0,tk.END)

    entry.insert(0,str(angle))

 

    value_label.config(

        text=f"現在値:{angle}°"

    )


 

#----------------------------

# 数値入力を反映

#----------------------------

 

def set_value():

 

    try:

        angle = int(entry.get())

 

        if angle < 0:

            angle = 0

 

        if angle > 180:

            angle = 180

 

        slider.set(angle)

 

        value_label.config(

            text=f"現在値:{angle}°"

        )

 

    except:

        pass

 

#----------------------------

# Arduinoへ送信

#----------------------------

 

def send_value():

    try:

        angle = int(entry.get())

 

        if angle < 0:

            angle = 0

 

        if angle > 180:

            angle = 180

 

        command = f"ANGLE:{angle}\n"

 

        ser.write(

            command.encode()

        )

 

        print("送信 :",command)


    except:

        pass

 

#----------------------------

# GUI作成

#----------------------------

 

root = tk.Tk()

 

root.title("Servo Controller")

root.geometry("400x250")


 

#----------------------------

# 数値入力

#----------------------------

 

label1 = tk.Label(

            root,

            text="角度入力(0~180)"

         )

 

label1.pack()

 

entry = tk.Entry(

            root,

            width=10

         )

 

entry.insert(0,"90")

entry.pack()


#----------------------------

# 値を反映

#----------------------------

 

set_button = tk.Button(

                root,

                text="値を反映",

                command=set_value

             )

 

set_button.pack(pady=5)

 

#----------------------------

# スライダー

#----------------------------

 

slider = tk.Scale(

            root,

            from_=0,

            to=180,

            orient="horizontal",

            length=300,

            command=slider_changed

         )

 

slider.set(90)

slider.pack()


 

#----------------------------

# 現在値の表示

#----------------------------

 

value_label = tk.Label(

                    root,

                    text="現在値:90°"

                 )

 

value_label.pack(pady=5)


 

#----------------------------

# Arduinoへ送信

#----------------------------

 

send_button = tk.Button(

                    root,

                    text="送信",

                    width=15,

                    height=2,

                    command=send_value

                 )

 

send_button.pack(pady=10)


 

#----------------------------

 

root.mainloop()

 

プログラムはChatGPTに作ってもらいました。

COMポートの割り当ては適切なものに修正してください。

 

これを拡張していけば、もっと色々と複雑なものが操作できそうです。