フォト
2017年4月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            
無料ブログはココログ

« 2015年11月 | トップページ | 2016年1月 »

2015年12月の7件の記事

2015年12月28日 (月)

Propeller始めました(14) プロペラボードを自作しました

プロペラボードを自作しました。
市販のクイックボードは普段使わない機能にI/Oポートを使われており、色々と実験する
には使いにくので必要機能のみをチョイスして実装しました。

Dscn4619

プログラム保存用32kバイト EEPROM、RTCモジュール(ボタン電池によるバックアップ付き)、
漢字フォント等のデータ用 8Mバイトフラッシュメモリ搭載です。
外付け水晶発振子は6MHzのものを付けて、標準の80MHzに対して96MHz(20%オーバークロック)
にしました。

漢字フォントデータを8Mバイトフラッシュメモリの載せることによって、5秒かかっていた
1画面分の日本語テキスト表示処理が0.2秒に改善出来ました。

Img02

回路図(クリックすると拡大表示します)

Propeller

今回の実装において、I2C接続のRTC用ICのDS1370が5V駆動のためI2Cバス接続において
レベルシフトを行っています。レベルシフトはFETを使う方法で対処しました。
Nch MOS-FET BSS138を使っています。 

02

この方法については、air bibleさんのブログの記事「I2Cインタフェースで異なる電圧の接続
を参考にさせて頂きました。

BSS138は米粒サイズなので扱いが面倒ですが安い(1個8円)し、スペースを取らない
ので市販のレベルシフトモジュールなんかを使うよりは良いですね。

Img03

黒いユニバーサル基板を使ったせいなのか、見た目がかっこよい感じになりました。
ユニバーサル基板は何でも同じだと思ったのですが、今回使った
秋月電子で購入した「片面ユニバーサル基板(ProtoBoard)」は大変使いやすいです。
角型ランドははんだ付けしやすく、太いポリウレタン同線、ビニール線が付け易いです。
また、基板の左右の端列がVCC用・GND用になっているのも良いです。


2015年12月18日 (金)

「Ichiojam関連記事のまとめ」ページを作成しました

Ichiojam関連記事のアクセス数が多いので、まとめページを作成しました。

Ichiojam関連記事のまとめ http://nuneno.cocolog-nifty.com/blog/icihojam.html

本ブログの左側よりアクセス出来ます。

2015年12月13日 (日)

Propeller始めました(13) ステッピングモーターの制御

安価なステッピングモーター28BYJ-48をいじってみました。

Dscn4568

このモーター、amazonでも制御ボード(実際には単なるトランジスタアレイ)とセットで
送料込みで289円で販売されているようです。

01

このモータはユニポーラ型です。あまり詳しくはないのですが、
現在主流のバイポーラ型に比べると性能が劣る(特に低速でのトルク)ようですが、
制御が非常に簡単です。

ステッピングモーターの制御関連の情報を調べてみると、
TekuRobo工作室さんの解説記事「ステッピングモータを動かす」 で
"手動でパルスを与えて動かすことができる"という面白そうな実験が紹介されている
ので私もやってみました。

Dscn4573

結線しボタンの赤黄緑青の順番で押して次のような「1-1相励磁」のパルス信号を
作ってみると、1ステップ分、モーターが動きました。順番を逆にして押すと、
逆回りします。

03

このパルスをマイコンで生成するのは簡単ですね。だだし「1-1相励磁」は
トルクが小さくあまり使われていない駆動方法のようです。

いくつか、駆動方法があるようですが「1-2相励磁」は「1-1相励磁」よりも
回転が安定し、高いトルクが得られるようです(下記の8パルスで1ステップ)。

04

さすがに、これを人間がボタン操作で再現するのは難しいので、
プロペラでパルスを生成してモーターを駆動させてみました。

Dscn4578

実際の動作の様子です。


簡単なプログラムで制御出来ました。

モータ的には1ステップで5.625度(1/64回転)回転します。
「1-2相励磁」の1ステップのパターンは8パルスで生成するので、
1回転するには512パルスを与えることになります。

このパルスを早めると回転数が早くなります。早すぎると脱調という現象が起きて
回らなくなります。このモータの限界は1回転 4.9秒が限界でした。

回転は遅いですが、精度の高い数値制御が出来そうです。
モーターを2つ使って、2次元的な動きをさせようと考えています。



2015年12月12日 (土)

Propeller始めました(12) TV出力ドライバーライブラリの作成

取りあえず、今までの試作を元に、日本語テキスト表示を行うドライバーライブラリを
作成しました。今回、初めてアセンブラを一部利用して本格的なドライバを作成してみました。
CPUコア的には3コア利用しています。

Dscn4567

ドライバライブラリを使ったソースは下記の通りです。
お手軽に日本語表示出来ます(逆にそれしか出来なんだけど...)

spin言語がglue(のり)となって、部品を繋ぎ合わせてプログラミングが出来ます。
アセンブラ等のややこしいとろこは見えません。

Src

実装においては、アセンブラにて高速化を行ったつもりですが、
やはりSDカード上のフォントを検索して表示しているため、その部分がボトルネックとなり
思ったほど高速化出来ませんでした。

また、アセンブラのコーディングにおいてはスタックが使えない点と
メモリーが全部レジスタのため、からだが痒くなるような落ち着かない気分での
作業となりました。

その点を含め、今回の実装でプロペラののアセンブラプログラミングの流儀の
いくつかを学ぶことが出来ました。

アセンブラ命令語は、分かり易く強力な命令があります。
下記の例のように通常の命令に修飾子をつけて機能を付加できます。

01

上記のand命令のお尻に wznr を付けて zフラグ(演算結果が0の場合はセット)の
セット指定、nr(演算結果を設定にない)を付けて、代入せずzフラグだけの
結果を取得することができます。

通常のmov(値のセット)にも if_z等を付けて、zフラグがセットされている場合に
実行する等の条件を付けることができます。

プロペラのアセンブラプログラミングでは積極的に自己プログラム変更を行うのが
流儀のようです。プログラムを積極的に書き替える命令があります。

02

上記のmovd :arg ,#f_x は ラベル:arg rdlongdstの内容を書き換えることが出来る
命令文です。add :arg,d0 rdlongdstを変更して読み込みデータの格納アドレスを
インクリメントしています。
メモリー制約が厳しい(1コアのメモリは2kバイト)のでこのようなテクニックを使うのでしょうね。

 

2015年12月 9日 (水)

Propeller始めました(11) アセンブラでLチカ

前回のビデオ出力処理の高速化にはアセンブラでの記述が必要なため、
アセンブラの勉強を開始しました。とりあえずは、定番のLチカです。

マニュアルのアセンブラのソースを意味を理解しながら打ち込み、実行してみました。
クイックボート上の16番ピンに接続されているLEDを点滅させます。

ソースのダウンロード

Pasm

問題なく動作しました。その動作も理解出来ました。
これから、徐々に色々と学んで行きたいと思います。

Dscn4564

アセンブラコードの実行はSpinプログラムから呼び出す形態となります。
そして、そのアセンブラコードの実行は、別のコアCPU(cog)を割り当てます。

色々とプロペラ固有の作法があるようです。特に別コアで動かすため、
メインのSpinプログラムとの連携等を今後学んでいく必要があります。

まあ、しかし開発環境がアセンブラをサポートしていると、意外と手軽に利用出来ますね。



2015年12月 6日 (日)

Propeller始めました(10) ビデオ出力で日本語表示

Propeller搭載 QuickStartボードでビデオ出力での日本語の表示を実装してみました。

Photo

画面の解像度は256x192ドットとなります。
SDカード上に7種類の異なるフォントを突っ込み、ユニコード文字列(UTF-8)を
NTSCビデオ信号にてモニターに表示しています。

SDカード上の漢字フォントは、UTF-16のインデックスを付けてUTF-16順にソートした
漢字フォントデータを検索参照します。
漢字フォントデータは以前フラッシュメモリW25Q64V用に作成したフォントデータを
利用しました。

関連記事:arduinoで利用可能な漢字フォントROMの製作
              arduinoで利用可能な漢字フォントROMの製作(2)             

表示に指定するユニコード文字列UTF-8は可変長のためそのコードから漢字フォント
を検索するのは面倒なので、UTF-16に変換してから漢字フォントを検索しています。

SDカード周りのアクセス性能は問題ないのですが、
graphicsライブラリのplotメソッドで点打ちしているので表示がちょっと遅いです。
直接フレームバッファに書き込み等を行ってもう少し性能改善を行う必要があります。

今回の実装で、プロペラのメモリ不足に遭遇してしまいました。
graphicsライブラリは24.5kバイトもメモリーを食うのです。調べると贅沢なダブルバッファ
方式を使っていました。一部を修正して表示中のメモリに直接書き込みするように
変更すると、12kバイト節約でき、プログラムを載せることが出来ました。

2015年12月 1日 (火)

Propeller始めました(9) I2Cデバイスを利用する

Propeller搭載 QuickStartボードを使って初めてのI2Cを使ってみました。

IcihgoJam用に製作したHT16K33を使った8x16LEDマトリックモジュールを繋げてみました。
Propeller用のI2Cライブラリはいくつかありますが、今回はSpin言語のみで実装している
Basic_I2C_Driverを使ってみました。

プログラムは下記の通りです。
{{ File: LED_Matrix.spin
   8x16LEDマトリック表示制御 by たま吉さん 2015/11/28    
   I2C接続LEDドライバHT16K33を使った8x16のLEDマトリックスを制御する
}}

CON
    {システムクロック設定 5Hhz×16=80Mhz}
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000
  
    {HT16K33 利用ピン,アドレス}
    SCL_PIN = 5         'I2C SCLピン
    SDA_PIN = 6         'I2C SDAピン
    I2CADR  = $70<<1    'HT16K33のアドレス(8ビットアドレス)

    {HT16K33 コマンド}
    HT_CMS_DATA       = $00 'データ送信
    HT_CMD_SYSSET     = $20 'システムセットアップ
    HT_CMD_BLINK      = $80 '点滅表示周期の設定
    HT_CMD_BRIGHTNESS = $E0 '明るさの設定
    
    {HT16K33 レジスタ設定値}
    HT_SYSSET_OSC_ON  = 1
    
    {HT16K33 点滅表示周期 設定値} 
    HT_BLINK_OFF        = %00000000
    HT_BLINK_DISPLAY_ON = %00000001
    HT_BLINK_2HZ        = %00000010
    HT_BLINK_1HZ        = %00000100
    HT_BLINK_05HZ       = %00000110                       

VAR  
    word    buf[8]  'HT16K33 表示パターンバッファ 横16ドットx縦8ドット
    byte    str[16]
OBJ
    i2c     : "Basic_I2C_Driver_1"
    debug   : "Parallax Serial Terminal"
    f       : "Float32.spin" 

{メイン処理}
PUB main | i,x,y,d,f_rd, f_x, f_y,f_dv,f_dx
    debug.Start (115200)
    i2c.Initialize(SCL_PIN)
    f.start
       
    ht_clear
    ht_init
    
    repeat
        repeat i from 0 to 7
            ht_clear_buffer
            ht_write_at(@msg_saitama[0], i-7, 0)
            ht_write_at(@msg_saitama[8], 15-i, 0)        
            ht_update
            waitcnt(clkfreq/1000 * 100 + cnt)       
        waitcnt(clkfreq/1000 * 500 + cnt)       
        repeat i from 0 to 7
            ht_clear_buffer
            ht_write_at(@msg_saitama[0], 0, -i)
            ht_write_at(@msg_saitama[8], 8, i)        
            ht_update
            waitcnt(clkfreq/1000 * 100 + cnt)       
        waitcnt(clkfreq/1000 * 2000 + cnt)       
           
        
        f_rd := 0
        f_x  := 0.0
        f_dv := f.FDiv (PI, 5.0)
        f_dx := f.FDiv (16.0, 80.0)
        'repeat 
        repeat 2
            f_rd := 0.0
            f_x  := 0.0
            repeat i from 0 to 80
                f_x := f.FAdd (f_x, f_dx)
                f_y := f.FAdd (f.FMul (f.Cos (f_rd), 8.0), 8.0)
                ht_clear_buffer
                ht_write_at(@msg_saitama[0], f.FTrunc (f_x) , f.FTrunc (f_y))
                ht_update
                waitcnt(clkfreq/1000 * 100 + cnt)       
                f_rd := f.FAdd (f_rd, f_dv)    
        waitcnt(clkfreq/1000 * 500 + cnt)       

        d := 1
        repeat 2
            repeat y from 0 to 7
                repeat x from 0 to 15
                    ht_set_dot(x, y, d)
                    ht_update
                    waitcnt(clkfreq/1000 * 20 + cnt)
            d:= !d & 1       

{HT16K33 初期化}
PUB ht_init
  ht_cmd(HT_CMD_SYSSET, HT_SYSSET_OSC_ON)                  'システムオシレータをONにする
  ht_cmd(HT_CMD_BLINK, HT_BLINK_DISPLAY_ON | HT_BLINK_OFF) '点滅表示周期の設定
  ht_cmd(HT_CMD_BRIGHTNESS, 0)                             '明るさの設定    

{HT16K33 コマンド送信}
PUB ht_cmd(cmd, prm)
    i2c.Start(SCL_PIN)
    i2c.Write(SCL_PIN, I2CADR)
    i2c.Write(SCL_PIN, cmd|prm)
    i2c.Stop(SCL_PIN)

{表示パターンの送信}
PUB  ht_update | i
    i2c.Start(SCL_PIN)
    i2c.Write(SCL_PIN, I2CADR)
    i2c.Write(SCL_PIN, HT_CMS_DATA)

    {16バイト分パターンデータ送信}
    repeat i from 0 to 7
        i2c.Write(SCL_PIN, buf[i]& $FF)
        i2c.Write(SCL_PIN, buf[i]>>8)

    i2c.Stop(SCL_PIN)

{バッファクリア}
PUB ht_clear_buffer | i
    wordfill(@buf, 0, 8)

{表示のクリア}
PUB ht_clear
    ht_clear_buffer
    ht_update
    
{バッファの指定座標のON/OFF}
PUB ht_set_dot(x, y, d)
    if d
        buf[y] |= $80_00 >>x
    else
        buf[y] &= !($80_00 >>x)

{バッファ上の指定座標に8x8パターンをセット(負座標指定可能)}
PUB ht_write_at(fptr, x, y) | i               
    if (x > 15) or (y > 7) or (x < -7) or (y < -7)
        return    
    repeat i from 0 to 7                   
        if i + y => 0 and i + y < 8
            if x =< 8
                buf[i + y] |= byte[fptr][i]<<(8 - x)
            else
                buf[i + y] |= byte[fptr][i]>>(x-8)
                                      
DAT
msg_saitama     byte $08,$08,$7E,$04,$24,$40,$3C,$00  'さ
                byte $00,$88,$84,$82,$82,$50,$20,$00  'い
                byte $20,$F0,$2E,$40,$48,$50,$8E,$00  'た
                byte $08,$7E,$08,$7E,$08,$7C,$7A,$00  'ま

Spin言語は超マイナー(プロペラ以外の使い道無し)ですが、
使いやすい言語です。

« 2015年11月 | トップページ | 2016年1月 »