Miho's Memory

組込みとアートとまぜまぜ

AI自動運転ちびラジコンカー ~ 製作~

AI自動運転ちびラジコンカー ~ 製作~

以前 AI自動運転”でかっ!”ラジコンカー をつくりました ^^#

https://miho-diary.hatenablog.com/entry/2019/12/24/023430

今回は 手のひらサイズの AI自動運転ちびラジコンカー を作ろうと思います ^^#

◆ ハードウェア

【車体】
Fabo で数年前に購入済!2台!!

GeckoCar – FaBo Store

Gecko ただいま絶賛アップデート中! 

※ 大きくてもいいからラジコンカーを持っていたら、コントローラーとPCA9685 だけ買えばいいよ!

【Raspberrry Pi】
    車2台分
    ● Raspberry Pi 4 Model B(4GB RAM)
    ● Raspberry Pi 3 Model B v1.2

【無線ゲームコントローラ
    ロジクールF710

【カメラ】
    RaspberryPiカメラV1 広角レンズ

【micro SD】
    32MByte

【モバイルバッテリー】
    Raspberry Pi へ電源供給

【組み立て完成図】

           

   

      

 -----  と、今回は 車の組み立ては終わってる前提で、ここからが本題!  -----

参考にするのは、

CQ出版社 インターフェース 2023年3月号 記事』 

AIがピッタリ…人間の操作よりも安定して好タイム!学習データも作りやすい

自動運転ラジコン・カーの製作

https://interface.cqpub.co.jp/wp-content/uploads/if2303_151.pdf

◆ ソフトウェアのインストール

【事前準備 インストール】
    ● Raspberry Pi Imager:使用したバージョン  1.7.3
    ● RealVNC Viewer
    ● WinSCP
    ● NetworkScanner
    ● TeraTerm

Raspberry Pi OS セットアップ】

http://ma2.la.coocan.jp/AI_Driver/tt02/view.cgi?fname=install.txt&fsize=5

1. Raspberry Pi Imager を起動

2. 「OS を選ぶ」/ Debian Bullseye の Full でも Lite でもないやつ を 選択
   
    Raspberry Pi OS (other) を 選択
   
    Raspberry Pi OS (Legacy, 64-bit)を選択
   
         
3. 「詳細な設定」/ 画面右下の ギヤマーク を選択
   

   

   

   

4. ストレージを選択して書き込み!!

--- 書き込み終了! ---

5. SSH を有効にする
   1) Raspberrry Pi OS を書き込んだ micro SD を もう一度カードリーダーに
   2) 中身無し、拡張子無し、ファイル名 ssh のファイルを作成
   3) Raspberry Pi OSをインストールしたmicro SDカードのbootディレクトリ直下に、2) で作成した空の“ssh”ファイルをドラッグアンドドロップで置く
       というのも、bootディレクトリの下でファイルを作成しようとすると固まったからw
   4) NetworkScanner を起動し、現在のネットワーク環境を見ておく
   5) Raspberrry Pi に micro SD をセット、電源をいれる
   6) 最初は少し時間がかかるが、ある程度したら 再度 NetworkScanner を起動
       増えたものが Raspberrry Pi

6. TeraTerm で raspberrypi.local で接続!できた!

    サイトを見ながら。。。
    http://ma2.la.coocan.jp/AI_Driver/roba/view.cgi?fname=install.txt&fsize=5

7. Raspberrry Pi OS アップデート & アップグレード
    1) sudo apt-get update
    2) sudo apt-get upgrade

8. raspi-config による設定
    1) sudo raspi-config 
    2) 以下の項目を設定
        ・ 2 Display Options
                ⇒ D5 VNC Resolution
                     ⇒ 1024×768
                ⇒ D6 Composite→V2
                     ⇒ Yes
        ・ 3 Interface Options
                ⇒ I1 Legacy Camera
                     ⇒ Yes
                ⇒ I3 VNC
                     ⇒ Yes
        ・ 6 Advanced Options
                ⇒ A1 Expand Filesystem
                     ⇒ OK

9. python の仮想環境を作成
    1) python3 -m venv --system-site-packages ~/venv
    2) source ~/venv/bin/activate

10. ライブラリをインストール
    1) pip install --upgrade pip
    2) pip install tensorflow
    3) pip install tensorflow_io
    4) pip install tflite-runtime
    5) pip install opencv-python

    ※ 長い時があるけど、じっとガマン!

11. 作業フォルダを作成してファイルをダウンロード
    1) mkdir ~/AI_Driver
    2) cd ~/AI_Driver
    3) wget http://ma2.la.coocan.jp/AI_Driver/roba/download/aidriver.py
    4) wget http://ma2.la.coocan.jp/AI_Driver/roba/download/cfg.py
    5) wget http://ma2.la.coocan.jp/AI_Driver/roba/download/movie.py

12. WinSCP を 使って ~/.bashrc の最後に以下3行を追加
      source ~/venv/bin/activate
      cd ~/AI_Driver
      sudo pigpiod
     
      ※ WinSCP の 環境設定を変更:パネル - 隠しファイルを表示する

13. exit して再ログイン
      ※ exit すると、ヒストリ が溜まっていく / bash_history ファイルが更新される

14. 無線ゲームコントローラのドングルを RaspberryPi に挿す

15. RealVNC Viewer を起動し接続:raspberrypi.local または IPアドレス

16. コンソールを起動し、
      1) カメラ認識 の確認
          ls /dev
          video0  があれば OK!
      2) ゲームコントローラ認識 の確認
          ls /dev/input
          js0  があれば joystick OK!
      3) カメラとゲームコントローラの動作確認
          python aidriver.py 
          ※ 時間かかるけどガマン!!
         

 

【ためしてみよう!】

★ コントローラの赤ボタンを押すと画像が保存されるぞ!

     ⇒ 画面に枚数が表示される! 再 赤ボタン で止まる

     ⇒ WinSCP で AI_Drive フォルダを見ると log フォルダがあり .jpg でいっぱい!

★ 「Qキー」でプログラムが停止するぞ!

     ⇒ WinSCP で AI_Drive フォルダを見ると log フォルダがあり .csv あり!

★ 「ctrキー + Cキー」で止める!

⇒ .jgp(写真) と .csv(サーボやESC情報)を  TensorFlow で学習する

 

まだ、サーボはつないでないので、次回は、

● サーボの確認 & 手動走行

● 教示データ作成

● AI の学習/深層学習(google Colaboratory, TensorFlow)

 

そして、以前作ったモノもまた活躍するときがやってきた ^^#

【minion バスに大変身】

   

   

【minion カラーの可愛いト音記号のコース ^^#

   

【車窓から ^^#】

   


最後までお付き合い下さりありがとうございました ^^#

【鬼滅の刃】栗花落カナヲの光る刀の作り方

鬼滅の刃】栗花落カナヲの光る刃の作り方**

Merry Christmas!!

この記事は SeeedUG アドベントカレンダー2021の24日目のエントリになります。
サイトはこちら https://qiita.com/advent-calendar/2021/seeed_ug
はじめての SeeedUG への参加です ^^#
技術ガッツリのお話は、無理 ^^; なので、Seeeduino XIAO を使ってつくった、今流行りのアニメの刃を作ったのでそれを紹介したいと思います ^^#

きっと誰しもあっちいけ~思う鬼(人)がいるハズ。
そんなあなたと一緒に鬼退治用アイテムを一緒に創りたいと思います ^^#

そのアイテムは “刃” ^^

簡単に作りましょう!在り物を上手に使います。
さて、ダイソーの光る刀(\200)円を用意します。
ダイソー刀もすごいんですけど、上弦の鬼はヤレマセン。今回は上弦の鬼用の刀を創ります。

そこで、ダイソー刀の解体新書。
と、そのまえに!ダイソーオリジナル はこんな光り方です ^^#

で、解体新書。
いたってシンプル。LEDに至っては天才的なセンスです!
そしてとても綺麗です!
こんな感じ ↓↓

さて、この美しくデザインされた筐体に潜む精神の核たちをすっかり入れ替えてしまいましょう!

新しく精神の核になるモノ!
ダイソーの光る刀 \200
・ Seeeduino XIAO 1個
https://www.marutsu.co.jp/pc/i/2191155/
https://wiki.seeedstudio.com/jp/Seeeduino-XIAO/
・ 丸っ子ユニバーサル基板 1個
https://akizukidenshi.com/catalog/g/gP-09674/
・ タクト/モーメンタリスイッチ 1個
https://akizukidenshi.com/catalog/g/gP-03651/
・ ロックスイッチ 1個
https://www.aitendo.com/product/3600
・ Novonest アドレス指定可能な5V 3PIN RGB LEDライト 1本
https://www.amazon.co.jp/gp/product/B093D266QV/ref=ppx_yo_dt_b_asin_title_o04_s00?ie=UTF8&psc=1

見てください!
こんなにも美しく収まるんです(⋈◍>◡<◍)。✧♡

LEDだってこんなにすっぽり

おまけですが、刃の弧 を意識して、刃の背に小さな穴をあけてそこから針金差し込んで、LEDがすこし弧を描くように押しています。

もともとついてたスイッチ基板を使えるほどできる人じゃないんで、私はそれは使わない(使えないw)。
その代わりに自分が得意な工作の方へ!

今回使用した タクト/モーメンタリスイッチの足は4本だったので、ニッパでに2本に

今回使用しているロックスイッチは、足が両サイドに出たものだったw

ロックスイッチの取り付けは、もともとのスイッチの穴をニッパで切って拡大し、棒ヤスリでこすりながら穴を大きくロックスイッチが収まるように加工します。

【構成図】

【開発環境】

とか


+

今回は VSCode + PlatformIO を使ってみます。

プロジェクト作成の時、選ぶ Board名 はもちろん
Seeeduino XIAO
を選択します。
プロジェクト作成後 platformio.ini がこう↓なっていれば OK です。

つっこんだライブラリは

  • FastLED
  • Button 2
  • Adafruit NeoPixel

ライブラリをつっこんだ後 platformio.ini がこんな↓感じになっていれば OK です。

あとはこんな感じ↓でプログラミングします。

出来上がった刃と出来上がった私がこちら↓

出来上がった刀。それだけでも十分すごいけど、みためDAISOよりかっこよくつくっちゃえ!とデザインを施した。
そしてさらに、子どもたちにそれを見せるとき、もっと彼らが目を光らせるように、自分もなりきりろうと衣装をまとった。
小さい頃、ウルトラマンと一緒に写真を撮った。
あれが、中のお兄さんで胸にラーメンタイマーつけてても写真撮りたいとは思わんわ笑
子どもたちがこういったものに興味を示すために、どこまでどう何を創り込むかはその人次第(*^^*)

光り方はこちら Youtube で↓
鬼滅の刃】栗花落カナヲの光る刃作り方&デモ
youtu.be

ピアノ発表会の演出も是非ご覧ください。子供たちにとってさらに良い想い出になってくれてたらなと思います♪↓
鬼滅の刃】栗花落カナヲの光る刃の舞 in Piano recital
youtu.be

と、最後に、ダイソーノーマル刀では、見た目が寂しい。。。
ということで、ダイソーに売っているスプレーやタミヤの塗料で見た目もカナヲの刃に仕上げました ^^#
他には、炭治郎、善逸、まだ途中の伊之助 刀たちが出来上がってます。

このまましばらく 鬼滅の刃 人気であってほしいなぁ ^^*
もっとどっかに出かけて見せびらかせたい♪

最後までお付き合い下さりありがとうございました ^^#

はじめての F (⋈◍>◡<◍)。✧♡ ~ Pythonプログラム編② の弐~

はじめての F (⋈◍>◡<◍)。✧♡ ~ RasPi編②の弐 ~

さてっ.
RasPi編②の壱 では サンプルプログラムを実行して、FRAMメモリの読み書きができてそうか?ってのを波形をみて確認しました。
そう
波形は信号の『素顔💛』です ^^#

せっかくなので、データシートのすべてのコマンドを実行してみようと思います。
ここは、FRAM波形ワールドなページ♪

引き続き、波形を見るにはおうちにあった LabTool を使います。

Random Readコマンド

FRAMサンプルプログラム!
【fram_main2.py】

import os
import time
import sys
import time
import random 

from i2c_fram2 import *

if __name__ == '__main__':

    print(" HELLO FRAM ")
    print("----------------- ")
    fram = SDL_I2CFRAM(addr = 0x50)

    print("- WRITE - ")
    fram.write8(7,34)
    print("WRITE FINISH")

    print("- READ - ")
    fram.read8(7)
    print("READ FINISH")

    print("---framEND---")

【i2c_fram2.py】

import time
import smbus2
import sys
from decimal import *

from datetime import datetime

class SDL_I2CFRAM():

    ###########################
    # SDL_I2CFRAM Code
    ###########################
    def __init__(self, twi=1, addr=0x50):
        self._bus = smbus2.SMBus(twi)
        self._addr = addr

    def write8(self, address, data):
        w = smbus2.i2c_msg.write(self._addr, [address>>8, address%256, data]) 
        self._bus.i2c_rdwr(w)

    def read8(self, address):
        w = smbus2.i2c_msg.write(self._addr, [address>>8, address%256])    # r1
        r = smbus2.i2c_msg.read(self._addr, 1)    # r2
        self._bus.i2c_rdwr(w,r)    # r3
        print(list(r)[0])

では、プログラムを実行しておきましょう!

(env) pi@Donkey-Miho:~/miho/blog $ python fram_main2.py
 HELLO FRAM
-----------------
- WRITE -
WRITE FINISH
- READ -
34
READ FINISH
---framEND---

波形はこれ ↓↓

f:id:MihoN:20210209200651p:plain

つぎ!
■ Page Writeコマンド

FRAMサンプルプログラム!
【fram_main3.py】

import os
import time
import sys
import time
import random 

from i2c_fram3 import *

if __name__ == '__main__':
    fram = SDL_I2CFRAM(addr = 0x50)

    print(" HELLO FRAM ")
    print("----------------- ")

    print("- WRITE - ")
    address =0x00
    data = [1, 2, 3, 4, 5, 6, 7, 8]
    fram.write_block(address, data)
    print("WRITE FINISH")

# With LabTool
    print("- MemDump - ")
    fram.mem_dump()

    print("---framEND---")

【i2c_fram3.py】

import time
import smbus2
import sys
from decimal import *
from datetime import datetime

class SDL_I2CFRAM():

    ###########################
    # SDL_I2CFRAM Code
    ###########################
    def __init__(self, twi=1, addr=0x50):
        self._bus = smbus2.SMBus(twi)
        self._addr = addr

    def write_block(self, address, data):
        cnt_len = len(data)
        for y in range(0, cnt_len):
            print("data[%d] = %d" %(y, data[y]))
        print("---")
        new_data = [address%256] + data
        cnt_len = len(new_data)
        for y in range(0, cnt_len):
            print("new_data[%d] = %d" %(y, new_data[y]))
        self._bus.write_i2c_block_data(self._addr,address>>8, new_data)  # r1

    def mem_dump(self):
        w = smbus2.i2c_msg.write(self._addr, [0x00>>8, 0x00%256]) 
        self._bus.i2c_rdwr(w)
        for x in range(0,10):
            r = smbus2.i2c_msg.read(self._addr, 1)
            self._bus.i2c_rdwr(r)
            print("data = 0x%x " % (list(r)[0]))

では、プログラムを実行しておきましょう!

(env) pi@Donkey-Miho:~/miho/blog $ python fram_main3.py
 HELLO FRAM
-----------------
- WRITE -
WRITE FINISH
- MemDump -
data = 0x1
data = 0x2
data = 0x3
data = 0x4
data = 0x5
data = 0x6
data = 0x7
data = 0x8
data = 0x6c
data = 0x6d
---framEND---

※ 出力結果 0x6c や 0x6d の部分は、FRAMに書かれているデータが違えば変わってきます

波形はこれ ↓↓
f:id:MihoN:20210209195624p:plain

つぎ!
■ Sequential Readコマンド

FRAMサンプルプログラム!
【fram_main4.py】

import os
import time
import sys
import time
import random 

from i2c_fram4 import *

if __name__ == '__main__':
    fram = SDL_I2CFRAM(addr = 0x50)

    print(" HELLO FRAM ")
    print("----------------- ")

    print("- WRITE - ")
    address =0x00
    data = [1, 2, 3, 4, 5, 6, 7, 8]
    fram.write_block(address, data)
    print("WRITE FINISH")

    print("- READ - ")
    fram.read_block(0x00, 3)
    print("READ FINISH")

# With LabTool
    print("- MemDump - ")
    fram.mem_dump()

    print("---framEND---")

【i2c_fram4.py】

import time
import smbus2
import sys
from decimal import *
from datetime import datetime

class SDL_I2CFRAM():

    ###########################
    # SDL_I2CFRAM Code
    ###########################
    def __init__(self, twi=1, addr=0x50):
        self._bus = smbus2.SMBus(twi)
        self._addr = addr

    def write_block(self, address, data):
        cnt_len = len(data)
        for y in range(0, cnt_len):
            print("data[%d] = %d" %(y, data[y]))
        print("---")
        new_data = [address%256] + data
        cnt_len = len(new_data)
        for y in range(0, cnt_len):
            print("new_data[%d] = %d" %(y, new_data[y]))
        self._bus.write_i2c_block_data(self._addr,address>>8, new_data)

    def read_block(self, address, sequence):
        w = smbus2.i2c_msg.write(self._addr, [address>>8, address%256])   # r1
        r = smbus2.i2c_msg.read(self._addr, sequence)   # r2
        self._bus.i2c_rdwr(w,r)   # r3
        for x in range(0, sequence):
            print("data = 0x%x" % (list(r)[x]))

    def mem_dump(self):
        w = smbus2.i2c_msg.write(self._addr, [0x00>>8, 0x00%256]) 
        self._bus.i2c_rdwr(w)
        for x in range(0,10):
            r = smbus2.i2c_msg.read(self._addr, 1)
            self._bus.i2c_rdwr(r)
            print("data = 0x%x " % (list(r)[0]))

では、プログラムを実行しておきましょう!

(env) pi@Donkey-Miho:~/miho/blog $ python fram_main4.py
 HELLO FRAM
-----------------
- WRITE -
WRITE FINISH
- READ -
data = 0x1
data = 0x2
data = 0x3
READ FINISH
- MemDump -
data = 0x1
data = 0x2
data = 0x3
data = 0x4
data = 0x5
data = 0x6
data = 0x7
data = 0x8
data = 0x6c
data = 0x6d
---framEND---

※ 出力結果 0x6c や 0x6d の部分は、FRAMに書かれているデータが違えば変わってきます

波形はこれ ↓↓
f:id:MihoN:20210212110620p:plain

さいご!
■ Device IDコマンド

FRAMサンプルプログラム!
【fram_main5.py】

import os
import time
import sys
import time

from i2c_fram5 import *

if __name__ == '__main__':

    print(" HELLO FRAM ")
    print("----------------- ")
    fram = SDL_I2CFRAM(addr = 0x50)

    print("- DeviceID - ")
    fram.read_device_id()
    print("DeviceID FINISH")

    print("---framEND---")

【I2C_fram5.py】

import time
import smbus2
import sys

from decimal import *
from datetime import datetime

class SDL_I2CFRAM():

    ###########################
    # SDL_I2CFRAM Code
    ###########################
    def __init__(self, twi=1, addr=0x50):
        self._bus = smbus2.SMBus(twi)
        self._addr = addr

    def read_device_id(self):
        w = smbus2.i2c_msg.write(0xf8//2, [0xa0])   # D1
        r = smbus2.i2c_msg.read(0xf9//2, 3)   # D2
        self._bus.i2c_rdwr(w, r)   # D3
        print(list(r)[0],list(r)[1],list(r)[2])

では、プログラムを実行しておきましょう!

(env) pi@Donkey-Miho:~/miho/blog $ python fram_main_DeviceID.py
 HELLO FRAM
-----------------
- DeviceID -
0 165 16
DeviceID FINISH
---framEND---

波形はこれ ↓↓
f:id:MihoN:20210209202822p:plain
f:id:MihoN:20210209202834p:plain:w500

smbus2 を使った FRAM MB85RC256V の データシートのコマンドを全部実行できました!
API の仕様がうまく分ってなくても ^^; 波形を見るとこうなってるから、こう設定しよう!とか、いったい何がどうなって、どうなってるのかわかります ^^#
お手軽ロジアナで十分波形を見れました!
次は、SPI の FRAM の 波形を見てみたいなと思います ^^#

はじめての F (⋈◍>◡<◍)。✧♡ ~ Pythonプログラム編② の壱~

はじめての F (⋈◍>◡<◍)。✧♡ ~ RasPi編②の壱 ~

さてっ.
RasPi編① では サンプルプログラムを実行して、FRAMメモリの読み書きができてそう、ってところまで確認しました。

でも、なんとなく不安です。。。本当にコマンドはちゃんと実行されているのだろうか。。。
不安なら安心しましょう!そう!波形を見ればいいんです!!

波形を見るにはおうちにあった LabTool を使います。

ではさっそく ^^# っと、その前に
I2C について一緒に簡単に勉強しておきましょう♪

今回LobToolにつながれるFRAMはI2Cインターフェースを持つFRAMデバイスです。


■ なになに? I2C

I2C は Philips社(現在のNXP社)によって開発されたシンプルなシリアルバスです。
I2C は FRAMとMCU 間をシンプルにつなぎ、シリアル通信を提供します。
I2C は マスターがスレーブデバイスとの通信を開始する同期式プロトコルです。
その、I2Cプロトコルはデータ転送速度(クロック周波数)であるクロックをマスターが出す、マスター/スレーブ通信です。

Master                       Slave
MCU      ←   Data  → FRAM
            -- Clock →

双方向バスなので、マスターはスレーブへの書き込みと、スレーブからの読み取りが可能です。
また、その双方向のシリアルバスは、シリアルクロック(SCL)とシリアルデータ(SDA)の2つです。

I2Cバス:
・必要なバスラインは2本だけ!シリアル・データライン(SDA)とシリアル・クロックライン(SCL)
・バスに接続されている各デバイスを固有のアドレスで指定できる!
・通信は常にシンプルな、マスタ/スレーブ!
・複数のマスタが同時にデータ転送を開始した場合のデータの破損を防止する、衝突検出と調停機能を備える!
・ I2CではSCLの立ち上がりエッジ時にデータが読み込まれる!また、SDAの出力が遷移するのはSCLの立ち下がりエッジ時!

 
■ MB85RC256V I2C FRAM で確認してみよう!

以下は、同じI2Cバスに3つのFRAMを接続した例(マスタ1個、スレーブ(FRAM)3個)です。
f:id:MihoN:20200801224715p:plain
f:id:MihoN:20201112150159p:plain
プルアップ抵抗は I2C FRAM が正しく通信するために必要です。これは、I2Cプロトコルが、SCLおよびSDAバスラインがオープンドレインまたはオープンコレクタであることを前提としているためです。


■ I2C通信の波形からI2C通信を理解する

LabTool を使って波形を見てみます。
f:id:MihoN:20201127185227j:plain:w300

まず、LabTool を パソコンに接続し、LabToolの画面を立ち上げます。
立ち上がったら
” Sample Rate を 50MHz ” にし、” Add Signal ” を行います。設定は以下の図を参考に。
f:id:MihoN:20201127192656p:plain:w400

OK押下で以下の画面が出てきます。
SCL が D0 ってのと、 SDA が D1 ってのを覚えてOK押下。
f:id:MihoN:20201127192919p:plain:w200

最後に、D0 と D1 の トリガは立下りにします。
団子みたいな絵の Continuous capture を有効にします。
なお、D0 D1 I2C ってやつの順番は上下入れ替えできます。
掴んで動かしてみて ^^
f:id:MihoN:20201127193752p:plain:w200

次は、LabTool と FRAM を接続します。
前回の『はじめての F (⋈◍>◡<◍)。✧♡ ~ RasPi編① ~』を参考に、SCL、SDA、GNDの足を確認してね。
こんな感じ。
f:id:MihoN:20201127194428p:plain:w400
f:id:MihoN:20201127194444j:plain:w300

前回の『はじめての F (⋈◍>◡<◍)。✧♡ ~ RasPi編① ~』のプログラムを確認します!
分かりやすくするために、

RasPi編① で紹介したFRAMサンプルプログラム の fram_main.py の一部を少し変えてみます。
value = x +100 ※100を足しておきます 特に意味はないです ^^;
繰り返し文は 2回繰り返しにします。
あと、プログラムをシンプルに、print文も削除します。

FRAMサンプルプログラム!
【fram_main1.py】

import sys
from i2c_fram1 import *

if __name__ == '__main__':

    print(" HELLO FRAM ")
    print("----------------- ")
    fram = SDL_I2CFRAM(addr = 0x50)
    for x in range(0,2):
        value = x + 100
        fram.write8(x,value)
    print("---------")
    for x in range(0,2):
        fram.read8(x)  
    print("---framEND---")

【i2c_fram1.py】

import smbus2
import sys
from decimal import *

class SDL_I2CFRAM():

    def __init__(self, twi=1, addr=0x50):
        self._bus = smbus2.SMBus(twi)
        self._addr = addr

    def write8(self, address, data):
        print("addr =0x%x address = 0x%x data = 0x%x  " % (self._addr, address, data))
        self._bus.write_i2c_block_data(self._addr,address>>8,[address%256, data])     # w1

    def read8(self, address):
        self._bus.write_i2c_block_data(self._addr,address>>8,[address%256])              # r1
        returndata = self._bus.read_byte(self._addr)                                                      # r2
        print("addr = 0x%x address = 0x%x %i returndata = 0x%x " 
                 % (self._addr, address, address, returndata))
        return returndata

では、プログラムを実行しておきましょう!

(env) pi@Donkey-Miho:~/miho/blog $ python3 fram_main1.py
 HELLO FRAM
-----------------
addr =0x50 address = 0x0 data = 0x64
addr =0x50 address = 0x1 data = 0x65
---------
addr = 0x50 address = 0x0 0 returndata = 0x64
addr = 0x50 address = 0x1 1 returndata = 0x65
---framEND---

そして、そう!LabTool をみて!
波形がみえます。右にスクロールすれば5つ分の波形が見えてきます。
FRAMメモリへのデータ書き込みの様子が波形で確認できました!

f:id:MihoN:20210115205402p:plain

最初の波形を取り上げて

f:id:MihoN:20210115205504p:plain

波形について少し見てみましょう!
波形のアタマは...

f:id:MihoN:20210221214103p:plain

続きからオシリは...

f:id:MihoN:20210221214122p:plain

データシートの説明とも重ねてみましょう。

f:id:MihoN:20210213165645p:plain

データシートの Byte Write コマンドだ!

Byte Writeコマンドは、I2Cfram1.py の #w1 の1文が実行されたときの波形になります。
実行結果を載せときます これ ↓↓
■ Byte Writeコマンド
f:id:MihoN:20210209174931p:plain

つづけて # r1 , # r2 が実行されたときの波形をみてみましょう。
実行結果を載せときます これ ↓↓
Random Readコマンド
f:id:MihoN:20210209194704p:plain

調子にのってきたので、smbus2 を使って、データシートの コマンドを実行させてみよう!(次回 RasPi編②の弐 に続く)

とりあえず、これをやって分かったこと!
「ちゃんとコマンド実行されてるのかなぁ...」と思う時には、こうやって波形を見たらいいんですね!
My オシロを持ってたり、「波形!波形!」と言って、なにかあるとすぐに波形を見る方たちの気持ちが、ちょっとわかった瞬間でした(笑)

波形は信号の『素顔』💛

はじめての F (⋈◍>◡<◍)。✧♡ ~ Pythonプログラム編① ~

はじめての F (⋈◍>◡<◍)。✧♡ ~ RasPi編① ~

さ.
今回は 2019年の Donkey Car / AI Car に FRAM を載せたいと思います ^^#
ただ...使い道はこれから ^^; でも ゆくゆく Donkey Car / AI Car の中で使っていきたいので、Python3 で動くこと!
そして、今回はちゃんとコマンドが送れてるのかなど、LabTool を使って波形を見ようと思います。

ではさっそく
2017年 の はじめての F (⋈◍>◡<◍)。✧♡ ~ ハードウェア編 ~
http://miho-diary.hatenablog.com/entry/2017/05/08/120918
を参考に、SOP8 FRAM Device(今回は I2C FRAM) をユニバーサル基板(RasPi Zero ユニバーサル基板)に載せましょう♪

準備!

■ 用意するものっ

(A)
・SOP8 DIP 変換基板 金フラッシュ(9枚入り)

http://akizukidenshi.com/catalog/g/gP-05154/

・連結ソケット(両端オスピン)8P

http://akizukidenshi.com/catalog/g/gP-00264/

・FRAM(今回は MB85RC256V)

https://www.chip1stop.com/view/searchResult/SearchResultTop?keyword=MB85RC256V&partSameFlg=false


(B)
・丸ピンICソケット(8P)

http://akizukidenshi.com/catalog/g/gP-00035/

・RaspberryPi Zero 用ユニバーサル基板

http://akizukidenshi.com/catalog/g/gP-14031/


(C)
※ 次回②で使うことになりそうです
・LabTool

https://www.embeddedartists.com/products/labtool/

・LabTool専用エンクロージャ:なくてもいいよ

https://shop.emergeplus.jp/labtool/



(A) は
『はじめての F (⋈◍>◡<◍)。✧♡ ~ ハードウェア編 ~』を参考に、FRAMをユニバーサル基板で使えるようにしよう!

f:id:MihoN:20200726150136p:plain

【完成図:変換基板に搭載されたFRAM】

(B) では、
(A) でできたFRAMを RaspberryPi Zero用ユニバーサル基板に載せていきます。そのまま、Zero基板にハンダしてもいいんですが、せっかくなので、抜き差しでFRAMを取替っこ出来るようにしましょう!
ということで、丸ピンソケットIC を Zero基板にハンダづけすることにします!

f:id:MihoN:20200726151423p:plain

【完成図:Zero基板にFRAM搭載】


完成図は RasPi に Zero基板を搭載してしまってますが、搭載する前に、FRAMの配線を行わなければいけません。今回は I2C のFRAMです。
接続するピンは4つ。ピンの足に色付きの丸印がついているピンが対象です。

f:id:MihoN:20200726153820p:plain

【図:FRAMだと、どのピンが対象なの?】


でも、今回FRAMは変換基板に載せているので、変換基板のピン/足が対象です。

f:id:MihoN:20200726160044p:plain

【図:変換基板だと、どのピンが対象なの?】


変換基板の ピン/足 につけた色付きの丸印の色と、RasPiピン配 につけた色付きの丸印の色をつなぐように配線しよう!
配線が終わったら、Zero基板はRasPiの40ピンにぶすっと挿しておきます。

補足:
端子 A0~A2 について、今回は GND につないでも、つながなくても大丈夫だよ。

以下、データシートの一部抜粋。

f:id:MihoN:20200801224715p:plain

【図:端子機能説明 データシートの一部抜粋】


FRAMは認識されるかな?RasPiに電源を入れましょう!
ターミナルソフトで接続し、i2cdetectコマンドで I2Cバス一覧 および それらのアドレスを確認します。

FRAMがいないとき

(env) pi@Donkey-Miho:~ $ sudo i2cdetect -y 1

0 1 2 3 4 5 6 7 8 9 a b c d e f

00: -- -- -- -- -- -- -- -- -- -- -- -- --

10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

70: 70 -- -- -- -- -- -- --

FRAMがいるとき

(env) pi@Donkey-Miho:~ $ sudo i2cdetect -y 1

0 1 2 3 4 5 6 7 8 9 a b c d e f

00: -- -- -- -- -- -- -- -- -- -- -- -- --

10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

70: 70 -- -- -- -- -- -- --

FRAMは 0x50 に違いない!
じゃFRAMメモリへのデータ書き込み、読み出しを試してみよう!
今回は smbus2 を使ってみます。
https://pypi.org/project/smbus2/

別途インストールが必要です。インストールしましょう!

$ pip install smbus2


サンプルプログラムはここのサイトのソースを参考にさせていただきます。
https://www.raspberrypi.org/forums/viewtopic.php?t=209937

https://github.com/switchdoclabs/SDL_Pi_FRAM

FRAMサンプルプログラム!
【fram_main.py】

#!/usr/bin/env python3

import sys
from I2Cfram import *


if __name__ == '__main__':

    print(" HELLO FRAM ")
    print("----------------- ")
    fram = SDL_I2CFRAM(addr = 0x50)
    for x in range(0,5):
        value = x
        print("address = %i writing value = %i" %(x,value))
        fram.write8(x,value)
    print("---------")
    print("reading first 10 address")
    for x in range(0,5):
        print("address = %i value = %i" %(x,fram.read8(x)))
    print("---framEND---")

【I2Cfram.py】

#!/usr/bin/env python3

import smbus2
import sys
from decimal import *

class SDL_I2CFRAM():

    def __init__(self, twi=1, addr=0x50):
        self._bus = smbus2.SMBus(twi)
        self._addr = addr

    def write8(self, address, data):
        print("addr =0x%x address = 0x%x data = 0x%x  " % (self._addr, address, data))
        self._bus.write_i2c_block_data(self._addr,address>>8,[address%256, data])

    def read8(self, address):
        self._bus.write_i2c_block_data(self._addr,address>>8,[address%256])
        returndata = self._bus.read_byte(self._addr)
        print("addr = 0x%x address = 0x%x %i returndata = 0x%x " % (self._addr, address, address, returndata))
        return returndata

    def readB(self, adr):
        b = self._bus.read_byte_data(self._addr) 
        return b

【実行結果】
f:id:MihoN:20200728190316p:plain

今回書けなかったので、次回はちゃんとコマンドが送れてるのかなど、LabTool を使って波形を見ようと思います。

美を追求する Donkey Car 💛

2019年夏 Donkey Car / AI Car なるものに出逢った。

f:id:MihoN:20191224014653p:plain

小さい時からずっと組み立てたかったラジコンカー ^^#
そこそこいい値段です。大人のおもちゃ💛です。
ただ、なんだろう…ちっとも心がときめかない…
ディープラーニング機械学習もAIも、ちょっと興味があったのに、だからいい機会だとおもったのに、どうして心がときめかない?

心がときめかない...それは...

f:id:MihoN:20191224015543p:plain

心ときめかないのは、きっとわたしは Art をもう少し欲しがってるんだ
最近では、ARTも技術の一つ^^#

さぁ、美を追求する旅にでよう!

その前に、お風呂に入って綺麗になりましょう💛

f:id:MihoN:20191224020056p:plain

お風呂で綺麗になったら、いよいよ 美 の追求です。
美と言えば、それは お化粧!
ただ、お化粧をするにも準備が必要です。
ベースがとっても大切です ^^#

f:id:MihoN:20191224020545p:plain

ベースをしっかり整えました。
その後はしっかりとカバーをしていきます。今回はとてもカバー力のあるモノを使います。そのためとても匂いが強烈です。それにお化粧を始めると、それは空気中をのびのびと飛び回るのです。
防毒マスクを用意しましょう!

f:id:MihoN:20191224020721p:plain

そうそう。お化粧をするとき、ムラを抑えるのには これ!
5円玉を上手に使うんです!
そして細かいところは、筆を使って描きましょう。

f:id:MihoN:20191224020924p:plain

眉やアイラインも丁寧にね!

f:id:MihoN:20191224021051p:plain

細かい ”美” にも気を配って💛

f:id:MihoN:20191224021139p:plain

できあがった!わたし

f:id:MihoN:20191224021500p:plain

 

綺麗だからってそんなにわたしを見つめないで💛
わたしもあなたを見つめちゃう💛

 


MinionCarWindow TechShop

わたしはもっともっと綺麗になるわよ💛
これからもどんどん綺麗になっていくわたしを見ててネ!

まじめに。
Donkey Car とは 自分でRC Carを組み立てて、まずはリモコンで操縦し ”教師データ” をつくる。その教師データをもとに、TensorFlow で学習させ "学習済みデータ" をつくる。カメラ画像を 推論エンジン (TensorFlow + 学習済みデータ)に渡し推論し、結果を得る。その結果に従った走行をすることで自動運転が実現する。

これから 美 の追求だけじゃなく、そっちもやってくぞー ^^#

micro:bitな彼と合体 #^^#モグモグ

最初に,しばらくとってもバタバタしてて,落ち着いたかと思いきや,アタマガンガン,背中ゾクゾク,手のひらおでこはポッカポカw

なので細かくしっかり書けてなくて,ごめんなさい...
荒いところはぼちぼちと更新していきますのでよろしくお願いします...

 

さて,開始!

ラズパイちゃんとmicro:bitくんは相思相愛の仲.
USBケーブルでつながり,お互いの仲を確認しあえることは,技術書典6でお話しました.

ん? 技術書典6? なんのこと???の方もいると思うので,簡単に先に紹介します.
技術書典6 をご購入いただいた方は,軽く思い出し って感じで見てもらえると嬉しいです.

ラズパイちゃんとmicro:bitくん,お互いがつながる(合体💛する)ことで,いろんな役割を分担でき,それぞれの強みを簡単に生かすことができるんです.
その簡単な合体💛はこんな感じ.

お互いを USB でつないじゃえばいいんです ^^#

f:id:MihoN:20190410230728j:plain

繋げた後,らずぱいちゃんで

pi@raspberrypi:~ $ ls /dev

そうすると,「ttyACM0」というデバイスが見えてきます.

f:id:MihoN:20190410230954p:plain

これがまさに ラズパイちゃん に合体した micro:bit くん なのです ^^#

お互いの心は serial通信 で確かめあえます.
※ 簡単なサンプルは省略.技術書典6 には記載

そこに micro:bitくんのお友達が3人(みんな micro:bit)やってきました.
みんなでなにやら話をしています.

micro:bit①『最近とても物騒な世の中だよね~』
micro:bit②『ほんとそう.いつわる~い人が近づいてくるかわかんないよね』
micro:bit③『こわいこわい』
micro:bit彼④『なんかみんなで人のためになることしない?』
ラズパイちゃん彼女⑤『わる~い人が近づいてきたら,音楽を鳴らして警戒,写真を撮りツイートしてミサイルぶち込んで追っ払おうよ!』
みんな『それいいね!!』『名付けて!「おまえはだれだ! ツイートしちゃうぞ!」』

ということで,それぞれ次のような役割で ”おまえはだれだ! ツイートしちゃうぞ!” をやってみることにしました.さっそくみんなで話をして役割を決めたよ ^^#

micro:bit①:超音波センサーでわる~い人を見張るんだい!
micro:bit②:音楽鳴らして追っ払ってやる!
micro:bit③:ミサイルぶっ放して追っ払ってやる!
micro:bitな彼④:micro:bit①からの知らせを受け,ラズパイちゃん,micro:bit②,micro:bit③に連絡
ラズパイちゃん⑤:micro:bitな彼④からの連絡で,カメラを作動パシャと写メ.ツイッターに写真をほいっ.

f:id:MihoN:20190410233637p:plain

f:id:MihoN:20190410233732p:plain

今回ちょっと時間が足りないので(後日アップデートしていく予定),参考にさせていただいたサイトと,プログラムを貼り付けていきます.
micro:bit 間は無線通信を使いますが,無線グループは 81 です.
ラズパイのパイ(81)^^#

 

micro:bit①:超音波センサーでわる~い人を見張るんだい!
〇 参考にさせていただいたサイト
     https://qiita.com/asondemita/items/718e3da6cb33553257ed
〇 用意したモノ:超音波センサー
     micro:bit用ワンタッチ距離センサー TFW-DS1(Amazon

f:id:MihoN:20190413230055j:plain
〇 プログラム

f:id:MihoN:20190413094133p:plain

micro:bit②:音鳴らして追っ払ってやる!(楽譜部分はヒミツ)
〇 参考にさせていただいたサイト
     https://blogs.yahoo.co.jp/mikewanko2/14236153.html
〇 用意したモノ:TPA2005D1搭載モノラルオーディオアンプ(SWITCHSCIENCE)

f:id:MihoN:20190413230125j:plain
〇 プログラム

f:id:MihoN:20190413100255p:plain

micro:bit③:ミサイルぶっ放して追っ払ってやる!
〇 参考にさせていただいたサイト
     https://sanuki-tech.net/micro-bit/make/motor-driver-tb6612fng/
〇 用意したモノ:TB6612FNG搭載デュアルモータードライバ(SWITCHSCIENCE),
タミヤのギヤボックス,100均ミサイル

f:id:MihoN:20190413230156j:plain
〇 プログラム

f:id:MihoN:20190413111947p:plain

micro:bit④:micro:bit①,②,③とラズパイちゃんとの連携!

f:id:MihoN:20190413230415j:plain
〇 プログラム

f:id:MihoN:20190413112402p:plain

ラズパイちゃん⑤:彼④からの連絡で,写メ&ツイート
〇 参考にさせていただいたサイト
     http://kivantium.hateblo.jp/entry/2015/01/03/000225
〇 プログラム

# coding: utf-8

import serial
import time
import datetime
import picamera
import tweepy
import RPi.GPIO as GPIO
import Eye
import subprocess
import os

ser = serial.Serial('/dev/ttyACM0', 115200, timeout = 10)

def main():

consumer_key = "みなさんのを記載"
consumer_secret = "みなさんのを記載"
access_token = "みなさんのを記載"
access_secret = "みなさんのを記載"
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_secret)
api = tweepy.API(auth)

# 8x8 MatrixLED
RapiEye_l = Eye.Eye(0x71)
RapiEye_r = Eye.Eye(0x70)
RapiEye_l.heart()
RapiEye_r.heart()

while True:
# LoopCatch:
c = ser.read()
print (c)
if c == '1':
# camera
RapiEye_l.eye_angly1()
RapiEye_r.eye_angly2()
mycam = picamera.PiCamera()
mycam.brightness = 60
mycam.vflip = True
d = datetime.datetime.today()
FileName = d.strftime("%Y-%m-%d_%H%M%S") + '.jpg'
print(FileName)
mycam.capture(FileName)
mycam.close()
#tweepy
api.update_with_media(FileName, status="^-^#")
print ('Picture tweet')
time.sleep(3)
elif c == '0':
RapiEye_l.heart()
RapiEye_r.heart()
print ' Receve 0'


if __name__ == '__main__':
main()

 

micro:bitな彼とラズパイちゃんは,らぴろん(Rapiroロボット)の脳みそにしたかったけど,う~ぅ.後日動画でアップします.

f:id:MihoN:20190105225451j:plain

いったんここまでww
後日引き続きよろしくおねがいしまぁーす.

らぴろんの目入れ儀式💛

 

今年は近所の神社と,○○大師と○○神社に初詣にいってきた^^
そこで だるま を見て思った.

そうだ!らぴろんの目入れをしよう💛

まずは 目を創ることから!(笑)

■ らぴろんの目をつくります ^^

〇用意するもの
Adafruit I2C通信の8x8ミニLEDマトリックス基板  2個  

Adafruit I2C通信の8x8ミニLEDマトリックス基板(青色) - スイッチサイエンス

はさみで切れる超薄型ユニバーサル基板  

https://www.switch-science.com/catalog/3309/

ETFE電線(ジュンフロン線)0.26mm  

https://www.marutsu.co.jp/pc/i/7967/

ハンダづけ環境やRasPi2と接続するためのケーブル

 1.  目のイメージを創ります

MatrixLEDを取り付け基板に取り付けましょう♪
取り付け向きは下の通りにしてね ^^# 基板にある白丸側に型番表示が来るように ^^

f:id:MihoN:20190105225055j:plain

つぎに
はさみで切れるユニバーサル基板をらぴろんの目の縦幅くらいに切ります.
そして,目のパーツが取り付けられているネジを利用して止めちゃいます.
裏から見るとこんな感じ(左)表から見るとこんな感じ(右)

f:id:MihoN:20190105224340j:plainf:id:MihoN:20190105224624j:plain

ここで MatrixLED の登場です.いい感じのところに配置しましょう♪

f:id:MihoN:20190105224802j:plain

2. さぁ,ハンダ頑張って!

f:id:MihoN:20190105225301j:plain

じゃ目入れの儀式を行います ^^#

3. RasPiとつないで
    じゃぁ~ん! お正月なので💛 正月

f:id:MihoN:20190105225451j:plain

カメラで撮るとぼやけて撮れる...
いま,はさみで切れるユニバーサル基板が少し浮く(ネジで留めて反り返ってるからね)でもアタマにRasPi収めて閉じちゃえば,RasPiがはさみで切れるユニバーサル基板ごとグイっておすからその浮きはずいぶんマシになるよ ^^#

いろんな材料を加工できる機械持ってるひとは,材料を加工してRasPiに取り付けれる冶具なんかを創って取り付けてもいいかもね ^^#

3Dプリンタで冶具創るなんてのもありかも ^^#

と今日はここまで.ひさしぶりに らぴろん に息を吹き込んだ(笑)
これからアタマの中がいろんなもので詰まっていく予定.詰まりすぎて熱くなって らぴろん が熱で寝込んでしまわないようにしなきゃ ^^#