2022年前期活動


ページ内リンク

1.産業用ロボット監視用センサ制御のRaspberry Pi化
2.オープンキャンパス用ミニゲームのLED部分作成

1.産業用ロボット監視用センサ制御のRaspberry Pi化

産業用ロボットの作業、状態監視のため、複数種類のセンサを統合しサーバにアップロードするシステムの仕様変更を行った。
昨年はESP-WROOM-02開発ボードを使用してセンサのデータをサーバに直でアップロードする方法を取った。
しかし、実際に設置を行い実験したところ通信速度の問題により安定してデータをアップロードすることが出来ない不具合が生じた。
そこで、本研究ではRaspberry Piを使用することでセンサデータをCSV化し、アップロードに失敗した際にデータを保存するような形を取る事にした。

使用物

結線

現在はブレッドボード上に実装しているが、後に基板上に実装する予定である。

(画像クリックで拡大)

プログラム

プログラムはセンサのデータを受け取りCSVに書き込む用とそのCSVをサーバにアップする用の二つに分けて記述した。

・センサ受け取り&CSV化

以下はセンサ情報を受け取り、CSVに書き込むプログラムである。
一分ごとに新しくCSVを作成し、データを保存するようにしている。


import Adafruit_DHT as DHT
import RPi.GPIO as GPIO
import spidev
import time
import csv
import datetime

#robot
robotNum = 1

#pin
trigPin = 27
echoPin = 17
spwPin = 24
dhtPin = 23

#ambient temp

#time
echoLoop = 0
echoStart = 0
echoStop = 0
echo = 0

#set GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

GPIO.setup(trigPin,GPIO.OUT)
GPIO.setup(echoPin,GPIO.IN)

GPIO.setup(spwPin,GPIO.IN,pull_up_down=GPIO.PUD_UP)

#SPI init
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 100000
spi.mode = 3

s_dat = [0x00, 0x00]
x_dat = [0x00, 0x00, 0x00]
y_dat = [0x00, 0x00, 0x00]
z_dat = [0x00, 0x00, 0x00]

#ADXL init
s_dat[0] = 0x2C
s_dat[1] = 0x0B
readByteArry = spi.xfer2(s_dat)

s_dat[0] = 0x31
s_dat[1] = 0x09
readByteArry = spi.xfer2(s_dat)

s_dat[0] = 0x2D
s_dat[1] = 0x08
readByteArry = spi.xfer2(s_dat)

#SPW311
findFlag = 0
csvCount = 0

#DHT22
dhtName = DHT.DHT22

temperature = 20
humidity = 0
dhtTime = -30
dhtTmp = 0

#csv data name
csvX = 0
csvY = 0
csvZ = 0
csvEcho = 0
csvSpw = 0
csvTemp = 0
csvHumi = 0

#csv
dt = ""
csvDt = ""
fileDt = ""
fileDtStop = ""
fileTime = 0
fileTmp = -60

def ADXLread():

    x_dat[0] = 0x32
    x_dat[0] |= 0x80
    x_dat[0] |= 0x40

    y_dat[0] = 0x34
    y_dat[0] |= 0x80
    y_dat[0] |= 0x40

    z_dat[0] = 0x36
    z_dat[0] |= 0x80
    z_dat[0] |= 0x40

    #data read
    readByteArry = spi.xfer2(x_dat)
    readByteArry = spi.xfer2(y_dat)
    readByteArry = spi.xfer2(z_dat)

    #data change
    out_x = x_dat[2] << 8 | x_dat[1]
    out_y = y_dat[2] << 8 | y_dat[1]
    out_z = z_dat[2] << 8 | z_dat[1]

    #+ or -
    if out_x >= 32768:
        out_x = out_x - 65536

    if out_y >= 32768:
        out_y = out_y - 65536

    if out_z >= 32768:
        out_z = out_z - 65536

    #change physical
    out_x *= 0.004
    out_y *= 0.004
    out_z *= 0.004

    out_x = round(out_x,4)
    out_y = round(out_y,4)
    out_z = round(out_z,4)

    #print
    print('X:' + str(out_x))
    print('Y:' + str(out_y))
    print('Z:' + str(out_z))

    time.sleep(0.05)
    return out_x,out_y,out_z


def HCsrread():
        #trig on

        GPIO.output(trigPin, GPIO.HIGH)
        time.sleep(0.00001)

        GPIO.output(trigPin, GPIO.LOW)

        #echo time
        echoStart = time.time()
        echoLoop = time.time()

        while GPIO.input(echoPin) == GPIO.LOW:
                echoStart = time.time()
                
                if echoStart - echoLoop >= 0.1:
                    break

        echoStop = time.time()

        while GPIO.input(echoPin) == GPIO.HIGH:
                echoStop = time.time()

                if echoStop - echoStart >= 0.006:
                        break

        echo = echoStop - echoStart

        echo = echo*(331.50+(0.6*temperature))/2*100

        echo = round(echo,3)

        print(echo)

        return echo


def DHTread():
        humidity,temperature = DHT.read_retry(dhtName,dhtPin)

        temperature = round(temperature,1)
        humidity = round(humidity,1)

        print('temperature' + str(temperature))
        print('humidity' + str(humidity))

        return temperature,humidity

#loop
while True:
    csvX,csvY,csvZ = ADXLread()
    csvEcho = HCsrread()
    
    if GPIO.input(spwPin) == GPIO.LOW:
        if findFlag == 1:
            csvCount += 1
        findFlag = 0
    else:
        findFlag = 1
    
    print(csvCount)


    dhtTime = time.time()
    if dhtTime - dhtTmp >= 30:
        dhtTmp = dhtTime
        csvTemp,csvHumi = DHTread()
    
    
    dt = datetime.datetime.today()
    csvDt = dt.strftime('%Y%m%d%H%M%S%f')[:-3]
    fileTime = time.time()
    
    if fileTime - fileTmp >= 60:
        fileTmp = fileTime
        dt = datetime.datetime.today()
        fileDt = dt.strftime('%Y%m%d%H%M%S')
        fileDtStop = dt+datetime.timedelta(minutes=1)
        fileDtStop = fileDtStop.strftime('%Y%m%d%H%M%S')
        
        with open('robot'+str(robotNum)+'_'+fileDt+'_to_'+fileDtStop+'.csv','a') as f:
            writer = csv.writer(f)
            writer.writerow(["robotNumber","time","X","Y","Z","distance","count","temperature","humidity"])
    else:
        with open('robot'+str(robotNum)+'_'+fileDt+'_to_'+fileDtStop+'.csv','a') as f:
            writer = csv.writer(f)
            writer.writerow([robotNum,csvDt,csvX,csvY,csvZ,csvEcho,csvCount,csvTemp,csvHumi])

    time.sleep(0.01)


f.close()
spi.close
                        

・CSV作成デモ

・CSVをサーバにアップロード

以下はCSVをサーバにアップロードするプログラムである。
送信が失敗した場合(レスポンスで200が返ってこない場合)CSVを削除しないようにしている。


# -*- coding: utf-8 -*-
import requests
import os
import datetime
import time


#difinition
XLSX_MIMETYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
filename=""
url="送り先のurl"

minute = datetime.timedelta(minutes=1)
gap = 0

while True:
    try:	    
        date = datetime.datetime.now()
        print(date)
        
        for filename in os.listdir():
            base, ext = os.path.splitext(filename)
            if ext == '.csv':
                print('file:{}'.format(filename))
                filetime = os.path.getmtime(filename)
                filetime = datetime.datetime.fromtimestamp(filetime)
                gap = date - filetime
                
                if gap > minute:
                    #post
                    with open(filename, 'rb') as file:
                        files = {'file': (filename, file, XLSX_MIMETYPE)}
                        response = requests.post(url, files=files)
                    
                    #print(response.text)

                    if response.status_code == 200:
                        print("send&remove")
                        os.remove(filename)
                    else:
                        print("error")
                else:
                    print("not minute")

        time.sleep(10)
    except:
        pass
                        

・CSV送信デモ

参考サイト


2.オープンキャンパス用ミニゲームのLED部分作成

山本ゼミでは班に分かれてオープンキャンパス用の脱出ゲームの作成を行った。
私の班ではタイミングよくボタンを押し、コインを積み上げるゲームと箱で橋を作るゲームの二つを作成した。
私はその中でタイミングを計る為のLEDテープの制御とボタンが押された後にそれをゲーム本体のプログラムに伝える部分を担当した。
以下はゲームのプレイ動画である。

・コインタワー

・箱の中身はなんだろな

使用物

結線

16番に繋がっているスイッチはゲームのLEDを止めるためのスイッチであり、
4番に繋がっているスイッチはLEDの速度を調整する為のスイッチである。

(画像クリックで拡大)

プログラム(スケッチ)

以下は実際にLEDを点灯させるプログラムとボタンを押された後に数値を送信するプログラムである。
二つのゲームに対して若干異なる処理を行っているが、概ね同じプログラムである為一つだけ掲載する。


#include <Adafruit_NeoPixel.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>

const char* ssid = "SSID";
const char* password = "PASS";

int buttonFlag = 0;

//数字を変える用変数
int changeCount = 0;
int changeTmp = 0;
int changeFlag = 0;
int changeTime = 90;

int speedNum = 0;

//送る数字の変数
int sendNum = 0;
//スイッチピン
int swPin = 16;
int speedPin = 4;
//LED関係
const int ledPin = 13;
const int ledCount = 150;
int ledMargin = 20;
int ledMarginTmp = ledMargin;

int R = 128;
int G = 128;
int B = 128;

//汎用
int i = 0;
//おまじない
Adafruit_NeoPixel pixels(ledCount, ledPin, NEO_GRB + NEO_KHZ800);

//サーバーのアドレス
const char* server = "IPアドレス";

//WiFiClient をclientで定義
WiFiClient client;

//関数の宣言
void connectServer(int);
void connectWiFi();

void setup() {
    pinMode(swPin, INPUT);
    pinMode(speedPin, INPUT);
    Serial.begin(115200);
    
    pixels.begin();
    connectWiFi();
    
    delay(100);
    
    pixels.clear();
    pixels.show();

    pixels.setPixelColor(sendNum + ledMargin, pixels.Color(R,G,B));  
    ledMargin++;
    pixels.setPixelColor(sendNum + ledMargin, pixels.Color(R,G,B));
    pixels.show();
}

void loop() {

    Serial.print("now:");
    Serial.println(sendNum);

    if (digitalRead(speedPin) == 1){
        speedNum++;

        if(speedNum==3){
            speedNum = 0;
        }

        if(speedNum==0){
            changeTime = 90;
        }else if(speedNum==1){
            changeTime = 200;
        }else{
            changeTime = 500;
        }
        delay(500);
    
    }

    //押されたときの処理
    if (digitalRead(swPin) == 1 && buttonFlag == 0){
        buttonFlag = 1;
        B = 0;
        pixels.setPixelColor(sendNum + ledMargin, pixels.Color(R,G,B));
        pixels.setPixelColor(sendNum + ledMargin - 1, pixels.Color(R,G,B));
        pixels.show();
        Serial.print("push:");
        Serial.println(sendNum);
        connectServer(sendNum);
        delay(350);

        for(i=0;i<4;i++){
            pixels.clear();
            pixels.show();
            delay(350);
            pixels.setPixelColor(sendNum + ledMargin, pixels.Color(R,G,B));
            pixels.setPixelColor(sendNum + ledMargin - 1, pixels.Color(R,G,B));
            pixels.show();
            delay(350);
        }
        B = 128;
    }

    if(digitalRead(swPin) == 0){
        buttonFlag = 0;
    }

    //時間処理
    changeCount = millis();
    if(changeFlag == 0){
        changeTmp = changeCount;
        changeFlag = 1;
    }
    if(changeCount - changeTmp >= changeTime){

        //5を超えたら0に戻す
        if(sendNum == 4){
            sendNum = -1;
            ledMargin = ledMarginTmp;
        }
        
        sendNum++;

        if(sendNum == 0|sendNum == 4){
            G = 0;
            B = 0;
        }else{
            G = 128;
            B = 128;
        }
        
        pixels.clear();
        pixels.setPixelColor(sendNum + ledMargin, pixels.Color(R,G,B));
        ledMargin++;
        pixels.setPixelColor(sendNum + ledMargin, pixels.Color(R,G,B));
        pixels.show();

        changeFlag = 0;
    }

    delay(10);
}

//アクセスポイントに接続
void connectWiFi() {
    Serial.println();
    Serial.println();
    Serial.println("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    //もしWiFiに接続してなかったら繰り返す
    while (WiFi.status() != WL_CONNECTED){
        delay(500);
        Serial.print(".");
    }
    Serial.println ( "" );
    Serial.print ( "Connected to " );
    Serial.println ( ssid );
}
//サーバーに接続し値を送る
void connectServer(int num) {

    if(client.connect(server, 80)){
        Serial.println("connected to server");
        client.print("GET 送り先のurl?data=");
        client.print(num);
        client.print(" HTTP/1.1\r\n");
        client.println("HOST: IPアドレス");
        client.println("Connection: close");
        client.println();
    }
}      
                        

参考サイト

トップへ戻る