Pygameで遊んだ話

 製作実験という授業でライントレーサーを作るのですが、今までにいろいろなトレーサーを作っているのでただ作るだけでは面白くないと思い、ディスプレイに走行状態を表すアニメーションなんかを移そうと思いました。ちょうど、ラズパイ用のディスプレイも買ったのでPygameを使って作り、ラズパイで写すことにしました。

・準備
 ラズパイとWindowsのPCのセットアップの仕方は忘れました。ラズパイではデフォルトのもの、ノートパソコンではPyCharmを使っています。

・プログラム
import sys, pygame

pygame.mixer.pre_init(44100, -16, 1, 512)
pygame.init()
window_size = (320, 240)
clock = pygame.time.Clock()
screen = pygame.display.set_mode(window_size)
#img_char1 = pygame.image.load('reimu2.png')
img_char2 = pygame.image.load('reimu3.png')
before = 3
after = 3

# SEの読み込み
se = pygame.mixer.Sound('se.wav')
"""
# BGMを読み込んで再生
pygame.mixer.music.load('bgm1.wav')
pygame.mixer.music.set_volume(0.5)
pygame.mixer.music.play(-1)
"""

x = 75 # 表示位置X

# キー入力
class KeyState:
def __init__(self):
self.key_new = pygame.key.get_pressed()
self.key_old = self.key_new

def update(self):
self.key_old = self.key_new
self.key_new = pygame.key.get_pressed()

def get_key(self, name):
return self.key_new[name]

ks = KeyState()
end_game = False
while not end_game:
for event in pygame.event.get():
if event.type == pygame.QUIT:
end_game = True

ks.update()

r, g, b = 255, 255, 255
if ks.get_key(pygame.K_w):
loop_anim_index = int(20) % 4
after = 0
elif ks.get_key(pygame.K_a):
loop_anim_index = int(21) % 4
after = 1
elif ks.get_key(pygame.K_d):
loop_anim_index = int(22) % 4
after = 2
elif ks.get_key(pygame.K_s):
loop_anim_index = int(23) % 4
after = 3
else:
loop_anim_index = int(23) % 4
after = 3


if before != after:
se.play() # SEの再生

before = after

screen.fill((r,g,b))
#screen.blit(img_char1, (x, 50), (27 * loop_anim_index, 0, 27, 16))
screen.blit(img_char2, (x, 150), (163 * loop_anim_index, 0, 163, 96))
pygame.display.flip()
clock.tick(60)

sys.exit(0)
 このようなプログラムを書きました。
 いろいろなプログラムを参考にして適当に描いたので、ぐちゃぐちゃですが許してください。
 コメントアウトしている文では、小さいほうのアニメーションを動かせます。

・素材
reimu2
reimu3
 今回はサイズ違いの二つのものを作りました。画力がないので微妙ですが。
 博麗霊夢が旗をパタパタしてるように見えたらいいです。

・動作
 映像のようにWを押すと両手をA,Dを押すとそれぞれ右手と左手を挙げてくれます。


 今回は製作実験のためにPygameを使いました。ソフトの素材はほとんどできていると思うので、ハードの制作とソフトの合成?を進めていきたいです。
 それではまた今度。

ラズパイとArduinoでシリアル通信をした話

 製作実験という授業で作るライントレーサーとサークルのモジュールで使うために、Raspberry PiとArduinoでシリアル通信をしました。


・準備すること
 ラズパイでシリアル通信をするためにはpysirialというライブラリが必要なのですが、それをインストールするためにはpipというものが必要です。それぞれをダウンロードするために↓のコマンドをターミナルで打ちます。
$ sudo apt-get install python-pip
$ pip install pyserial

・Arduinoのプログラム
 ラインとレースをする都合でいろいろシリアル通信と関係ない部分が多いですが、Arduinoから出力する分にはシリアルモニタに出力するときと一緒です。
 ちなみにこのプログラムで読み取っているのはフォトリフレクタからの出力で、出力しているのはTA7291pへの信号です。
int val1,val2,val3,val4,val5;
int thre1=500;
int thre2=500;
int thre3=500;
int thre4=500;
int thre5=500;

int repo;

void setup() {
  Serial.begin(9600);
  pinMode(13,OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(10,OUTPUT);
}
 
void loop() {
  
  val1=analogRead(0);
  val2=analogRead(1);
  val3=analogRead(2);
  val4=analogRead(3);
  val5=analogRead(4);
  
  if(val2>thre2){
  repo=2;
  digitalWrite(13,HIGH);
  digitalWrite(12,LOW );
  digitalWrite(11,HIGH);
  digitalWrite(10,HIGH);}
  
  if(val3>thre3){
  repo=1;
  digitalWrite(13,HIGH);
  digitalWrite(12,LOW );
  digitalWrite(11,LOW );
  digitalWrite(10,HIGH);}
  
  if(val4>thre4){
  repo=3;
  digitalWrite(13,HIGH);
  digitalWrite(12,HIGH);
  digitalWrite(11,LOW );
  digitalWrite(10,HIGH);}
  
  if(val1>thre1){
  repo=4;
  digitalWrite(13,LOW );
  digitalWrite(12,HIGH);
  digitalWrite(11,LOW );
  digitalWrite(10,HIGH);}
  
  if(val5>thre5){
  repo=5;
  digitalWrite(13,HIGH);
  digitalWrite(12,LOW );
  digitalWrite(11,HIGH);
  digitalWrite(10,LOW );}
  
  if(val1>thre1 && val5>thre5){
  repo=0;
  digitalWrite(13,HIGH);
  digitalWrite(12,LOW );
  digitalWrite(11,LOW );
  digitalWrite(10,HIGH);}
  
  Serial.println(repo);
  delay(10);
}

・Raspberry Piのプログラム
# coding: UTF-8

from serial import *

from sys import exit

from datetime import datetime

# ArduinoのUSBデバイス名

port = '/dev/ttyACM0'

# シリアルポートを開く

try:

   ser = Serial(port, 9600)

   print('open port: %s' % port)

except:

   print('cannot open port: %s' % port)

   exit(1)

# 読み出しと出力

while True:

   # 1ライン単位で読み出し、末尾の改行コードを削除

   line = ser.readline().rstrip()

   try:

       print(datetime.now(),line)

   except Exception as e:

       print(e.message)


・動作
 これを入れて、Ardinoと普通のパソコンをつなぐのと同じ様にラズパイとArduinoをつなぐと、Serialprintされた値がラズパイに表示されます。この値を使ってラズパイ側で音を鳴らしたり画像を表示したりしたいのですが、いまいちいい方法が見つからず...まあ、いろいろ試行錯誤してやっていこうと思います。それではまた今度。


こんな感じで動かしてました。
JPiAwx-C

ラズパイ用ディスプレイを買った話

 ラズパイを家の外でも動かすために専用ディスプレイを買ったので、今回はそのことを書きました。

 ラズパイ用のディスプレイを選ぶにあたって色々調べていたところ、ラズパイのGPIOピンを使っているものがあり、そのディスプレイを使っているとGPIOピンが使えなくなってしまうということがわかりました。なので今回はGPIOが使えることを第一条件に選びました。

 その結果今回選んだのはこちらのものです。


 先ほど言った通りGPIOが使えるものの中でもいいと思ったのでこれにしました。
 このディスプレイはGPIOを使わないためHDMIでラズパイと接続します。そのために、このように二つ並んだHDMIのポートをつなぐための独特な形の基板が付いてきます。

IMG_1130

↑の二つのHDMIポートをつなぐために↓のような基板が付いてきます。
IMG_1131

 また、ディスプレイにつながれてしまうはずのGPIOピンは横に飛び出たピンヘッダで使えます。IMG_1128


 このディスプレイはタッチディスプレイとしても使えるのですが、使えるようにするには別にセットアップしなければいけません。付属しているDVDにドライバなどが入っているようなのですが、ラズパイに光学ドライブはもちろんついてないし、一回デスクトップに入れてから移し替えるのも面倒くさいです。それなので今回は、githubにも同じものがあるのでそれをインストールしました。
 
 セットアップ手順は、ターミナルで下のコマンドを実行するだけです。
$ git clone https://github.com/goodtft/LCD-show.git
chmod -R 755 LCD-show
cd LCD-show/
sudo ./MPI3508_480_320-show
 これを実行すると画面が暗転し、大量の文字が下から流れてきますがそれが終わればタッチパネルが機能するようになります。


 今回は、ラズパイを外出先でも使えるようにディスプレイの設定を行いました。これで家以外でもラズパイをいじれるようになったので、開発を進めていきたいと思います。それではまた今度。

「みちびき」対応のGPSセンサーを使ってみた話

 サークルのほうで、GPSを使って面白いことができたらいいと思ったので、ちょっと使ってみました。

 秋月でGPSモジュールを検索したら「みちびき」対応のものがあったので、それを買ってきて使うことにしました。

・回路
 今回はアナログシリアルを使ったことや1PPSを使わなかったため、入っている説明書とは少し違う回路になってます。
 説明書ではTXとRXになっている所を今回はDIGITALピンの3,2ピンに接続しています。

・プログラム
 ネットで見つけたプログラムを改良して使っています。ゴリ押しで速度を出しているのでプログラムが汚いですが、そこには目を瞑ってください...
#include <SoftwareSerial.h>
#include <math.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);
}
 
// UTC時刻から日本の標準時刻に変換する(GMT+9:00)
String UTC2GMT900(String str) {
  int hh = (str.substring(0,2).toInt()) + 9;
  if(hh > 24) hh = hh - 24;
 
  return String(hh,DEC) + ":" + str.substring(2,4) + ":" + str.substring(4,6);  
}
 
  float ai,bi,di;//緯度の状態
  float ak,bk,dk;//経度の状態
  float fi=294.2940886111111;//緯度一分当たりの距離
  float fk=295.2841203703704;//経度一分当たりの距離
  float dmi,dmk,def;//移動距離
void setup() {
  mySerial.begin(9600);
  Serial.begin(115200);
}
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(UTC2GMT900(list[1]));
        
        //緯度
        bi =list[2].toFloat();
        di = bi - ai;
        dmi = di * fi;
        Serial.print(" 緯度:");
        Serial.println(NMEA2DD(list[2].toFloat()));

        //経度
        bk =list[4].toFloat();
        dk = bk - ak;
        dmk = dk * fk;
        Serial.print(" 経度:");
        Serial.println(NMEA2DD(list[4].toFloat()));

        //速度
        def=sqrtf(dmi*dmi + dmk*dmk);
        Serial.print("速度:");
        Serial.println(def);
        
      }else{
        Serial.print("測位できませんでした。");
      }
      
      Serial.println("");
      ai =bi;
      ak =bk;
    }
  }
}


・動作
 GPS信号を扱っている関係で、出力に緯度と経度が乗ってしまうので画像は上げられないのですが、速度を出力することは一応できました。しかし、等速に移動しているときでも結構表示される速度に違いが出てしまいました。


 今回は、精度の良いGPS信号を得ることができていたのに、あまりそれを活用することができませんでした。このモジュールは10Hzで信号を出すことができるので、それを利用してもっと複雑な処理をすれば精度が上がると思います。
 すぐ改良したいのですが、大学が始まってしまって忙しくなってしまったので今回はここまで、それではまた今度。

ラズパイ-ArduinoでI2C

 ArduinoをA/D変換などのデコーダやモータードライバとして使うために、ラズパイからArduinoに指令を出せるようにしました。


1.配線
 今回はラズパイの3B+での配線なので、パターンが違う別のボードではつなぐピンが違うので気を付けてください。
 図のように配線すると、SDA,SCL,GND同士をつなぐことができます。

arduino-raspi_ブレッドボード

2. Arduinoのプログラム
 このあいだArduino-Arduino間のI2Cをした時のプログラムと大体同じ感じになってます。
#include <Wire.h>

int add = 0x04; //I2Cのアドレスを0x04に設定
int out = 13;
int Ain = A0;

boolean toggle = false; //LEDの点灯制御用

void setup(){
  pinMode(out, OUTPUT);

//I2C接続を開始する 
  Wire.begin(add);

//Raspberry Piから何かを受け取るたび、receive関数を呼び出す 
  Wire.onReceive(receive); 

//Raspberry Piから要求された場合に、send関数を呼び出す 
  Wire.onRequest(send);
}

void loop(){
}

void receive(int n){
 char ch = Wire.read();
 if (ch == '1'){
  LED(); 
 }
}

//LEDの点灯・消灯用の関数
void LED(){
  toggle = !toggle; //trueとfalseの入れ替え
  digitalWrite(out, toggle);  
}

//Analogピンの数値を読み、Raspberry Piに送る
void send(){
  int reading = analogRead(Ain);
  Wire.write(reading >> 2); //ビットを2つ右にずらした数値を送る
}

3.Raspberry Piのプログラム
 これはとても簡単で、shellに打ち込まれた文字によってArduinoに対する出力を変えることと、Arduinoからの入力を表示することを行っています。

import smbus

import time


bus = smbus.SMBus(1)


add = 0x04


def request_reading():

   reading = int(bus.read_byte(add))

   print(reading)


while True:

   command = input("Enter command: 1-Toggle LED, r-read A0:")

   if command == '1':

       bus.write_byte(add, ord('1'))

   elif command == 'r':

       request_reading()


4.実際の動作

2018-09-18-113207_1366x704_scrot
 実際に動作させているときの画面はこのようになります。"1"と入力したときにLEDの出力が変わり、"r"と入力したときにArduinoで読み取ったセンサーの値を表示することができました。
 

 夏休みが残り一日となりましたが、今週末までには買っているけど使ってないセンサー類(GPSモジュールとか)を使えるようにして記事が書けるといいなと思います。それではまた今度。

ラズパイでi2c(仮)

 ラズパイでi2Cを使えるようになるために、この前Arduinoで使ったLCDをRaspberry Piでも使ってみることにしました。

 今回は前回と同じくモジュール付きのLCDを使いました。型番はFC-113というものでした。調べたところ、ラズパイでこのLCDを使うためのサンプルプログラムが公開されており、それを参考にすることにしました。

1. 配線
 ラズパイのピンアサインを公式サイトで調べ、GND,VCC,SDA,SCLをLCDの対応するピンとつなぎます。

2. i2cを有効にする
 Terminalで下記のコマンドを実行します。
$ sudo raspi-config
そうすると、画面が切り替わるので、Interfacing Option -> I2C -> Enable I2C -> Finish という風に進みます。
 ラズパイが再起動したらconfig fileを編集します。そのためにまず、Terminalで下記のコマンドをっ実行します。
$ sudo nano /etc/modules
モジュールファイルに下記の二つの分を追加しっます。
i2c-bcm2708
i2c-dev
Ctrl+Xを押して決定し、Yを押すと保存されます。

3. ライブラリのインストール
 Terminalで下記のコマンドを実行します。
sudo apt-get update
$ sudo apt-get install -y python-smbus i2c-tools
$ sudo reboot
三つ目のコマンドは再起動させるものなので、それが完了したら
Terminalで下記のコマンドを実行します。
$ lsmod | grep i2c_
i2c_bum2708がリストに追加されていればセットアップが完了しています。もしなかったら2と3を繰り返します。

4.  アドレスの確認
 Terminalで下記のコマンドを実行します。
$ sudo i2cdetect -y 1
or
$ sudo i2cdetect -y 0
 今回自分は3fと出ました。これが、後に書くプログラムの五行目にかかわってきます。

5. プログラム

import smbus

import time


# Define some device parameters

I2C_ADDR  = 0x3f # I2C device address, if any error, change this address to 0x27

LCD_WIDTH = 16   # Maximum characters per line


# Define some device constants

LCD_CHR = 1 # Mode - Sending data

LCD_CMD = 0 # Mode - Sending command


LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line

LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line

LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line

LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line


LCD_BACKLIGHT  = 0x08 # On

#LCD_BACKLIGHT = 0x00  # Off


ENABLE = 0b00000100 # Enable bit


# Timing constants

E_PULSE = 0.0005

E_DELAY = 0.0005


#Open I2C interface

#bus = smbus.SMBus(0)  # Rev 1 Pi uses 0

bus = smbus.SMBus(1) # Rev 2 Pi uses 1


def lcd_init():

 # Initialise display

 lcd_byte(0x33,LCD_CMD) # 110011 Initialise

 lcd_byte(0x32,LCD_CMD) # 110010 Initialise

 lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction

 lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off

 lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size

 lcd_byte(0x01,LCD_CMD) # 000001 Clear display

 time.sleep(E_DELAY)


def lcd_byte(bits, mode):

 # Send byte to data pins

 # bits = the data

 # mode = 1 for data

 #       0 for command


 bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT

 bits_low = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT


 # High bits

 bus.write_byte(I2C_ADDR, bits_high)

 lcd_toggle_enable(bits_high)


 # Low bits

 bus.write_byte(I2C_ADDR, bits_low)

 lcd_toggle_enable(bits_low)


def lcd_toggle_enable(bits):

 # Toggle enable

 time.sleep(E_DELAY)

 bus.write_byte(I2C_ADDR, (bits | ENABLE))

 time.sleep(E_PULSE)

 bus.write_byte(I2C_ADDR,(bits & ~ENABLE))

 time.sleep(E_DELAY)


def lcd_string(message,line):

 # Send string to display


 message = message.ljust(LCD_WIDTH," ")


 lcd_byte(line, LCD_CMD)


 for i in range(LCD_WIDTH):

   lcd_byte(ord(message[i]),LCD_CHR)


def main():

 # Main program block


 # Initialise display

 lcd_init()


 while True:


   # Send some test

   lcd_string("Created by ",LCD_LINE_1)

   lcd_string("Chisao_62 ",LCD_LINE_2)


   time.sleep(3)

 

   # Send some more text

   lcd_string("Hello World ",LCD_LINE_1)

   lcd_string("Raspberry Pi ",LCD_LINE_2)


   time.sleep(3)


if __name__ == '__main__':


 try:

   main()

 except KeyboardInterrupt:

   pass

 finally:

   lcd_byte(0x01, LCD_CMD)


最終的にこのようなプログラムとなりました。これを実行した結果下のように動きました。


 ラズベリーパイ関係のことはまだまだできないことが多いので、いろいろやっていこうと思います。それではまた今度

ラズパイを使ってみた話

 ラズパイをこのあいだ買ったので、セットアップとLチカを行いました。

・ハードの準備
 用意したものはコチラ

IMG_1033
 ラズパイ本体です。秋月でRaspberry Pi 3 Model B+を買ってきました。
IMG_1034
 microSDカードです。相性が悪いものがあると聞いたので調べた結果、東芝のものは全部使え、16GBあれば余裕があるとのことだったので、これを買ってきました。秋月で売っているmicroSDはこれだけなのかな?と思います。
 マウスはノパソで使ってたもの、ディスプレイとキーボードはメインPCで使っているものを使いました。キーボードだけ使ってないものがなかったので、メインPCとラズパイの間で抜き差ししながら使うことにしました。

・ソフトの準備
 セットアップの手順は以下の通りでした。
①別のパソコンにmicroSDカードを挿す。
②公式サイトからOSをダウンロードする。
③ダウンロードしてきたファイルを展開する。
④展開したファイルをSDカードに書き込む。
⑤SDカードをラズパイにさす。
⑥ラズパイを起動して画面の手順に従って操作する。
という手順で簡単にできました。
 ここまで終わるとプログラムやオフィスなどのことができる環境が整いました。

・Lチカ
 私は今までPythonを使ったことがなかったので、まずはプログラムではなく、ターミナルでLチカを行うことにしました。

 公式サイトでピンアサインを調べ、GPIO2ピンとGNDにLEDと適当な抵抗を刺します。
 ターミナルに以下の通りに入力します。
 echo 2 > /sys/class/gpio/export
 echo out  > /sys/class/gpio/gpio2/direction
 echo 1  > /sys/class/gpio/gpio2/value
 echo 0  > /sys/class/gpio/gpio2/value
 echo 2 > /sys/class/gpio/unexport
するとそれぞれ、
・ピンを有効化
・アウトプットに設定
・ON
・OFF
・ピンを無効化
というように働くはずです。まだ自分もよくわかってないのでここら辺は間違えているかもしれません。実際に動作させるとこのようになります。

 PythonでもLチカをしてみました。
 以下のプログラムを書き込みます。
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(2, GPIO.OUT)
while True:
    GPIO.output(2, GPIO.HIGH)
    time.sleep(0.1)
    GPIO.output(2, GPIO.LOW)
    time.sleep(0.1)
    GPIO.cleanup()
書き終わってRUNさせるとLチカができます。
このような感じになります。


 今回はこれで以上です。これをやる前に自作VVVFインバータで三相モーターを回すことができなかった事件がありました。しかし、どうせシステムもインバータも期限は大体一緒だと思うから気分転換にこっちをやりました。
 後期始まるまで一週間切ってるんですけど、お金が無くなってきているので働かないといけない上、授業中にラズパイいじるためにディスプレイ買いたいので、バイトしなきゃと思いつつ適当にバイトをしながら進捗を上げればいいなぁと思います。それではまた今度

システムの開発をしなきゃなっていう話

 I2Cとデータの表示の練習として、センサー-Arduino-Arduino-LCDとデータを転送するシステムを作りました。

・システムの詳細
 SlaveのArduino(以下スレイブ)では、MasterのArduino(以下マスター)から要求があった時にセンサーの値を読み取りマスターにそのデータを返します。また、マスターではスレイブにデータの要求をし、帰ってきたデータをLCDに表示します。

・配線
 そのためにまず、スレイブには使うセンサー(今回は半固定抵抗器)をつなぎ、マスターにはLCDと通信するためにArduinoとLCDのSDA,SCL,VCC,GNDをつなぎます。Arduino間はI2C通信を行うためにSDA,SCL,GNDをつなぎます。
 実際に配線するとこんな感じです。キタナイ...
IMG_1013


・プログラム
マスター
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
  LiquidCrystal_I2C lcd(0x3F, 16, 2); // I2C: 0x3F, 16x2 LCD
  long c=0;

void setup() {
  Wire.begin();
  lcd.init(); 
  lcd.backlight();
  Serial.begin(9600);
}

void loop() {
  Wire.requestFrom(8,1);
  while (Wire.available()) {
    c = Wire.read();
    Serial.println(c);
  }
  lcd.setCursor(0, 0);
  if(c >99){
  lcd.print(c);}
  else{
    if(c >9){
    lcd.print(" ");//LCDの出力を整えるための空白
    lcd.print(c);}
    else{
    lcd.print("  ");//LCDの出力を整えるための空白
    lcd.print(c);
    }}
  delay(100);
}


スレイブ
#include <Wire.h>
int val1=0;

void setup() {
  Serial.begin(9600);
  Wire.begin(8);
  Wire.onRequest(requestEvent);
}

void loop() {
  delay(100);
}

void requestEvent() {
  val1=analogRead(0)/4;
  Serial.println(val1);
  Wire.write(val1);
}

・動作
 実際の動作の様子はこんな感じです。マスター、スレイブ、LCDの値がずれることなく同期できています。



 今回はこんな感じで、今まで通信系のことを一切やっていなかったので勉強になりました。まあ、サークルとかで使うかもしれないのでその時に生かせたらいいな...と。

 後期が始まるまで二週間切ってしまったので、制作実験用の期待の改良をやんないとなぁと思いつつ机の上にあってジャマな三相モーターも動かせるようにならないとなぁと思っています。それではまた今度

なんとなくLCDを点けた話

 なんか家に謎のLCDがあったので使ってみました。

 実物がこれです
IMG_0988

IMG_0990
 なんか裏にモジュールがついていました。自分ではんだ付けした覚えはないので元からはんだ付けして在ったやつでしょうたぶん。調べたところ付いてるのはI2CモジュールらしくI2C入力を入れれば簡単に動く便利なものでした。

Arduino IEDでライブラリを持ってきて適当にプログラムを書きました。
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2); // I2C: 0x3F, 16x2 LCD

void setup() {
  lcd.backlight();
  lcd.init(); 
}

void loop() {
  lcd.setCursor(0, 0);
  lcd.print("Hello, world!");//一行目
  lcd.setCursor(0, 1);
  lcd.print("by Chisato");//二行目
}

このプログラムで光った様子がこちら

IMG_0991

 モジュールを使っているからワイヤーの本数が少ないこと以外はごく普通の動作をしました。

今回は短いけどこれ以上やることないのでそれではまた今度

ライントレーサーの改良をしたかった話

 前回、前々回でちょっと触れたライントレーサーの改良について失敗したのでその話でも。

 そもそも前回作ったモノは、「ラインが途切れているとき」「ラインが交差しているとき」の二点で自分の中では十分とは言えない性能でした。公益財団法人ニューテクノロジー振興財団のロボトレース協議規定( https://www.ntf.or.jp/mouse/micromouse2013/kitei_trace_since2013.html )ではラインが途切れることはないんですけど、昔NXTでなにかの大会に出たときはラインが途中で途切れてたりラインの上に障害物が置いてあったりしたので、ラインがなくてもある程度は動けるようにしようとしていました。

 実際のシステムは、前に作った時の回路の演算部を下の論理回路に置き換えることで実現させることにしました。
line v3 ronri
実際に素子で表すと以下のようになります。
LINE ronri_回路図v2

これをブレッドボードで作って動作させてみた様子がこちら。


 この時点ではうまくいっているように見えたが、主にOR回路の電圧降下が大きいことが今考えると問題であったのかもしれない


 これらの実験の結果、予測された入力に対して要求している通りの出力を得ることができたので配線図を書きました。

LINE ronri(boad)_プリント基板
 この基板を書く時には二層基板にしないと車体に乗らないことが分かっていたので二層にすることを前提に描いたのですが、すごく見づらい図になってしまいました。あと、間違えて左右反転して作ってしまっています。

 この配線図の通りにユニバーサル基板に配線し実験してみたのですが、入力のA/D変換に使ったコンパレータの出力電圧が過去に行った実験や前回のトレーサーでは5v出力されていたのに今回の回路では最大でも1.5v程度しか出ず、後々の演算部での電圧降下がそれよりも大きいため出力が想定通りに出ませんでした。

 まあその結果うまく動かずに失敗となったわけですが、まあいつか改良をしようと思ってます。後期の授業で制作実験というものがあり、その授業ではライントレーサを作るのでそれまでにはきちんと動くものを作ろうと思います。
 しかし、せっかくスライダックと三相モーターを買ったのでそれを使いたいという欲求が高まってきているのと、それらを買ったせいでお金がないので様々な素子が買えないという問題があります。それなので、しばらくはバイトを集中的にやりお金をためて、VVVFインバータなどのパワエレの勉強をやってきたいと思っています。
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

読者登録
LINE読者登録QRコード