2022年前期活動
ページ内リンク
1.産業用ロボット監視用センサ制御のRaspberry Pi化2.オープンキャンパス用ミニゲームのLED部分作成
1.産業用ロボット監視用センサ制御のRaspberry Pi化
産業用ロボットの作業、状態監視のため、複数種類のセンサを統合しサーバにアップロードするシステムの仕様変更を行った。
昨年はESP-WROOM-02開発ボードを使用してセンサのデータをサーバに直でアップロードする方法を取った。
しかし、実際に設置を行い実験したところ通信速度の問題により安定してデータをアップロードすることが出来ない不具合が生じた。
そこで、本研究ではRaspberry Piを使用することでセンサデータをCSV化し、アップロードに失敗した際にデータを保存するような形を取る事にした。
使用物
- Raspberry Pi
- 三軸加速度センサ(ADXL345)
- 超音波センサ(HC-SR04)
- 遮光センサ(EE-SPW311)
- 湿温度センサ(DHT22)
- ジャンパー線
- 抵抗(330Ω)
結線
現在はブレッドボード上に実装しているが、後に基板上に実装する予定である。
(画像クリックで拡大)
プログラム
プログラムはセンサのデータを受け取り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();
}
}