RaspberryPi 初期設定

64GBのSDカードを手に入れたので
RaspberryPiのSDカードを変更しようと思った。

OSをインストールする際に
SSHから初期設定ができるという話を聞き、
調べてみたので、併せてメモ。

環境

  • Windows10 64bit
  • teraterm-4.95
  • RaspberryPi2 Model B

OSのダウンロード

Raspbian Stretch with desktopを使用するため下記がダウンロード。
(今回の用途的にデスクトップの方が都合が良いため)

Download Raspbian for Raspberry Pi

SDカードの書き込み

DLしたOSはイメージファイルであるため下記を用いて書き込み

Etcher

書き込み後、即SSHを使用したいため
SSHという空ファイルをBoot直下に作成する。
(デフォルトで有効という話もあるが)

RaspberryPiのIPアドレスを調べる

何処に繋がっているかわからないのでIPを調べる。
ブロードバンドルータにログインして確認する方法もあるようだが
すぐに確認したかったのでPingを飛ばして確認。

import pings
p = pings.Ping()
ip = '192.168.11.'
with open('ping.txt', 'w') as f:
    for n in range(0, 20):
        print(n)
        res = p.ping(ip + str(n))
        if res.is_reached():
            f.write(ip + str(n) + "\n")

SSH

teratermから
引っかかったIPアドレスにアクセス。
※portは22
username→pi
password→raspberry

とりあえず、無事にアクセスできました。

【RaspberryPi】 RaspberryPiとArduinoをCAN通信させた 2回目

少し前に"Rasbee オリジナル MCP2515 CAN バス モジュール TJA1050 レシーバーSPIモジュール Arduinoのための AVR"を1つ壊してしまったのでMCP2561とMCP2515を改めて購入。
組み立てができたのでpython-canを用いて、RaspberryPiとArduinoのCAN通信で遊んでみたのでメモ。

f:id:Yoshichi:20171001032155j:plain

ハード側の準備

構成

配線などはfritzingの使い方覚えたら公開
(が、配線は察しorz)
f:id:Yoshichi:20171001032248j:plain

Arduino

ソースはこんな感じ。

#include <mcp_can.h>
#include <SPI.h>

#define TRIG_PIN  8
#define ECHO_PIN  9
int Duration;
float Distance;

MCP_CAN CAN0(10);     // Set CS to pin 10
byte Txbuffer[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

void CanInit()
{
  // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
  if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK) Serial.println("MCP2515 Initialized Successfully!");
  else Serial.println("Error Initializing MCP2515...");

  CAN0.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted
}

void CanSetTxBuffer(int t_duration)
{
  int v;
  for(int i = 0; i < 8; i++) {
    Txbuffer[i] = 0x00;
  }
  v = max(0, t_duration);
  Txbuffer[0] = (v >> 8) & 0xFF;
  Txbuffer[1] = v & 0xFF;
}

int  CanTransmitt(int id)
{
  byte sndStat = CAN0.sendMsgBuf(id, 0, 8, Txbuffer);
  if(sndStat == CAN_OK) {
    return 1;
  } else {
    return 0;
  }
}

void HcSr4Init()
{
  pinMode(TRIG_PIN,OUTPUT);
  pinMode(ECHO_PIN,INPUT);
}

void HcSr4Run()
{
  digitalWrite(TRIG_PIN,LOW);
  delayMicroseconds(1);
  digitalWrite(TRIG_PIN,HIGH);
  delayMicroseconds(11);
  digitalWrite(TRIG_PIN,LOW);
  Duration = pulseIn(ECHO_PIN,HIGH);
  if (Duration>0) {
    Distance = Duration/2;
    Distance = Distance*340*100/1000000; // ultrasonic speed is 340m/s = 34000cm/s = 0.034cm/us 
  }
}

void setup()
{
  Serial.begin(9600);
  CanInit();
  HcSr4Init();
}

void loop()
{
  HcSr4Run();
  Serial.print(" Hex: ");
  Serial.println(Duration,HEX);
  Serial.print(Duration);
  Serial.print(" us ");
  Serial.print(Distance);
  Serial.println(" cm");

  CanSetTxBuffer(Duration);
  if(CanTransmitt(0x100) == 1){
    Serial.println("Message Sent Successfully!");
  } else {
    Serial.println("Error Sending Message...");
  }
  delay(500);
}

簡単な解説

距離センサモジュールで取得した応答時間
ID100に対してセットし、500ms毎に送信している。
応答時間が2byte程度で事足りそうだったので
ID100の1byte目に応答時間の上位バイト。
ID100の2byte目に応答時間の下位バイトをセットしている。
距離の算出は、とりあえずマニュアル通り。

RaspberryPi

まず、下記を実行

sudo ip link set can0 type can bitrate 500000

ソースはこんな感じ。

import RPi.GPIO as GPIO
import can
import time
from struct import *
GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.IN)

bus = can.interface.Bus(channel = 'can0', bustype='socketcan_native', bitrate=500000, canfilters=None)

try:
    while True:
        if not(GPIO.input(25)):
            msg = bus.recv(0)
            if msg:
                duration = (msg.data[0] << 8) & 0xFF00
                duration |= msg.data[1] & 0xFF
                distance = duration // 2
                distance = distance * 340 * 100 / 1000000
                print(hex(duration))
                print(distance)
except KeyboardInterrupt:
     GPIO.cleanup()

簡単な解説

mcp2515のINTピン(割込みピン)をRaspberryPiのGPIO25に繋げているため
GPIO.input(25)で割込み判定を実施。
割り込み時はLowレベルになるので、notで判定しています。
後は、受信したデータをデシリアライズして出力しています。
※今思うと、ID100のみ受け取れるようにしないといけないですね。

実行結果

f:id:Yoshichi:20171002020454p:plain

左がArduinoの送信情報(シリアルモニタ)
右側がRaspberryPi(teraterm)の受信情報。
というわけで無事に取りえたい情報を通信できました。
また、距離センサーに手を近づけると、
それらしい反応を出しているのでやりたいことはできているっぽい。

補足

  • MCP2561は他のサイトでは、MCP2551で紹介されている。

端子の命名が一部変わっているものの、ほぼ同じものと考えて良いっぽい。

  • 紹介した、超音波距離センサモジュールは古いっぽいので

新しいものを買うのを推奨。

メモ

最近は専ら、RaspberryPiを使ってラジコンを作りたいと奮闘中。
上手いこと上記のやりとりをしながら自動停止とかしてみたい。。。

【Raspberry Pi】 Wiiリモコンを繋げる

Python3とcwiidを利用してWiiリモコンをRaspberryPiで
認識させれたのでメモ。

f:id:Yoshichi:20170921014301j:plain

使用したもの

  • RaspberryPi2 (そろそろ3ほすぃ)
  • I-O DATA Bluetoothアダプター Class 2対応 4.0+EDR/LE対応 USBアダプター USB-BT40LE
  • Wiiリモコン

cwiidのインストール

pipではインストールできなかったので。

https://github.com/azzra/python3-wiimote
上記サイトからクローンしてきます。

必要なものが
awk, bison, flex, bluez-libs, python 3.5以上
と指定があるので、それぞれ不足しているものをインストールしていきます。
また、僕の環境ではaclocalがなかったのでautotools-devでインストールします。

sudo apt-get install autotools-dev
sudo apt-get install bison
sudo apt-get install flex
sudo apt-get libcwiid-dev
sudo apt-get install bluetooth
sudo apt-get install bluez-utils

一通り、インストールしたらクローンでとってきたディレクトリ内で
下記コマンドを打つのみ。

sudo aclocal
sudo autoconf
sudo ./configure
sudo make install

何か不足していたら./configureを実行した際に
エラーメッセージの内容を読んだら気づけるかも。

実行

  1 import cwiid
  2 import time
  3
  4 wii = cwiid.Wiimote()
  5 time.sleep(3)
  6 wii.rpt_mode = cwiid.RPT_BTN
  7 while True:
  8     buttons = wii.state['buttons']
  9     print(buttons)

を実行する

Wiiリモコンのsyncボタンを押して10秒経たないぐらい待つと
認識されて、ボタンに対応した値が返ってくる。

f:id:Yoshichi:20170921015449j:plain

サンプルはこの辺を参考にするとよい。

Wiimote/wiimote.py at master · the-raspberry-pi-guy/Wiimote · GitHub

雑記

いやー、CANコントローラ1つ壊してしまって
CANで遊べなくなってしまった。

残念無念。

そういえば、以前MCP2551が見つからないと言っていたが
秋月にMCP2561というCANトランシーバがあるので
そちらを使用できるっぽい。今度買う。

次回のPython東海ネタはCANの話にしようかと思ったんだけど
壊してしまったし、今月はこれ以上色々買うわけにもいかないし
どうするかなーって思いながらラズコンを少しずつ作っているという。

f:id:Yoshichi:20170917054953j:plain

とりあえず、Bluetoothを繋げてアンドロイドから操作したい。。。

【Raspberry Pi】python-canを使ってCANで遊ぶ

引き続き、CANのお話。

今回は、Pythonモジュールのpython-canを利用して
外部CANコントローラ、レシーバなしで遊んでみたメモです。
※詳細ではなく、とりあえず動かせる程度のものをメモ。


f:id:Yoshichi:20170831232852j:plain

python-can

https://python-can.readthedocs.io/en/latest/python-can — python-can 2.0.0-alpha.2 documentation

PythonでCANを触ることができるようになる。
BusのInterfaceは色々揃ってて、企業でよく使われていそうなVector等も対応しているっぽい。
普段は、"socketcan_native"を使用すればよい思われます。

インストール

$ pip3 install python-can

Viertualを使ったテストコード

ドキュメントからprint文以外、そのまま持ってきています。

import can

bus1 = can.interface.Bus('test', bustype='virtual')
bus2 = can.interface.Bus('test', bustype='virtual')

msg1 = can.Message(arbitration_id=0xabcde, data=[1,2,3])
bus1.send(msg1)
msg2 = bus2.recv()
print(msg2)
assert msg1 == msg2

bustypeをvirtualとしていますが、virtualを指定すると
仮想環境上で送受信のやり取りが可能になり
CANコントローラなしで、動かすことができます。
ただし、上記は同一のPythonプログラム上でしか
動かせないっぽいので、ファイルを分けて
送受信させたい場合、上記だけではできないっぽいです。

canserverとRemote interface

python-canにはRemote interfaceというものがあり、
これを利用すると、canserverを介して複数のプログラム上で通信が可能になるようです。

canserverのインストール

https://github.com/hardbyte/python-can
からクローンしてきます。
落としてきたフォルダに移動し下記を実行。

$ python3 setup.py develop

※ちなみにWindowsの場合、ファイルを直接Python環境に放り込むのが吉

canserverを立ち上げる

上記、同フォルダにあるcanフォルダに移動し

$ python3 server.py -H 127.0.0.1 -p 54701 -i virtual -b 500000

を実行してサーバーを立ち上げます。

f:id:Yoshichi:20170907024251j:plain

canserverを介して送受信させる

受信用のファイルを用意します。
recve.py

import can
bus = can.interface.Bus('127.0.0.1:54701', bustype='remote', biterate=500000 , canfilters=None)
msg2 = bus.recv()
print(msg2)

次に送信用のファイルを要します。
send.py

import can
bus = can.interface.Bus('127.0.0.1:54701', bustype='remote', bitrate=500000, canfilters=None)
msg1 = can.Message(arbitration_id=0xabcde, data=[1,2,3])
bus.send(msg1)

後は、別なターミナル上でそれぞれ

ターミナル1
$ python3 recve.py

ターミナル2
$ python3 send.py

を実行すると、

サーバー上の画面

f:id:Yoshichi:20170907023957j:plain

recve.py上の画面

f:id:Yoshichi:20170907024033j:plain

てな感じで、ターミナル2で送ったデータが
無事に、ターミナル1に届きました。

次やりたいこと

  • python-canを利用したMCP2515とのやりとり
  • python-canをもうちょっと詳しく

【RaspberryPi】 RaspberryPiとArduinoをCAN通信させた

RaspberryPiとArduinoをCAN通信させたいと思いやってみた。
ので、とりあえずメモ。

CANとは

Controller Area Networkの略で
主に自動車で使用されている通信規格。

Controller Area Network - Wikipedia

準備

  • RaspberryPi2
  • Arduino Uno
  • Rasbee オリジナル MCP2515 CAN バス モジュール TJA1050 レシーバーSPIモジュール Arduinoのための AVR (2個)

f:id:Yoshichi:20170831232852j:plain

MCP2515 TJA1050

本来は、MCP2551、MCP2515を単品買いたいところだったのですが
MCP2551がAmazonや秋月になかったので
諦めてMCP2551ではありませんがMCP2515がくっ付いていて
セットになっているものを買いました。
(安いです。。。)

CANコントローラのMCP2515は、3V,5Vどちらでも動作可能ですが
CANトランシーバのTJA1050は、5Vで動作します。
また、RaspberryPiのGPIO端子は3Vであるため
5Vを突っ込んでも動作しないか壊す可能性があります。
そのため、RaspberryPiで使用するCANモジュールでは
MCP2515のVCCを3Vにして、他の部品は電圧5Vで動作するようにします。
f:id:Yoshichi:20170905000423j:plain

写真では見にくいですが、MCP2515のVCCは基盤に触れないよう切ってあります。
で、ジャンパワイヤーで3Vの電圧をかけています。

Arduinoで使用する方はそのままでOK。

参考

こちらの方を参考にしました。
Raspberry Pi CAN通信 (MCP2515 TJA1050 CAN Bus Module) - Qiita

また基盤の裏を改造するのも手のようだ。。。
[quick-guide] CAN bus on raspberry pi with MCP2515

RaspberryPi側の設定

SPIの設定

SPIを使用して、通信をやりとりするためSPIを有効にします。

$ raspi-config

SPIを有効にする。

/boot/config.txt

# Added for SPI-mcp2515
dtparam=spi=on
dtoverlay=spi-bcm2835-overlay
dtoverlay=mcp2515-can0-overlay,oscillator=1600000,interrupt=25

に設定して再起動。

CAN通信確認用ソフトのインストール

CAN Utils

$ sudo apt-get install autoconf git libtool
$ git clone https://github.com/linux-can/can-utils.git
$ cd can-utils
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install

確認方法などは下記がとても参考なる。
OBD2(CAN)で自動車と通信(ソフト編) | Make.

補足

oscillatorは発振子の周波数を設定するっぽい。
今回買った、CAN バス モジュールについてる発振子の周波数は8MHZなので
最初、8MHZ設定してみたんだけどArduino側でCAN送信する際に、
16MHZ設定しないと送信できなかったため16MHZ設定。
なぜ8MHZで通信できなくて、16MHZなら可能なのかわからない。
この辺勉強不足orz

Arduino側の設定

ライブラリのインストール

mcp_can.hをインストール
※ライブラリにコピーすればよい。

CAN バス モジュールとの接続

INT - Pin2
SCK - Pin13
Si - Pin11
So - Pin12
Cs - Pin10
GND - GND
VCC - 5V

送信コードは
exampleに入っている"CAN_send.ino"を書き込む。
ちなみに、内容は
CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ)はそのままで
ID123の8バイトデータ
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
を送信しているだけです。

実行

RaspberryPiで

$ sudo ip link set can0 type can bitrate 500000
$ candump can0

Arduinoに電源投入する。

f:id:Yoshichi:20170901024537j:plain

無事に、Arduinoから送信したデータを
RaspberryPi上で受信することができました。

f:id:Yoshichi:20170905013403j:plain

次やりたいこと

【RaspberryPi】 Pyenvの導入

RaspberryPiにPyenvを入れる。

現在の環境

OS:Raspbian 7.11

Pyenv

Pyenvとは複数バージョンのPythonを簡単に切り替えられるツール。

Pyenvの導入

下記からクローン

git clone https://github.com/yyuu/pyenv.git ~/.pyenv

~/.bash_profileに以下を書き込む

export PYENV_ROOT=$HOME/.pyenv
export PATH=$PYENV_ROOT/bin:$PATH
eval "$(pyenv init -)"

反映

source ~/.bash_profile

使用方法

インストール

pyenv install 3.5.0

アンインストールはuninstall

設定

pyenv global 3.5.0