Home > 多摩美 4+MC 実践デバイス

多摩美 4+MC 実践デバイス Archive

processing -> Flashのデータ送受信

processingからFlashへの通信サンプル

上記リンクをクリックすると、processingとFlashのサンプルが同時に起動します。processingのエリアをクリックしてアクティブにし、マウスを移動するとFlash側も同期して動く。Flash MX (ActionScript1.0)で記述しています。

*javaのセキュリティポリシーの設定が必要なのでこのままでは動作しません。サンプルをローカルにダウンロードして試してください。 どうしても興味のある人は下記のようなファイルを".java.policy"として保存し、ホームディレクトリに置いた上でポリシー設定を再ロード(やり方分からなければブラウザ再起動でも可)します。ただし、これは危険が伴うので(もしこのサイトに悪意のあるjavaアプレットが隠されていた場合に無防備)実験が終わったら削除した方が安心でしょう。
grant codeBase "http://www.vector-scan.com/-" {
	permission java.security.AllPermission ;
};


以下に今回のプログラムを示します。

processing側(サーバ)のソース
import processing.net.*;

Server server ;
Client client ;

boolean connected ;

void setup() {
  size(200,200) ;
  server = new Server(this, 5204) ;
}

void draw() {
  background(255) ;
  line(0,mouseY,width,mouseY) ;
  line(mouseX,0,mouseX,height) ;
  updateSocket() ;
}

void updateSocket() {
  String xmlStr = "<?xml version='1.0'?><p2f>" ;
  xmlStr += "<var name='mouseX' value='" + mouseX + "' />" ; // write data here
  xmlStr += "<var name='mouseY' value='" + mouseY + "' />" ; // write data here
  xmlStr += "</p2f>\0" ;
  server.write(xmlStr) ;
}

void serverEvent(Server srv, Client clt) {
  println("connected") ;
  if (client != null) server.disconnect(client) ;
  client = clt ;  
}
ここではmouseXとmouseYの情報を送ってます。
必要に応じて// write data hereのコメントがある行を書き換えて、自分がFlashに伝えたい変数をXML化してください。
Flash側(クライアント)のソース
var vars = new Array();
var socket;
var connected = false;

// ソケットを作成
socket = new XMLSocket();

// 接続時のイベントハンドラ
socket.onConnect = function(f) {
	if (f) {
		trace("connected");
		connected = true;
	} else {
		trace("server not found");
	}
};

// データ受信時のイベントハンドラ
socket.onData = function(rx) {
	parse(rx);
};

// 接続要求
function connect() {
	socket.connect("127.0.0.1", 5204);
}

// データ受信時にXMLから連想配列に変換
function parse(str) {
	rxXML = new XML();
	rxXML.parseXML(str);
	n = rxXML.firstChild.childNodes;
	for (i=0; i<n.length; i++) {
		vars[n[i].attributes.name] = n[i].attributes.value;
	}
}

// 接続確率まで定期的に接続を試みる
function checkConnection() {
	if (connected) {
		clearInterval(timer);
	} else {
			connect() ;
	}
}

// 接続を仕掛ける
var timer = setInterval(checkConnection, 1000);

Flash側ではvars["mouseX"]やvars["mouseY"]としてアクセスできます。


サンプルでは下記のようなスクリプトを3フレーム目に置いて、dotと名付けられた■のムービークリップを動かしています。

// 第3フレームのスクリプト
dot._x = vars["mouseX"] ;
dot._y = vars["mouseY"] ;
gotoAndPlay(2) ;


ローカルで試したい人はこちら→ソースのダウンロード(processingとFlash)

*通信を許可するにはFlashのグローバルセキュリティ設定を行う必要があります。ダイアログに従って設定してください。

*processing側(サーバ)は一度接続を確立したら送信を始めますが、接続が切れたことを検出しないので、Flash側を停止すると例外が発生してそれ以降正常動作しません。Flash側を停止した場合は、processing側も一度止めてrunし直してください。processingで接続断を検出する方法 or Flashで終了時のイベントを捕まえる方法を知ってたら教えてください。


Flashのセキュリティ設定方法

ローカルで開くとこのようなダイアログが出るので、「設定」をクリック。

出ない場合はグローバルセキュリティ設定のページにアクセス

するとAdobeの設定ページが表示されるので、「グローバルセキュリティ設定」タブを選んで…

信頼するファイルを追加する。

これで該当ファイルが選択されました。

Flashのファイルをリロードすれば動作するはずです。


processingはプログラムするには楽なのだけど、描画の負荷の大きい作品には不向きな面もあります。アニメーションのエディットという点でもFlashを使うと作品としていい結果を生む事は結構あるかと思うので、こういうやり方も良いかもしれないですね。つまり、デバイスの入出力とか画像解析などをprocessingで処理して、描画全般をFlashでやるなどです。
リクエストがあれば、Flash -> processingの方法も書こうと思います。

あと、ActionScript3.0を使うとポリシーをサーバから送ってやる方法があって、パーミッションの設定を手動でやらずに通信できるので便利です。バイナリの通信も出来るし。それはまたの機会に。

xbeeを5V系とつなぐ

xbeeはzigbeeのモジュールだけど、おそらく作品制作で当面必要なのは1対1の通信だと思います。その場合zigbeeとしての使い方ではなく、その下位のレイヤ(IEEE 802.15.4)での運用で十分と思います。zigbeeはメッシュネットを構成したりして大変興味深いプロトコルなんですが、なかなか複雑で実は自分、まだ理解してませんです。あと通信速度や遅延の安定度の点からするとzigbeeでない方が有利なはずです。ちょうどTCPとUDPの関係に似てると思います。
という訳で基板は同じものなんだけど、zigbeeでなくIEEE 802.15.4です。YMOでなくHASYMOということになります。

ところで無線モジュールのxbeeは3.3Vで動作するので、普段使っているであろう5V系の回路(Pri/Proもそうです)と接続する時はちょっと工夫が必要です。

写真は、ちょっと分かりづらくてすみませんが、FT232RL(5V動作時)との簡易接続についてのメモです。

xbee_interface.jpg

FT232RLのシリアル出力をxbeeのシリアル入力に入力するときに抵抗で分圧してます。
逆方向(xbeeシリアル出力→FT232RLシリアル入力)はFT232RLの入力の仕様をみると、1.9V(max)が入力の閾値となっているので、直結して大丈夫です。
xbeeに電源を供給するためにTA48M033などのレギュレータをつかって5Vから3.3Vを得ます。

Pri/Proライブラリ for procesingのサンプル

今日はPICでTIMER2を使ったPWM出力をやろうとしたのだけど、なぜかconst char[] = { xx, xx, ... xx } ;がちゃんとコンパイルされない問題に遭遇。sdccのバージョンが2.7にあがったのでアップデートしてみたところ、その問題は無事解決。しかし、今度はうまく割り込みがかからない。ちょっと確認に時間をもらうとして今日はPICはなしということで。

前のエントリーでPri/Proのprocessingライブラリを公開し、それに対応してファームをアップデートしていますので手持ちのPICtoasterなどで焼いてください。

以下はMCDさんからの質問に答えたサンプルで、一定時間でLEDを点滅するものです。もうちょっと楽なやり方もあるかもしれない。
PriProクラスを使うと、
入力値はPriPro.in[チャネル番号]に入ってきます。
出力値はPriPro.out[チャネル番号]に代入すれば反映します。
普通の変数にアクセスするのと同じ感覚でセンサの値をみたり出力したりできます。

// MCDさん用サンプル
import pripro.*;           // pri/proのライブラリをインポート
PriPro pp ;                // ここではpri/proをppとして扱う
int t = 30 ;               // 最初は3秒間

void setup() {             // ここはプログラム開始時に実行される
  pp = new PriPro(this) ;  // pri/proの導入
  frameRate(10) ;          // 毎秒10 draw()を実行する
}

void draw() {              // ここは繰り返し実行される
  t-- ;                    // タイミング用のカウンタを減算
  if (t==0) {              // カウンタが0になった?
    if (pp.out[0] == 0) {  // 今OFF?
      pp.out[0] = 255 ;    // ONにする
      t = 30 ;             // 次のタイミングを設定
    } 
    else {                 // ONの場合...
      pp.out[0] = 0 ;      // OFFにする
      t = 30 ;             // 次のタイミングを設定
    }
  }
}

SDCCでPICプログラミング 入力

ポートからの入力をするには、
・TRISIOの設定で希望のピンを入力に設定し
・GPIOの値を調べる
以上で出来る。GPIOはGP3を除き内部プルアップという機能を持っていて、ピンを解放状態でHiにすることができる。プルアップ機能はデフォルトでONであるが、個別にOFFにすることもできる。
一般にプルアップ(あるいはプルダウン)せずに入力ピンを解放するのは厳禁。不定な値になるだけでなく、内部の回路を壊す可能性がある。

スイッチの様な機械的入力についてはチャタリングに注意する必要がある。これは値が安定するまでにON/OFFを繰り返してばたついてしまう現象である。これ、オシロでみましょう。
それを回避する方法はいろいろあるが、ここではプログラム的なやり方をとる。具体的にはスイッチの状態を一定間隔で観察するというやり方である。この間隔がチャタリングのばたつきの間隔より十分長ければほぼ正常な動作が期待できる。ここではTIMER1割り込みによって入力のチェックをしている。

サンプルはtest01_3を修正してキー入力がある度に音程が変わる、というものにした。前回のソースと見比べればどこを変えたか分かると思う。
GP5を入力に設定した。GP5をスイッチかジャンパケーブルでGNDに繋ぐと入力がLoとなり、プログラム的にはスイッチが押されたと解釈される。TIMER1割り込み処理の中でそれをチェックしてTIMER0の初期値を変更している。
ところでこの「なる度に」に注意したいのだが、一定周期で入力を観察→Loなら音程を変更、というだけの処理だと、スイッチを押しっぱなしのときにひたすら音程を変更し続けるおかしな動作になってしまう。ほしいのは離した状態から押した状態に移行したときだけに音程を変更する機能であるので、ここはすこし工夫が必要になる。それがswitch_enabledというフラグで実現されているので、なにをやっているのか解読してみてほしい。

// test02 : スイッチ入力によって音を変化させる
// 回路の設定:ピエゾをGP0とGNDの間につなぐ。タクトスイッチをGP5とGNDの間につなぐ。

#include <pic12f683.h>

// フューズの設定 (内部オシレータ、ウォッチドッグOFF、ワパーアップタイマON、MCLR OFF)
int at 0x2007 __config = _INTOSC & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF ;


// 変数の宣言
char port_value = 0x00 ;                                // ポートの出力値
char notes[] = { 0, 128, 192, 224, 239, 248, 252 } ;    // 音程の配列
char note_index = 0 ;                                   // 読み出しインデックス
char switch_enabled = 1 ;                               // スイッチが有効フラグ

// メインルーチン
void main () {
    //-------- 基本的な設定 --------
    OSCCON = 0x72 ;                                 // 8MHzで動作
    ANSEL = 0x00 ;                                  // すべてのピンをデジタルI/Oに指定
    TRISIO = 0x28 ;                                 // ポートの入出力方向を指定 (GP3, GP5が入力)
    
    //-------- TIMER0の設定 --------
    OPTION_REG = 0x54 ;                             // プリスケーラ比1:32、内部クロックソース
                                                    // プルアップON

    //-------- TIMER1の設定 --------
    T1CON = 0x01 ;                                  // プリスケーラ比1:1、内部クロックソース、TIMER1 ON
                                                    
    //-------- 割り込みの許可 --------
    T0IE = 1 ;                                      // TIMER0割り込みを許可
    T1IE = 1 ;                                      // TIMER1割り込みを許可
    PEIE = 1 ;                                      // 周辺回路の割り込みを許可
    GIE = 1 ;                                       // 全体の割り込みを許可

    //-------- メインループ --------
    while (1) {                                     // 無限ループ
    }
}

// 割り込みルーチン
void interval() interrupt 0 {
    //-------- TIMER0割り込み処理 --------
    if (INTCON & 0x04) {                            // TIMER0割り込み?
        TMR0 = notes[note_index] ;                  // TIMER0の値をリセット
        port_value ^= 0x01 ;                        // GP0を反転
        GPIO = port_value ;                         //
        T0IF = 0 ;                                  // 割り込みフラグをクリア
    }

    //-------- TIMER1割り込み処理 --------
    if (PIR1 & 0x01) {                              // TIMER1割り込み?
        if (switch_enabled) {                       // スイッチ有効?
            if (!(GPIO & (1<<5))) {                 // スイッチが押されてる?
                note_index++ ;                      // 音程読み出し位置を進める
                if (note_index == sizeof(notes))    // 最後まで行ったら元に戻す
                    note_index = 0 ;                //
                switch_enabled = 0 ;                // スイッチを無効化
            }
        } else {                                    // スイッチ無効?
            if (GPIO & (1<<5)) {                    // スイッチが離されてる?
                switch_enabled = 1 ;                // スイッチを有効化
            }
        }
        T1IF = 0 ;                                  // 割り込みフラグをクリア
    }
}

SDCCでPICプログラミング 音を鳴らす

PIC12F683を使ってサウンドを発生してみる

PICの出力ポートの電圧をHi/Loと切り換える事でサウンドを発生する。切り替えの早さが音程に反映する。
以下のコードは前回test00(LEDの点滅)とほぼ同じ内容だけど、切り替えのタイミングが100倍早くなっている。

// test01_0 : ビープ
// 回路の設定:ピエゾをGP0とGNDの間につなぐ

#include 

// フューズの設定 (内部オシレータ、ウォッチドッグOFF、ワパーアップタイマON、MCLR OFF)
int at 0x2007 __config = _INTOSC & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF ;


// 変数の宣言
char port_value = 0x00;                 // ポートの出力値

// メインルーチン
void main () {
    int i ;                             // サウンド発生用のカウンタ
    
    //-------- 基本的な設定 --------
    OSCCON = 0x72 ;                     // 8MHzで動作
    ANSEL = 0x00 ;                      // すべてのピンをデジタルI/Oに指定
    TRISIO = 0x08 ;                     // ポートの入出力方向を指定
    
    //-------- メインループ --------
    while(1) {                          // 無限ループ
        port_value ^= 0x01 ;            // GP0を反転
        GPIO = port_value ;             //
        for (i=0; i<100; i++) ;         // 時間稼ぎに数を数える
    }
}
test01_0.c


ピッチを決定する数値はどこにあるだろうか。それをいろいろに変えてピッチがどう変わるかを実験してほしい。
そしてこの際だからオシロで周波数を計ってみよう。

これらのの実験で命令を実行するのには(たとえそれが何もしないただのループでも)特定の時間がかかることが分かるかと思う。


2つの音程を交互にならす

次に2つの音程を交互に鳴らすプログラムを考える。それぞれの音の長さは同じとする。
するとこのプログラムは2つの時間を管理することになる:
・一定の音程の音を発生する
・一定の長さの音を発生する
いままでのfor文のやり方でどうすれば良いか考えて見てほしい。一筋縄では行かないと思う。
ここでは音の長さを割り込みを使って得るやり方でコーディングしてみた。割り込みとはプログラムの外側にある要因を引き金として制御が切り替わる仕組み、のようなものである。
PICに内蔵されている周辺回路のTimer1を使用して、一定時間ごとに割り込みを起こしてみる。

// test01_1 : 2種類のピッチを交互にならす(割り込みで切り替え)
// 回路の設定:ピエゾをGP0とGNDの間につなぐ

#include 

// フューズの設定 (内部オシレータ、ウォッチドッグOFF、ワパーアップタイマON、MCLR OFF)
int at 0x2007 __config = _INTOSC & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF ;


// 変数の宣言
char port_value = 0x00 ;                // ポートの出力値
volatile char expired = 0 ;             // 完了フラグ 最適化をしないようにvolatile

// メインルーチン
void main () {
    int i ;
    
    //-------- 基本的な設定 --------
    OSCCON = 0x72 ;                     // 8MHzで動作
    ANSEL = 0x00 ;                      // すべてのピンをデジタルI/Oに指定
    TRISIO = 0x08 ;                     // ポートの入出力方向を指定
    
    //-------- TIMER1の設定 --------
    T1CON = 0x31 ;                      // プリスケーラ比1:8、内部クロックソース、TIMER1 ON

    //-------- 割り込みの許可 --------
    T1IE = 1 ;                          // TIMER1割り込みを許可
    PEIE = 1 ;                          // 周辺回路の割り込みを許可
    GIE = 1 ;                           // 全体の割り込みを許可

    //-------- メインループ --------
    while (1) {                         // 無限ループ

        // サウンド1
        expired = 0 ;                   // 最初にフラグをリセット
        while(1) {                      // 一見無限ループ
            port_value ^= 0x01 ;        // GP0を反転
            GPIO = port_value ;         //
            for (i=0; i<100; i++) ;     // 時間稼ぎに数を数える
            if (expired) break ;        // フラグが立ったらループから抜ける
        }
    
        // サウンド2
        expired = 0 ;                   // 以下同様...
        while(1) {
            port_value ^= 0x01 ;
            GPIO = port_value ;
            for (i=0; i<200; i++) ;
            if (expired) break ;
        }
    }
}

// 割り込みルーチン
void interval() interrupt 0 {
    expired = 1 ;                       // フラグを立てる
    T1IF = 0 ;                          // 割り込みフラグをクリア
}
test01_1.c


割り込みで音を鳴らす

割り込みの周期を短くすることで音を発生することができる。割り込みがかかる周波数を計算すると狙った音程の音が出せる。
割り込み周波数 = 命令時間 / 分周比 / N
音の周波数 = 割り込み周波数 / 2

// test01_2 : 割り込みでビープ(440Hz)
// 回路の設定:ピエゾをGP0とGNDの間につなぐ

#include 

// フューズの設定 (内部オシレータ、ウォッチドッグOFF、ワパーアップタイマON、MCLR OFF)
int at 0x2007 __config = _INTOSC & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF ;


// 変数の宣言
int port_value = 0x00 ;                 // ポートの出力値

// メインルーチン
void main () {
    //-------- 基本的な設定 --------
    OSCCON = 0x72 ;                     // 8MHzで動作
    ANSEL = 0x00 ;                      // すべてのピンをデジタルI/Oに指定
    TRISIO = 0x08 ;                     // ポートの入出力方向を指定
    
    //-------- TIMER0の設定 --------
    OPTION_REG = 0xd4 ;                 // プリスケーラ比1:32、内部クロックソース

    //-------- 割り込みの許可 --------
    T0IE = 1 ;                          // TIMER0割り込みを許可
    GIE = 1 ;                           // 全体の割り込みを許可

    //-------- メインループ --------
    while (1) {                         // 無限ループ
    }   
}

// 割り込みルーチン
void interval() interrupt 0 {
    TMR0 = 185 ;                        // TIMER0の値をリセット
    port_value ^= 0x01 ;                // GP0を反転
    GPIO = port_value ;                 //
    T0IF = 0 ;                          // 割り込みフラグをクリア
}
test01_2.c


2つの割り込みを組み合わせる

以上の実験で割り込みを使用すると正確な時間を得られることが分かったと思う。
最後に音程と音長の両方を割り込みで制御してみよう。ここではTIMER0とTIMER1を使っている。PIC12/16系の割り込みベクタは1つしかないので、割り込みが起きたらその要因を調べる必要がある。

// test01_3 : 2つの割り込みによる音程と音長の制御
// 回路の設定:ピエゾをGP0とGNDの間につなぐ

#include 

// フューズの設定 (内部オシレータ、ウォッチドッグOFF、ワパーアップタイマON、MCLR OFF)
int at 0x2007 __config = _INTOSC & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF ;


// 変数の宣言
int port_value = 0x00 ;                             // ポートの出力値
char notes[] = { 0, 128, 192, 224, 239, 248, 252 } ;// 音程の配列
char note_index = 0 ;                               // 読み出しインデックス

// メインルーチン
void main () {
    //-------- 基本的な設定 --------
    OSCCON = 0x72 ;                     // 8MHzで動作
    ANSEL = 0x00 ;                      // すべてのピンをデジタルI/Oに指定
    TRISIO = 0x08 ;                     // ポートの入出力方向を指定
    
    //-------- TIMER0の設定 --------
    OPTION_REG = 0xd4 ;                 // プリスケーラ比1:32、内部クロックソース

    //-------- TIMER1の設定 --------
    T1CON = 0x31 ;                      // プリスケーラ比1:8、内部クロックソース、TIMER1 ON

    //-------- 割り込みの許可 --------
    T0IE = 1 ;                          // TIMER0割り込みを許可
    T1IE = 1 ;                          // TIMER1割り込みを許可
    PEIE = 1 ;                          // 周辺回路の割り込みを許可
    GIE = 1 ;                           // 全体の割り込みを許可

    //-------- メインループ --------
    while (1) {                         // 無限ループ
    }
}

// 割り込みルーチン
void interval() interrupt 0 {
    if (INTCON & 0x04) {                // TIMER0割り込み?
        TMR0 = notes[note_index] ;      // TIMER0の値をリセット
        port_value ^= 0x01 ;            // GP0を反転
        GPIO = port_value ;             //
        T0IF = 0 ;                      // 割り込みフラグをクリア
    }

    if (PIR1 & 0x01) {                  // TIMER1割り込み?
        note_index++ ;                  // 音程読み出し位置を進める
        if (note_index == sizeof(notes))// 最後まで行ったら元に戻す
            note_index = 0 ;            //
        T1IF = 0 ;                      // 割り込みフラグをクリア
    }
}

test01_3.c

本当は
if (T0IF) {
    ....
    T0IF = 0 ;
}
みたいにしたかったのだけど、SDCCのバグか僕の不勉強かうまく行かなかったため、直接ビットを指定して判定している。

sdcc + gputils のインストール

HI-TECH PICCは授業では使わないことにしました。HI-TECHの所為ではなくeclipseでデバッグしてみたところあまりに遅く、自分で何をやっているかを見失うくらいに遅かったので残念ながらやめです。
代わりにSDCC(Cコンパイラ)とgputils(アセンブラgpasmその他のツール)を使用することにしました。久世さんのクラスもこれを使うそうです。eMac全部にインストール済みとのこと。
ただ、この環境だとシミュレータがついてません。gpsimというシミュレータが別にあるのですが、今のところ対応プロセッサが限られてる上にX11で走るのでちょっとドキドキします。慣れれば良いんだろうけどね。

というわけで、これからの作業の流れは
Cで書く→SDCCでコンパイル&gpasmでアセンブル→PICtoasterでPICに書き込み→動作確認
という感じになります。

ではまずソフトのインストールをしましょう。ソースをゲットしてコンパイルしても良いのだが、時間の関係もありここはコンパイル済みのバイナリを落としてインストールしてしまいます。以下の作業は管理者権限でログインして進めてください。多分みんなマイマシンだからそこらへんは問題ないと思います。
最終的に久世さんとこと同じディレクトリ構成だと何かと良いと思うのだけど、どうだろう?それは後で確認してみます。

これはMac OSXへのインストール手順です。念のため。

まずはSDCCをインストール

1) SDCCのサイトからうまくたどってMac OSX用のバイナリを落とす。まあここではデスクトップにそれがあるとします。現状ではsdcc-2.6.0-ppc-unknown-macosx10.tar.gzというファイルになります。
2) それを解凍する→デスクトップ上にsdccなるフォルダを発見。
3) ターミナルを開き、以下の作業
cd ~/Desktop/sdcc
sudo cp -r * /usr/local
そこでパスワード聞かれるのでタイプする。
以上。

次にgputilsのインストール

1) こちらにgputilsのOSX用バイナリをまりがたくも置いてくれてる人がいます。これをいただく。
2) そいつを解凍し、gputils-installer-osx.pkgなるファイルを得る。
3) それを起動しあとははいはいと答える。
以上。

パスを通す

1) ターミナルで
cd ~
pico .bash_profile
でエディタを起動し編集する。
export PATH=なんとかかんとか
とかいてあると思うので、そこに追加して
export PATH=なんとかかんとか:/usr/local/bin
として、control+Xで終了。他のところを削除しちゃだめだよ。
保存するかとか聞いてくるのではいはいと答える。

ホームディレクトリに.bash_profileが無い場合は新規に作成することになる。
上記と同様にエディタを起動し、
export PATH=$PATH:/usr/local/bin
として保存する。

1') 普通のテキストエディタでやりたい人はいったん
cd ~
cp .bash_profile ~/Desktop/bash_profile
とするとデスクトップにbash_profileというファイルが現れるはずなのでそれをテキストエディタで開いて、上記のごとく修正し保存。その上で
cp ~/Desktop/bash_profile .bash_profile
とすればオッケー

ログインし直す

これでパスの変更が反映されます。

確認

1) 今までの作業が無事に済むと、
/usr/local/bin/
にsdccやらgpasmやらといったファイルが見つけられるはずです。これらのフォルダはファインダから普段見えなくなっているので、ターミナルから
cd /usr/local/bin
ls
と打つか、ファインダで「フォルダへ移動」(シフト+プロペラ+G)を選んでダイアログに/usr/local/binと打って確認してください。
追:もっと簡単な方法があった。ブラウザに/usr/local/binなどと打てば見える。

2) それから
/usr/local/share/gputils/
/usr/local/share/sdcc/
なるフォルダーもあるかどうか確認する。上記同様の操作でそれぞれの存在を確認する。
そこには各プロセッサのヘッダファイルやらマニュアルなどが入ってます。あーgputilsのマニュアルはさっきのパッケージには含まれてないっぽいのでgputilsの所からたどってソースを落とすとそこに入ってるよ。欲しい人はそれを探すことにしましょう。

コンパイルしてみる

1) では実際にコンパイルをしてみましょう。以下がサンプルのソースです。

// very first test : blink a LED
// connect Anode of a LED to GP0 and Kathode to GND via some resistor (220~1kohm)

#include 

int at 0x2007 __config = _INTOSC & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF ;

void main () {
	long i ;
	int port_value = 0x00;
	
	OSCCON = 0x72 ;
	ANSEL = 0x00 ;
	TRISIO = 0x08 ;
	
	while(1) {
		port_value ^= 0x01 ;
		GPIO = port_value ;
		for (i=0; i<10000; i++) ;
	}
}

test00.c
これを落として、デスクトップにtest00などとフォルダを作りその中に置くとする
cd ~/Desktop/test00
sdcc -mpic14 -p12f683 test00.c
と打つとうまく行けば
message: using default linker script "/usr/local/share/gputils/lkr/12f683.lkr"
こんな表示が出るかと思います。
そうすると、test00フォルダの中にたくさんファイルが生成されている事が分かると思います。
その中のtest00.hexがPICに焼くためのファイルとなります。

2) PICtoasterwを起動し、そのファイルをドラァグ&ドロップし、toastボタンを押して無事焼きます。

3) ブレッドボードでPIC12F683のGP0ピンにLEDをつなぎ(直列に1k程度の抵抗を入れること)電源ONしてLEDが点滅したら成功です。よろしかったですか?
ピン配置などはググってデータシートを見つけるなりして自力でなんとかしてみよう。



追記
ソースからコンパイルをやってみたい人へ:久世さんによるSDCC(Small Device C Compiler)とgputils のインストール 超丁寧にまとめられてます!
miを使う不可視ファイルも開けるそうです。知らなかった!

HI-TECH PICC-LITEでPIC12F683/PIC16F88を使う

HI-TECH PICC-LITEは無料で利用できるが、対象デバイスが限定されていて、僕が非常によく使うPIC12F683もPIC16F88も対象外となっている。そこでそれらをコンパイルできるようにする方法を試したメモ。
以下はMacへのインストール手順を含む。ファイル名やパスは現時点の最新版をインストールした場合のもの。

1) HI-TECH社のサイトで以下のインストーラをダウンロード。その際ユーザ登録が必要。

・Free版のHI-TECH PICC-LITE
・HI-TIDE 3
・Demo版のHI-TECH PICC

2) それぞれをインストール

ターミナルを起動して以下のように作業。(各インストーラがデスクトップに置いてある場合)
cd /Users/ユーザ名/Desktop/

各ファイルのパーミッションを設定
chmod +x picclite-setup.run
chmod +x hi-tide_v3.12PL1.run
chmod +x picc-demo.run

各ファイルを実行。それぞれ何か聞かれるのでyと答える。シリアルナンバーを聞かれたらdemoとタイプ。インストールディレクトリはデフォルトでOK
./picclite-setup.run
./hi-tide_v3.12PL1.run
./picc-demo.run

以上で/Applications/HI-TECH/の下にそれぞれがインストールされる

3) ライブラリを移植

ディレクトリ移動
cd /Applications/HI-TECH/picc

PICC-LITEのライブラリをバックアップ
mv lite/9.60/lib lite/9.60/lib_backup

PICCのライブラリをPICC-LITEにコピー
cp -r std/9.60/lib lite/9.60/lib

移動
cd lite/9.60/lib

すべてのライブラリ名を変換
for i in pic*.lib; do mv $i `echo $i | sed -e 's/pic/pcl/'`; done

最後に.../std/9.60/dat/picc.iniの中から自分が使いたいプロセッサの箇所をコピーして...lite/9.60/dat/picc-lite.ini内にペースト。行数に制限があるっぽいので必要ない箇所を削除したほうがよさそう。

以上でいけるのではないかと思う。思うというのは、コンパイルを一度試しただけで、その後全く使っていないから。
授業の関係上Macで開発が出来る環境を模索している時に残したメモであり、今後これを使っていくかどうかは分からない。Javaベースなので動きが非常にモッサリしていてシミュレータなどもかなりな感じ。自分的にはMPLABでなんら不満なところはないのだ。

そもそもこういう使い方がフェアなのかどうかよく分からない。問題があると思われる方はご指摘ください。

Home > 多摩美 4+MC 実践デバイス

Search
Feeds

Page Top