私がReUsというサークルに入ってるという話は何回か出てきたと思いますが、(サークルって言ってるときは大体このサークルです。)そのサークルの主な活動であるEne1-GP MOTEGI KV-BIKEに参加してきました。

 この大会は充電式の単三電池40本で電動バイクを動かして、一周のタイムと60分で走った周回数を競う大会です。

 今回私はエンジニアとして計器のシステムの開発をしました。今回作ったシステムの概要は以下の通りです。
Untitled Diagram
 今回はすべてのセンサーがアナログなので機能のわりに複雑なシステムになりました。

・プログラム
Arduino-slave

#include <Wire.h>
#include <math.h>
int val = 0;
int i = 0;
int stb;
int sta;
int V;
float f;
void setup() {
  Serial.begin(9600);
  Wire.begin(8);
  Wire.onRequest(requestEvent);
  }

void loop() {
  val=analogRead(0);
  Serial.println(val);
  i++;
  if(val > 900){
    sta = 1;
  }else{
    sta = 0;
  }
  if(sta > stb){
      f = 10000 / i;
      V = 55*3.14*f;//なんかいい感じの係数をかける
      Serial.print("V=");
      Serial.println(V);
      i = 0;
  }
  stb = sta;
  delayMicroseconds(100);
}

void requestEvent() {
  Wire.write(V);
}


Arduino-master
#include <SoftwareSerial.h>
#include <math.h>
#include <Wire.h>
 
// rxPin = 2  txPin = 3
SoftwareSerial mySerial(2, 3);
 
// NMEAの緯度経度を「度」(DD)の文字列に変換する
String NMEA2DD(float val) {
  int d = val / 100;
  int m = (((val / 100.0) - d) * 100.0) / 60;
  float s = (((((val / 100.0) - d) * 100.0) - m) * 60) / (60 * 60);
  return String(d + m + s, 6);
}


int val1;//温度
int val2;//電圧
int temp;
float vol;
void setup() {
  Wire.begin();
  mySerial.begin(9600);
  Serial.begin(9600);
  }

void loop() {
  // 1つのセンテンスを読み込む
  String line = mySerial.readStringUntil('\n');
 
  if(line != ""){
    int i, index = 0, len = line.length();
    String str = "";
  
    // StringListの生成(簡易)
    String list[30];
    for (i = 0; i < 30; i++) {
      list[i] = "";
    }
 
    // 「,」を区切り文字として文字列を配列にする
    for (i = 0; i < len; i++) {
      if (line[i] == ',') {
        list[index++] = str;
        str = "";
        continue;
      }
      str += line[i];
    }
    
    // $GPGGAセンテンスのみ読み込む
    if (list[0] == "$GPGGA") {
      
      // ステータス
      if(list[6] != "0"){
        Serial.println("start");
        
        //緯度
        Serial.println(NMEA2DD(list[2].toFloat()));
        
        //経度
        Serial.println(NMEA2DD(list[4].toFloat()));
        
        //温度
        val1=analogRead(0);
        Serial.println(temp);

        //電圧
        val2=analogRead(1);
        vol = val2 * 0.00488281 * 11 ;
        Serial.println(vol);
  
        Wire.requestFrom(8,1);
        while (Wire.available()) {
          long c = Wire.read();
          Serial.println(c);
          }

      }else{
        Serial.println("start");
        
        //緯度
        Serial.println("error");

        //経度
        Serial.println("error");
        
        //温度
        val1=analogRead(0);
        Serial.println(temp);
        
        //電圧
        val2=analogRead(1);
        vol = val2 * 0.00488281 * 11 ;
        Serial.println(vol);
        
        Wire.requestFrom(8,1);
        while (Wire.available()) {
          long c = Wire.read();
          Serial.println(c);
      }
    }
  }
 }
}


Raspberry Pi

from serial import *
from sys import exit
from datetime import datetime
import pygame
import datetime,time
import requests

from pygame.locals import *
import sys

SCREEN_SIZE = (640, 480)
url = 'https://xxx.jp/yyy/update.php'

def addTime(logtext):
return str(datetime.datetime.now()) + ' ,' + logtext

def retime():
if(retime1 >= 50):
if(retime2 >= 50):
return "0" + str(59-retime2) + ":" + "0" + str(59-retime1)
elif(retime2 < 50):
return str(59-retime2) + ":" + "0" + str(59-retime1)
elif(retime1 < 50):
if(retime2 >= 50):
return "0" + str(59-retime2) + ":" + str(59-retime1)
elif(retime2 < 50):
return str(59-retime2) + ":" + str(59-retime1)


pygame.init()
screen = pygame.display.set_mode(SCREEN_SIZE)
pygame.display.set_caption("data")

# ArduinoのUSBデバイス名
port = '/dev/ttyACM0'

# フォントの作成
sysfont = pygame.font.SysFont(None, 80)

# シリアルポートを開く
try:
ser = Serial(port, 9600)
print('open port: %s' % port)
except:
print('cannot open port: %s' % port)
exit(1)

f = open("write.txt","w")
f.write(addTime("start\n"))
f.close()


# 読み出しと出力
while True:
line = ser.readline().rstrip().decode("utf-8")
if(line=="start"):

# 1ライン単位で読み出し、末尾の改行コードを削除
line1 = ser.readline().rstrip().decode("utf-8")
line2 = ser.readline().rstrip().decode("utf-8")
line3 = ser.readline().rstrip().decode("utf-8")
line4 = ser.readline().rstrip().decode("utf-8")
line5 = ser.readline().rstrip().decode("utf-8")


payload = {"speed":line5,"temp":line3,"volt":line4}
response = requests.get(url,params=payload)
# テキストを描画したSurfaceを作成
text1 = sysfont.render("North", True, (0,0,0))
text2 = sysfont.render("East", True, (0,0,0))
text3 = sysfont.render("Temp", True, (0,0,0))
text4 = sysfont.render("Volt", True, (0,0,0))
text5 = sysfont.render("Speed", True, (0,0,0))
data1 = sysfont.render(line1, True, (0,0,0))
data2 = sysfont.render(line2, True, (0,0,0))
data3 = sysfont.render(line3, True, (0,0,0))
data4 = sysfont.render(line4, True, (0,0,0))
data5 = sysfont.render(line5, True, (0,0,0))

f = open("write.txt","a")
f.write("North,")
f.write(line1)
f.write(", Eeat,")
f.write(line2)
f.write(", Temp,")
f.write(line3)
f.write(", Volt,")
f.write(line4)
f.write(", Speed,")
f.write(line5)
f.write(",\n")
f.close()

try:
screen.fill((255,255,255))

# テキストを描画する
screen.blit(text1, ( 0, 50))
screen.blit(data1, (200, 50))
screen.blit(text2, ( 0,100))
screen.blit(data2, (200,100))
screen.blit(text3, ( 0,150))
screen.blit(data3, (200,150))
screen.blit(text4, ( 0,200))
screen.blit(data4, (200,200))
screen.blit(text5, ( 0,250))
screen.blit(data5, (200,250))

pygame.display.update()
except Exception as e:
print(e.message)



for event in pygame.event.get():
if event.type == QUIT:
sys.exit()

プログラム自体は今までやってきたものの組み合わせでした。

 本番のこととかはこちら

 まあ、これでひと段落したので、Pygameで作っているパックマンを完成させて、その後にライントレーサーのIoT化とかをやっていきたいと思います。
 あと、インバーターとかも作ります。それではまた今度。