フォト
2017年5月
  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 31      
無料ブログはココログ

« 2015年12月 | トップページ | 2016年2月 »

2016年1月の17件の記事

2016年1月31日 (日)

aitendoのATTiny ISPシールドきっと [K-TINY-SLD]を購入

ATtiny13A用のプログラマ用にaitendoのATTiny ISPシールドきっと [K-TINY-SLD]
購入して動作確認をしました。

01

295円とリーズナブルです。

Dscn4816

内容はこんな感じです。

Dscn4817

早速組み立てて動作確認しました。

先日動作確認したUSBtinyISPに繋げて確認してみました。
上面にICSPピンヘッダがあるので接続出来ました。
問題なく書きこめました。

Dscn4818

本来はArduino UNOの上にのせてシールドとして利用します。
ArduinoISPを利用して書込みを行うことが出来ます。

Dscn4819

次にICSPピンヘッダにUSBaspをつなげてみます。

Dscn4820

手持ちのコネクタは若干、8ピンICソケットに干渉してしまい奥まではめ込めませんでした。
一応、書き込みは出来ます。

汎用的に使えて非常に便利な製品です。


2016年1月30日 (土)

ATtiny13A - USBtinyISPによるプログラムの書き込み

AliexpressにてAVRプログラマ USBtinyISPを購入して試してみました。価格は$4.5です。
自作した書き込みボードに接続してみました。

Dscn4815

ATtiny13Aに書込みを行って動作確認を行ってみると問題なく書きこめました。
Arduino IDEにも対応しています。USBaspやArduinoISPに比べると早いです。

また、ATtiny13Aのシステムクロックを16KHzにした場合でも avrdudeの-Bオプションで
書込み速度を指定することで書き込み出来ました。

USBtinyISPボード上にはATtiny2313が乗っています。ファームウェアの更新も簡単に
出来そうです。

2016年1月27日 (水)

Propeller始めました(17) ポータブルゲーム機の実装 2

ちびちびと実装を進めていましたLameStationがほぼ完成しました。

Dscn4784

いい感じに仕上がりました。
写真は試しにLameStation SDKのサンプルゲームを書きこんで動かしている状況です。

Dscn4778

実装は本家のLameStationの構造とはちょっと異なります。
既存のQuickStartボードを拡張する形(Arduinoのシールド形式)で実装しました。

表面実装の2x20ピン(オス)を利用してQuickStartボードを拡張するようにしました。

Dscn4738

この方法は今後も色々と使えそうです。

Dscn4775

基板の下には、ダイソーで買った発泡スチロールのボードを取り付けました。
このボードは加工しやすく、強度もそこそこあるのでケースや車体なんかの利用に
良いです。

実際の動作の様子です。片手にカメラを持って撮影しているため、ゲーム操作は適当です。
遊び方も今一分かりませんでした。


このゲーム機の実装で色々と勉強出来ました。
SDKのライブラリを使って何か作る予定です。

ライブラリにはスプライト表示やマップ表示などが充実しており、ちょっとしたゲームが
簡単に作れそうです。


2016年1月25日 (月)

Aliexpressで注文していたアナログジョイスティックが到着

Aliexpressで見つけたアナログジョイスティックが到着しました。1個$0.56(70円)。
注文してから5日で届きました。送料無料では今まで一番早い配達かもしれません。
4個注文しました。

01

激安ですが、以前購入したものよりもしっかりした製品でした。
実際に動作確認しましたが問題なしです。

Dscn4752

今商品をチェックすると、若干値上がりして売り切れ状態でした。

Aliexpressではこういうパターン(投げ売り?)が多いので、こまめにチェックして
掘り出し物を発見を心がけています。


2016年1月23日 (土)

IchigoJamでaitendoのI2Cマトリックスキットを動かしてみました

IchigoJamでaitendoの「I2Cマトリックスキット K-8X8I2C1388」を動かしてみました。

IchigoJam ファームウェアの1.2系のβ版の動作確認を兼ねて制御してみました。
(1.2系のβ版は フェイスブックのIcigojam-FANグループにて公開されています)
1,2系では文字列操作機能が追加されました。

参考情報
  福野泰介の一日一創 - 「文字列対応の IchigoJam ver 1.2β4 でジャンケンゲーム改良」

接続は次のような感じです。
4線接続(VCC、GND、SCL、SDA)で制御します。

Dscn4717

動いている様子

プログラムソース
10 CLV
110 POKE #700,#21,#81,#E1,#00
120 FOR M=#700 TO #702
130 R=I2CW(#70,M,1,#700,0)
140 NEXT
150 S="Hello,Ichigojam World!"
160 L=LEN(S)
500 FOR J=0 TO L-1
510 A=PEEK(S+J)*8
520 FOR C=0 TO 5
530 FOR D=0 TO 7
540 [D]=[D]<<1|PEEK(A+D)>>(7-C)
560 NEXT
570 R=I2CW(#70,#703,1,#800,16)
580 WAIT 2
590 NEXT
600 NEXT
610 GOTO 500

プログラムは意外と短いです。
文字列を扱えるようになったので、デバイスへのデータ渡しが簡単に実現出来るように
なりました。

プログラム的には、
10行が変数領域の初期化
110~140行がデバイスの初期化
150行でスクロール表示する文字列を指定しています。Sにその先頭アドレスが入ります。
160行で文字数の取得
500~610行がスクロール表示を行っています。
[0]~[7]をデバイスに送信するためのデータ領域と利用してます。

500~610行がスクロール表示部において
500行は文字列数分のループ
510行で"Hello,Ichigojam World!" の先頭からJ番目の文字コードを取得し、更に
8倍(1文字につきフォントデータは8バイト)してフォントデータ格納アドレスを取得します。
フォントデータは仮想アドレス#000から格納されています。下記が本来の計算式です。
A=PEEK(S+J)*8+#000

520行は1文字の左スクロール5ドット分のループ(英数字は横幅5ドット)
530行は縦8ドット分の処理のためのループ

540行は表示するデータの加工処理です。直前のデータを左に1ドットスクロールした後、
PEEK(A+D)にてフォントデータを取得してそのデータを右にシフトした値との和を[D]に
代入しています。

570行でデバイスでの表示データ16バイトを送信しています。
表示パターンデータ[0]~[7]の16バイトはアドレス#800に格納されています。
I2CW(#70,#703,1,#800,16) のお尻から2つのパラメタがそれを意味します。
前半の#70,#703,1はデバイス指定と表示のための命令ですが詳細は省略します。

arduinoなんかよりも、短いプログラムで簡単に制御できました。
コンパイルや書き込みも不要なので、確認も楽ちんです。



2016年1月20日 (水)

aitendo I2CマトリックスキットをArduino動かしてみました

aitendo のI2Cマトリックスキット(8x8) [K-8X8I2C1388]をArduinoで動かしてみました。



このキットはLEDのドライブにHT16K33-24Wを使っています。I2Cバス接続なので
少ない配線で8x8ドットのLEDを制御できます。

パーツ的にはこんな感じ

Dscn4705

なぜかドットが四角くないですが良しとします。

組み立てですが、困ったことに基板上の4ヶ所の穴(基板左下の4つ並ぶ穴)がちゃんと空いて無くて
端子が差し込めませんでした。ピンセットでぐりぐりと拡張して広げました。

それ以外は問題なく組み立て完了。
やはり、キットを使った組み立ては自作よりも楽ちんです。

Dscn4710

部品が少し余りましたが、これはいつものaitendoクオリティーなので問題なし。
基板の左上のピンでI2Cのアドレスの設定が出来るようです。
なのでこのキットを複数使えばドットマトリックスを増やせそうです。

Dscn4712

Arduinoに繋げて動かしてみます。

ライブラリやサンプルソースの入手はaitendoの商品ページに情報の掲載がありますが、
以前作成したソースを流用して簡単な動作確認を行いました。

Dscn4714

実際の動作の様子(デモはいつもの ”さいたま” です)


プログラムソース

#include <Wire.h>

// アドレス
#define HT_I2C_ADDRESS 0x70

// コマンド
#define HT_CMS_DATA       0x00
#define HT_CMD_SYSSET     0x20
#define HT_CMD_BLINK      0x80
#define HT_CMD_BRIGHTNESS 0xE0

// System Setup レジスタ設定値
#define HT_SYSSET_OSC_ON  1

// Display setup 設定値
#define HT_BLINK_DISPLAY_ON B00000001
#define HT_BLINK_OFF        B00000000
#define HT_BLINK_2HZ        B00000010
#define HT_BLINK_1HZ        B00000100
#define HT_BLINK_05HZ       B00000110

// 表示パターン用バッファ(R16xC8)
uint8_t buf[8];  

// テスト用パターン('さ','い','た','ま')
uint8_t msg_saitama[4][8] = {
  {0x08,0x08,0x7E,0x04,0x24,0x40,0x3C,0x00},  // さ
  {0x00,0x88,0x84,0x82,0x82,0x50,0x20,0x00},  // い
  {0x20,0xF0,0x2E,0x40,0x48,0x50,0x8E,0x00},  // た
  {0x08,0x7E,0x08,0x7E,0x08,0x7C,0x7A,0x00}   // ま
};

// HT16K33の初期化
void ht_init() {
  Wire.begin();
  ht_system_Seup(HT_I2C_ADDRESS, HT_SYSSET_OSC_ON);  // システムオシレータをONにする
  ht_display_setup(HT_I2C_ADDRESS,HT_BLINK_OFF) ;    // 点滅表示周期の設定
  ht_setBrightness(HT_I2C_ADDRESS,1);                // 明るさの設定
}

// SystemSetup Registerの設定
// (システムオシレータのモード設定)
void ht_system_Seup(uint8_t addr, uint8_t p) {
  Wire.beginTransmission(addr);
  Wire.write(HT_CMD_SYSSET | p);
  Wire.endTransmission(); 
} 

// 明るさの設定
void  ht_setBrightness(uint8_t addr, uint8_t p) {
  if (p > 15) p = 15;
  Wire.beginTransmission(addr);
  Wire.write(HT_CMD_BRIGHTNESS | p);
  Wire.endTransmission(); 
}

// Display setup(点滅周期の設定)
void ht_display_setup(uint8_t addr, uint8_t p) {
  if (p > 3) p = 0;
  Wire.beginTransmission(addr);  
  Wire.write(HT_CMD_BLINK | HT_BLINK_DISPLAY_ON | p); 
  Wire.endTransmission();
}

// 表示パターンの送信
void ht_update(void) {

  // HT16K33  にデータ転送
  Wire.beginTransmission(HT_I2C_ADDRESS);
  Wire.write(HT_CMS_DATA);

  for (uint8_t i = 0; i<8; i++) {
    Wire.write(buf[i]);    
    Wire.write(0);    
  }
  Wire.endTransmission();  
}

// バッファのクリア
void ht_clear_buffer() {
    for (uint8_t i = 0; i <8; i++) 
      buf[i] = 0;
}

// 表示のクリア
void ht_clear() {
  ht_clear_buffer();
  ht_update();
}

// バッファの指定座標のON/OFF
void ht_set_dot(int8_t x, int8_t y, uint8_t d) {
  if ( (x > 7) || (y > 7) || (x < 0) || (y < 0) ) 
     return;     
  if (d)
    buf[y] |= 0x80 >> x;
  else
    buf[y] &= ~(0x80 >>x);  
}

// バッファ上の指定座標に8x8パターンをセット(負座標指定可能)
void ht_write_at(uint8_t* p, int8_t x, int8_t y) {
    int8_t i; 
    if ((x > 7) || (y > 7) || (x < -7) || (y < -7) ) 
        return;
    for (i = 0; i <8; i++) {
        if ((i+y >= 0) && (i+y < 8) ) {
           if (x >= 0)
              buf[i+y] |= p[i]>>x;
           else
              buf[i+y] |= p[i]<<(-x);
        }
    }
}

// バッファ左スクロール
void scroll() {
   for (uint8_t i = 0; i < 8; i++) {
      buf[i]<<=1;  // 各行を左にシフトする
   }
}

// 1文字左スクロール挿入
void ht_scrollIn(uint8_t* p, int wt) {
    int8_t i,j;
    for (j = 0; j < 8; j++) {
        for (i = 0; i < 8; i++) {
            buf[i]<<=1;
        }
        ht_write_at(p, 7-j, 0);
        ht_update();
        delay(wt);
    }
}

void setup() {
   ht_init();
   ht_clear();
}

// デモ1 ドット表示チェック
void demo1() {
  ht_clear();
  for (int8_t d = 1; d >= 1; d--) {
    for (int8_t y = 0; y <8; y++) {
      for (int8_t x = 0; x <8;  x++) {
         ht_set_dot(x, y, d);
         ht_update();
         delay(75);
      }
    } 
    delay(500);
  }
  for (int8_t i = 0; i <8; i++) {
    scroll();
    ht_update();
    delay(100);    
  }
}  

// デモ2 パターンを指定座標の表示
void demo2() {
   ht_clear();
   for (uint8_t i = 0; i <4; i++) {
        ht_clear_buffer();
        ht_write_at(msg_saitama[i], 0, 0);
        ht_update();
        delay(1000);  
   }
}

// デモ3 パターンをスクロールイン表示
void demo3() {
   ht_clear();
   for (uint8_t i = 0; i <4; i++) {
        ht_scrollIn(msg_saitama[i], 150);  
   }
}
 
void loop() {  
   demo1();
   delay(1000); 
   demo2();
   delay(1000); 
   demo3();
   delay(1000); 
}

次に美咲フォントを利用してちょっとした日本語表示をやってみます。
aitendo I2CマトリックスキットをArduino動かしてみました (2)  に続きます。

ATtiny13Aの省電力化を試みる

前回の「ATtiny13Aをシステムクロック16kHzで利用する」でシステムクロックを落とすことで
省電力化を図りました。

更に省電力化する方法はないかと調べると次の対策があることが分かりました。

1)アナログコンパレータを停止する
    これにより消費電流が100μAほど抑えられるようです。

2)必要に応じてsleepさせる
    次の関数を使って、delayによる内部ループ待ちはせずに、CPUを必要にお応じて
    停止させる。
    set_sleep_mode(SLEEP_MODE_IDLE)
    sleep_mode()

   SLEEP_MODE_IDLEを指定したときはタイマーは可動しておりタイマー割り込みの
   利用が可能です。このタイマー割り込みを使って定期的にCPUを起こして処理し
   また寝るようにします。

実際に前回のソースを修正して試して見ました。
// アナログジョイスティック デジタル出力変換 for Lame Station
//
//       ATMEL ATTINY13 / ARDUINO
//
//                 +-\/-+
// ADC0 (D 5) PB5 1|    |8 Vcc
// ADC3 (D 3) PB3 2|    |7 PB2 (D 2) ADC1
// ADC2 (D 4) PB4 3|    |6 PB1 (D 1) PWM1
//            GND 4|    |5 PB0 (D 0) PWM0
//                 +----+

#include <avr/sleep.h>

// ピンの割り付け
#define J_UP    PB1  // UP 出力
#define J_DOWN  PB0  // DOWN 出力
#define J_RIGHT PB5  // RIGHT 出力
#define J_LEFT  PB2  // LEFT 出力

// アナログ入力ピンの割り付け(要ピン番号で指定)
#define IN1     2  // ジョイスティック UP/DOWN 
#define IN2     3  // ジョイスティック LEFT/RIGHT

void setup() {
  ACSR |= _BV(ACD);  
  pinMode(J_UP,OUTPUT);
  pinMode(J_DOWN,OUTPUT);
  pinMode(J_RIGHT,OUTPUT);
  pinMode(J_LEFT,OUTPUT); 
  
  set_sleep_mode(SLEEP_MODE_IDLE); // アイドルモードに設定
}

void readjoystic() {
  int v1,v2;
  int s1 = analogRead(IN1);
  int s2 = analogRead(IN2);
  
  if (s1 < 50) {
     digitalWrite(J_DOWN, LOW);
     digitalWrite(J_UP, HIGH);
     
  } else if (s1 > 973) {
     digitalWrite(J_UP, LOW);
     digitalWrite(J_DOWN, HIGH);
     
  } else {
     digitalWrite(J_UP, LOW);
     digitalWrite(J_DOWN, LOW);
  } 
  
  if (s2 < 50) {
    digitalWrite(J_RIGHT, LOW);
     digitalWrite(J_LEFT, HIGH);
  } else if (s2 > 973) {
     digitalWrite(J_LEFT, LOW);
     digitalWrite(J_RIGHT, HIGH);
  } else {
    digitalWrite(J_RIGHT, LOW);
    digitalWrite(J_LEFT, LOW);
  }
}

void loop() {
  readjoystic();
  sleep_mode();
}

アナログコンパレータの利用停止はsetup()内のACSR |= _BV(ACD) で設定しています。

次にスリープですが、私が利用しているsmeezekittyさん公開の「Arduino core for Attiny13
は内部的にdelay用にタイマー割り込みを使っており、256サイクルに1回割り込みが
発生するようになっています。

システムクロックが16kHzなので割り込みは62.5Hz(1秒にだいたい60回)です。
この間隔でのジョイスティックの読み込みでも実用的だと思い、ソースには単純に
setup()でset_sleep_mode(SLEEP_MODE_IDLE)、loop()でsleep_mode()を入れるだけ
としました。
(だだし、 readjoystic()の処理が1/62.5秒以上かかる場合は意味なしですが)

実際に動かして電流を測定してみると、前回の1.27mAから0.13mAほど減りました。
アナログジョイスティックが0.70mAほど流れるのでATtiny13A単体では0.44mAです。

ただし、スリープと稼働の繰り返しで電流変動が変動するため、私の安いテスター
では正確には測れていないと思います。

Dscn4702

まあ、効果はあるようなのでこの修正でいってみます。

2016年1月19日 (火)

Raspbian Jessie のGPIOまわりの利用権限

Raspbian Jessieで普段使っている アカウント pi の所属グループは、

01

となっていて上記のグループが利用権限を持つディバイスの利用が可能です。

02

もし新たにユーザを登録してそのユーザでGPIOまわりを利用する場合は
そのユーザを各グループに登録すれば利用できるようになります。

ユーザ hoge を グループ dialout に登録するコマンド
$ sudo adduser hoge dialout

他のLinux系だと
$ sudo gpasswd -a hoge dialout

2016年1月17日 (日)

Arduino IDE 1.06にATtiny13A開発を構築

smeezekittyさんが公開している「Arduino core for Attiny13(core13_022_arduino_1_6.zip)」を
Arduino IDE 1.06環境に導入するための作業メモです。

はじめに
このモジュールを導入することで、Arduino IDE上にてAttiny13Aをターゲットとした開発が行えます。
ただし、別途書き込み機器(USBaspやArduinoISP等)が必要です。

蛇足:aitendoのATTiny ISPシールドきっと [K-TINY-SLD] なんかお手軽で良さそうです。
    説明が無いですがarduino経由でArduinoISPにて書込む形式のようです。

             05


smeezekittyさん公開モジュールはシステムクロックの128kHz、600kHz、1.2MHz、4.8MHz、9.8MHzのに対応しており、
ブートローダの書き込みによってヒューズビットの書き込みが行われます。

「Arduino core for Attiny13」は定期的に更新されており、現在のバージョンはV0.22です。
いくつかの関数がAttiny13用にメモリ消費を抑えるよう最適化されています。

必要とするモジュールおよび入手先
Core13 prealpha - Arduino core for Attiny13

関連情報
Arduino Forum >  Using Arduino >  Microcontrollers >  core13: An Arduino core for the Attiny13 *testers wanted*

導入手順
1)モジュールのダウンロードと解凍
  ・入手先のリンクのサイトからcore13_022_arduino_1_6.zipをダウンロードして解凍します。

2)モジュールのインストール
  ・Arduino IDE 1.0.6をインストールしたディレクトリの
      E:\Arduino\IDE\arduino-1.0.6\hardware\
   に、解凍したcore13モジュールの\attiny13にある \avrフォルダをコピーします。

  ・コピーしたavrフォルダの名前をattiny13に変更します。

  ・attiny13フォルダにあるboads.txtの内容を次の内容に変更します。   

attiny13a.name=Attiny 13A standalone 128khz
attiny13a.upload.maximum_size=1024
attiny13a.maximum_data_size=64
attiny13a.upload.speed=19200
attiny13a.bootloader.low_fuses=0x7b
attiny13a.bootloader.high_fuses=0xFF
attiny13a.build.mcu=attiny13
attiny13a.build.f_cpu=128000L
attiny13a.build.core=core13
#######################

attiny13b.name=Attiny 13A standalone 600khz
attiny13b.upload.maximum_size=1024
attiny13b.maximum_data_size=64
attiny13b.upload.speed=19200
attiny13b.bootloader.low_fuses=0x69
attiny13b.bootloader.high_fuses=0xFF
attiny13b.build.mcu=attiny13
attiny13b.build.f_cpu=600000L
attiny13b.build.core=core13
#######################

attiny13c.name=Attiny 13A standalone 1.2mhz
attiny13c.upload.maximum_size=1024
attiny13c.maximum_data_size=64
attiny13c.upload.speed=19200
attiny13c.bootloader.low_fuses=0x6a
attiny13c.bootloader.high_fuses=0xFF
attiny13c.build.mcu=attiny13
attiny13c.build.f_cpu=1200000L
attiny13c.build.core=core13

#######################
attiny13d.name=Attiny 13A standalone 4.8Mhz
attiny13d.upload.maximum_size=1024
attiny13d.maximum_data_size=64
attiny13d.upload.speed=19200
attiny13d.bootloader.low_fuses=0x79
attiny13d.bootloader.high_fuses=0xFF
attiny13d.build.mcu=attiny13
attiny13d.build.f_cpu=4800000L
attiny13d.build.core=core13
#######################
attiny13e.name=Attiny 13A standalone 9.6Mhz
attiny13e.upload.maximum_size=1024
attiny13e.upload.speed=19200
attiny13e.maximum_data_size=64
attiny13e.bootloader.low_fuses=0x7A
attiny13e.bootloader.high_fuses=0xFF
attiny13e.build.mcu=attiny13
attiny13e.build.f_cpu=9600000L
attiny13e.build.core=core13

これで完了です。
Arduino IDEのメニュー ツール - マイコンボードに
ATtiny13Aの 128kHz、600kHz、1.2MHz、4.8MHz、9.8MHzが追加されます。

ただし、利用する書き込み機器によっては低速クロックを指定した場合、
低速に対応していないために書き込みに失敗する場合があります。

私の手持ちのUSBaspでは600kHzまでしか書き込み出来ませんでした。
本家のUSBaspにはジャンパスイッチによるLow speed設定が出来るようですが、
私のものにはありません。自動調整機能があるようですが128kHzには対応していないようです。

また、デフォルトのArduinoISP(arduino IDEのスケッチを利用)の利用では1.2MHzでもエラーになりました。

低速クロックを利用する方法としては、私は「ArduinoISP slow SCK」を利用しています。
Arduino IDEにあるArduinoISPの代わりに使います。

入手先
ArduinoISP slow SCK - https://github.com/lmpipaon/ArduinoISP_slow_SCK

さらにこれをArduino IDEから利用するために
\hardware\arduinoフォルダにある programmers.txt の最後に次の内容を追加します。

arduinoisp_low.name=Arduino as ISP(low speed)
arduinoisp_low.communication=serial
arduinoisp_low.protocol=stk500v1
arduinoisp_low.speed=2400

これで書込装置のメニューに追加されます。

Ide01

書込み機器が低速に対応していないで、ブートローダを書きこんでエラーが発生すると
以後ATtiny13Aへの書き込みが出来なくなる場合があります。

この状態から復活するには高圧12Vでのヒューズビットのリセット(書き込み)をする必要があります。これについては「ATtiny13Aのヒューズビットのリセット」を参照して下さい。


ATtiny13Aをシステムクロック16kHzで利用する

まずは、ATtiny13Aをシステムクロック16kHzで利用する目的のお話しです。

プロペラをつかったホータブルゲーム機LameStationのジョイスティック部が次のような感じで
コンパレータLM339を使ってアナログ2入力をUP、DOWN、LEFT、RIGHTのON/OFF出力に変換
する形式となっています。

01

部品的には抵抗10本、IC(LM339)1個の利用とその配線となります。
この部分をADコンバーター機能を持つ「手持ちのATtiny13Aで置き換えれば簡略化出来るのでは?」
と思いつきやってみました。

動作確認と実装


まずは次ような感じの動作チェック回路を実装し確認しました。
ジョイスティックからのアナログ値を取得しその方向をON/OFFで出力します。
2入力4出力のため6ピン必要となり、リセットピンも利用しました。

02

プログラムソースは下記のようになります。
Arduino IDE 1.06環境にてsmeezekittyさんが公開している
「Arduino core for Attiny13(core13_022_arduino_1_6.zip)」を導入して利用しています。

03

// アナログジョイスティック デジタル出力変換 for Lame Station
//
//       ATMEL ATTINY13 / ARDUINO
//
//                 +-\/-+
// ADC0 (D 5) PB5 1|    |8 Vcc
// ADC3 (D 3) PB3 2|    |7 PB2 (D 2) ADC1
// ADC2 (D 4) PB4 3|    |6 PB1 (D 1) PWM1
//            GND 4|    |5 PB0 (D 0) PWM0
//                 +----+

// ピンの割り付け
#define J_UP    PB1  // UP 出力
#define J_DOWN  PB0  // DOWN 出力
#define J_RIGHT PB5  // RIGHT 出力
#define J_LEFT  PB2  // LEFT 出力

// アナログ入力ピンの割り付け(要ピン番号で指定)
#define IN1     2  // ジョイスティック UP/DOWN 
#define IN2     3  // ジョイスティック LEFT/RIGHT
 
void setup() {
  pinMode(J_UP,OUTPUT);
  pinMode(J_DOWN,OUTPUT);
  pinMode(J_RIGHT,OUTPUT);
  pinMode(J_LEFT,OUTPUT); 
}

void loop() {
  int v1,v2;
  int s1 = analogRead(IN1);
  int s2 = analogRead(IN2);
  
  if (s1 < 50) {
     digitalWrite(J_DOWN, LOW);
     digitalWrite(J_UP, HIGH);
     
  } else if (s1 > 973) {
     digitalWrite(J_UP, LOW);
     digitalWrite(J_DOWN, HIGH);
     
  } else {
     digitalWrite(J_UP, LOW);
     digitalWrite(J_DOWN, LOW);
  } 
  
  if (s2 < 50) {
    digitalWrite(J_RIGHT, LOW);
     digitalWrite(J_LEFT, HIGH);
  } else if (s2 > 973) {
     digitalWrite(J_LEFT, LOW);
     digitalWrite(J_RIGHT, HIGH);
  } else {
    digitalWrite(J_RIGHT, LOW);
    digitalWrite(J_LEFT, LOW);
  }
}

Arduino IDE環境ではシステムクロック 128kHzまでしか対応していないので、
プログラム書き込み後、リセットピンを出力に使うためのリセット禁止とシステムクロックを
16kHzに設定するためにヒューズビットを設定を行います。

作業はコマンドプロンプトにてavrdueコマンドを使って行います。

04

実行コマンド
avrdude -carduino -Pcom6 -pt13 -U lfuse:w:0x6b:m -U hfuse:w:0xfe:m -v -F -b2400
(書き込み機器はarduinoを利用した"Arduino as ISP"です)

ヒューズビットの設定値を簡単に調べるには次のサイトが便利です。
Engbedded Atmel AVR® Fuse Calculator

注意:RESET禁止またはシステムクロックを低速にすると、プログラム書き込みとヒューズビットの
設定が通常環境では出来なくなります。高電圧書き込みにてヒューズビットのリセット
が必要となります。


書き込み後、実装して動作確認をいたします。

Dscn4688

問題無く動作しているようですが、RSETピンの出力が弱いです。

Dscn4689

微妙にしか点灯しません。
この現象がなぜなのか、悩んだのですがSNS上のアドバイスにより理由が判明しました。

Reset
上記の"The reset pin can also be used as a (weak) I/O pin."のweak(弱い)がこの現象の理由のようです。
信号には使えるが、LEDの駆動には使えないくらい弱いようです。
信号として利用するには問題無いでしょう。

LEDが点灯していない状態で電池からブレットボードに流れる電流を測定すると、
1.27mAでした。予想よりも消費電力が大きいと思ったのですが、
アナログジョイスティックに流れる電流を測定したところ、0.70mAほどでしたので、
ATtiny13A単体では0.57mA程度と思われます。

ATtiny13A を 9.6MHzで動かすと、2.66mAなのでクロックを落とすことで消費電力化
が図れるのは確かなようです。

Dscn4692

実際、プロペラ lumestationに組み込んで利用してみるとリセットピンからの
ON/OFFの信号も問題なく読み取れました。

Dscn4690

これでジョイスティック入力が出来ました。SDKに付属のゲームで遊べました。

Dscn4691

結論と感想
ATtiny13Aをシステム16kHzで利用しても問題なく利用出来ました。
むしろ、こういう使い方こそ50円マイコンにふさわしいと言えますね。

2016年1月16日 (土)

ATtiny13Aのヒューズビットのリセット

ATtiny13Aをシステムクロック128kHzで稼働させる模索中にミスにより4個が
文鎮状態(brick状態)になってしまいました。

原因としては、ヒューズビットの設定をミスしてリセット不能・低速過ぎて書き込み機器で
の通信が行えないことが考えられます。ヒューズビットをリセットすれば復活出来るかも
しれません。

復活方法を調べてると、高電圧12Vによる書き込み方法があると知り早速試してみました。

次の記事を参考にして試してみました(情報公開に感謝します)
tadfmacさんのHP 「Arduino UNOでATTiny開発してるときに書き込めない!AVR壊れた!?その前に」
Wayne's Tinkering Page さんのHP 「ATTiny Fuse Reset」

回路図およびスケッチ(プログラム)は「ATTiny Fuse Reset」をほぼそのまま利用させて頂きました。
ただしトランジスタは、2N3904ではなく手持ちの2SC1815GRを利用しました。

Dscn4684

12Vの電圧はACアダプタから供給し、ボード上のVinピン(写真の黄色線)から取得しました。
操作等のツールの使い方はtadfmacさんの記事を参考にしました。

無事に復活出来ました。
これで、色々とムチャな実験をしても復活できる手段を取得出来ました。

2016/01/17 追記

便利な機能なのでシールド化しました。
リセッター機能だけではもったいないので、プログラマ機能としてArduinoISPで
利用出来るようにしました。

Dscn4686

2016年1月10日 (日)

Propeller始めました(16) ポータブルゲーム機の実装 1

LameStationのサイトの情報を元にポータブルゲーム機を実装することにしました。

Dscn4679

まずは一番のかなめである液晶ディスプレイを実装してみました。
LameStationのサイトの解説では、KS0108 LCDを利用しているとの記載があります。
そこで、手持ちの秋月の「LCDグラフィック・ディスプレイモジュール(液晶表示器)TG12864B-02WWBV」
を試したところ、問題なく表示出来ました。

Dscn4673

この液晶ディスプレイは2色表示のはずですが、PWM的な操作で見た目上の
中間色を再現しています。若干中間色のドットはチラつきが発生します。

若干、液晶の表示速度が遅いようでスプライト表示のデモプログラムを試したところ、
見えにくい状況でした。

液晶モジュールとプロペラ間のデータ通信の結線には15Ωの抵抗が入っています。
ダンピング抵抗というものだそうです。なくても動くようですが、とりあえず回路図に
従って入れました。

次は、ジョイスティックまわりを実装して操作が出来るようにしてみます。



2016年1月 7日 (木)

ゲームコンソールキット LameStation

面白そうなキットを見つめました。
LameStationという製品で プロペラを使ったポータブルゲームコンソールキットのようです。

http://www.lamestation.com/

似たようなキットはいくつか存在しますが、解説ドキュメントの内容が丁寧で素晴らしいです。
LameStation Manual Latest Home https://lamestation.atlassian.net/wiki/display/LAME/

キットは日本からの購入は出来ないようですが、回路図や必要パーツが公開されているので、
自力で部品を集めて自作したいですね。

2016年1月 5日 (火)

Raspberry Pi 2でLEDドットマトリックスを制御してみました

以前作成したI2C接続で利用するLEDドットマトリックスをラズパイに繋げて制御してみました。

Dscn4664

I2C接続で制御します。電源は直接ラズパイから供給しています。
4線だけの接続で済みました。

LEDドライバにはHT16K33を利用しています。
HT16K33は、ピン数のことなるバージョンがいくつかあるようですが、
28ピンの8x16の制御ができるバージョンを使っています。





動いている様子


プログラムはC言語で実装しました。GPIOまわりの制御は wiringPiライブラリを利用しました。

// file : matrix.c
// Raspberry Pi 8x16LEDマトリック表示制御 by たま吉さん 2016/1/5
// I2C接続LEDドライバHT16K33を使った8x16のLEDマトリックスを制御する
//

#include <stdio.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>

#define I2CADR 0x70 // I2Cアドレス

// HT16K33コマンド
#define HT_CMD_DATA 	 	0x00	// データ送信 
#define HT_CMD_SYSSET  		0x20	// システムセットアップ
#define HT_CMD_BLINK	  	0x80	// 点滅表示周期の設定
#define HT_CMD_BRIGHTNESS 	0xE0	// 明るさの設定

// HT16K33 レジスタ設定値
#define HT_SYSSET_OSC_ON	1

// HT16K33 点滅表示周期 設定値
#define HT_BLINK_OFF	    	0
#define HT_BLINK_DISPLAY_ON 	1
#define HT_BLINK_2HZ	    	2
#define HT_BLINK_1HZ	    	4
#define HT_BLINK_05HZ   	6

// グローバル変数
int fd;                		 // I2Cファイルデスクプリタ
unsigned short buf[8];  	// 8x16ドットパターン

// サンプルパターンデータ
char msg_saitama[][8] = { 
	 { 0x08, 0x08, 0x7E, 0x04, 0x24, 0x40, 0x3C, 0x00 },    // さ
	 { 0x00, 0x88, 0x84, 0x82, 0x82, 0x50, 0x20, 0x00 },    // い
	 { 0x20, 0xF0, 0x2E, 0x40, 0x48, 0x50, 0x8E, 0x00 },    // た
	 { 0x08, 0x7E, 0x08, 0x7E, 0x08, 0x7C, 0x7A, 0x00 },    // ま
};

// HT16K33 コマンド送信
void ht_cmd(char cmd, char prm) {
	wiringPiI2CWrite(fd, cmd|prm);
}

// 表示パターンの送信
void ht_update() {
	int i;
	for (i = 0 ; i < 8; i++) {
		wiringPiI2CWriteReg8(fd, i*2,  buf[i] & 0xff);
		wiringPiI2CWriteReg8(fd, i*2+1,buf[i] >> 8);
	}
}

// バッファクリア
void ht_clear_buffer() {
	int i;
  	for (i = 0; i < 8; i++) {
    	buf[i] = 0;
  	}
}

// 表示のクリア
void ht_clear() {
	ht_clear_buffer();
	ht_update();
}

// バッファの指定座標のON/OFF
void ht_set_dot(int x, int y, int d) {
	if (d) {
		buf[y] |= 0x8000 >>x;
	} else {
		buf[y] &= ~(0x8000 >>x);
	}
}

// バッファ上の指定座標に8x8パターンをセット(負座標指定可能)
void ht_write_at(char* p, int x, int y) {
	int i;

	if ((x > 15) || (y > 7) || (x < -7) || (y < -7) ) 
		return;

	for (i = 0; i <8; i++) {
		if ((i+y >= 0) && (i+y < 8) ) {
		   if (x <= 8)
		      buf[i+y] |= p[i]<<(8-x);
		   else
		      buf[i+y] |= p[i]>>(x-8);
		}
	}
}

// 1文字左スクロール挿入
void ht_scrollIn(char* p, int wt) {
	int i,j;
	for (j = 0; j < 8; j++) {
		for (i = 0; i < 8; i++) {
			buf[i]<<=1;
		}
		ht_write_at(p, 15-j, 0);
		ht_update();
		delay(wt);
	}
}

// HT16K33 初期化
void ht_init() {
	ht_cmd(HT_CMD_SYSSET, HT_SYSSET_OSC_ON);
	ht_cmd(HT_CMD_BLINK,  HT_BLINK_DISPLAY_ON | HT_BLINK_OFF);
	ht_cmd(HT_CMD_BRIGHTNESS, 0);
}

// メイン
int main(void) {
	int  i,x,y;

	// GPIO利用のための初期化
	wiringPiSetup();
	// HT16K33の初期化
	fd = wiringPiI2CSetup(I2CADR);
	ht_init();
	
	// デモ
	while(1) {
		// デモ1 ドット表示
		for (i =1; i >=0; i-- ) { 
			for ( y=0; y < 8; y++) {
				for ( x=0; x < 16; x++) {
					ht_set_dot(x,y, i);
					ht_update();
					delay(10);
				}
			}
		}
	  	// デモ2 'さいたま' 表示
		for (i = 0; i <4; i++) {
			ht_scrollIn(msg_saitama[i], 100);  
		}
		delay(500);
		ht_clear();
 	}
 	return 0; 
}

コンパイルは、
$ gcc -o matrix matrix.c -lwiringPi
とします。

美咲フォントを使って、コマンド引数に任意も文字列を指定して表示出来るようにしようと思います。

Raspberry Pi 2(Raspbian Jessie) のGPIOのシリアルポートを使う

Raspberry Pi 2のOSをRaspbian Jessieにアプグレードしました。

2016/04/18 追記
/boot/cmdline.txtの修正について追記しました。

01

ボード上のGPIOのシリアルピンを使う場合、
デフォルトでは1)システムコンソール出力(printk()の出力)と、2)コンソールログイン(getty)に
利用されており、それらに利用されないように設定する必要があります。

1)の対応は、/boot/cmdline.txt の定義を修正します。
具体的には "console=ttyAMA0,115200 kgdboc=ttyAMA0,115200" を削除し、
  dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4
  elevator=deadline rootwait

となります。

ただし、これでもシャットダウンとリブート時等に若干メッセージが出力されるみたいです。
一時的なら/proc/sys/kernel/printk の設定変更でも良いかもしれません(未確認)。

2)は/etc/inittabを開いて修正しようとすると、ファイルがありません。
JESSIEではシステムまわりがsystemdに移行しため、無くなったんですね。

色々と調べ、次のような感じでコンソール(getty)の利用設定が出来るようです。

停止/開始
$sudo systemctl stop serial-getty@ttyAMA0.service
$sudo systemctl start serial-getty@ttyAMA0.service

自動起動の有効/無効
$sudo systemctl enable serial-getty@ttyAMA0.service
$sudo systemctl disable serial-getty@ttyAMA0.service

参考情報
  adafruit RASPBERRY PI - Using UART instead of USB
  Raspberry PIのGPIO上シリアルとArduinoの通信

コンソール(getty)の利用を停止したのち、
シェルプロから直接/dev/ttyAMA0をいじって入出力をする場合、
通信速度や制御コードを送らない設定は従来と同じでsttyコマンドを使います。

$sudo systemctl stop serial-getty@ttyAMA0.service
$sudo chmod o+rw /dev/ttyAMA0
$sudo stty -F /dev/ttyAMA0 115200 \
-iuclc -ixany -imaxbel -iutf8 -opost -olcuc -ocrnl -onlcr \
-onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 -isig \
-icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase \
-tostop -echoprt -echoctl -echoke

確認として
$cal 2016 > /dev/ttyAMA0

でカレンダーのテキスト文字をTeraTermに送信出来ました。

シェルプロから/dev/ttyAMA0を使う場合は状況に応じて環境変数IFSの設定も必要ですね。
このあたりの話は、以前まとめた下記の記事が参考になると思います。
 ・参考記事 「Linuxで直接シリアルデバイスを利用する際の注意点等」

試しにラズパイにIchigoJamをシリアル接続してIchigoJamのファームウェアの更新を
行ってみたところ、問題なく更新出来ました。
接続
   ラズパイ ピン番号08:GPIO14/TXD(UART0) -> IchigoJam RxD
   ラズパイ ピン番号10:GPIO15/RXD(UART0) -> IchigoJam TxD
   ラズパイ ピン番号06:GND                         -> IchigoJam GND

Dscn4666

更新にはlpc21ispを使いました。
$sudo systemctl stop serial-getty@ttyAMA0.service
$sudo lpc21isp -control -bin ichigojam-xtal.bin /dev/ttyAMA0 115200 12000


USB-UARTモジュール不要なのでこれはこれでお手軽かもしれません。

からソースをダウンロードしてコンパイルしました。
$unzip lpc21isp_197.zip
$cd lpc21isp_197
$make
$sudo cp lpc21isp /usr/local/bin

systemdについては、まだ理解出来ていませんが、下記のサイトのスライドを見て概要は理解出来ました。
  「Linux女子部 systemd徹底入門」  http://www.slideshare.net/enakai/linux-27872553

systemdまわりが理解出来たら、自宅のCenOSサーバーも6から7にアップグレードしようと思います。

2016年1月 3日 (日)

Propeller始めました(15) 温度センサーSTTS751を試してみる

ADコンバーター機能を持たないプロペラで温度を測定したいと思い、
「高精度12ビットI2C接続デジタル温度センサ STTS751」を試してみました。
秋月電子で1個100円で販売されているものです。

主な仕様
・型番       STTS751-0WB3F
・パッケージ      SOT-23-6 (6ピン)
・インタフェース  I2C (4種類のアドレス設定可能)
・電源電圧        2.25 ~ 3.6V
・測定温度範囲  -40 ~ 125℃
・分解能               9 ~ 12ビット(設定可能)

実際の製品画像

02

変換基板にて6ピンDIPに変換します。

Dscn4662

取りあえず、使い方としては次のような感じで接続します。
Addr/Thermピン、EVENTピンにてI2C経由とは別の通知機能(出力)がありますが、
今回は使わないのでGNDに接続しています。

03_2

Addr/Thermピンはプルアップ抵抗にてアドレスの設定を行うことが出来ます。



7.5K~33KΩのプルアップ抵抗にて 4つの異なるアドレスを指定することが出来ます。
GNDに接続した場合の仕様についても記載があり、Note:の箇所にアドレスが
device STTS671-0 の場合は 72h となります。

なので、抵抗なしで I2Cスレーブアドレスは 72h となります。

自作プロペラボードにて動作確認してみます。

Dscn4661

プログラムソース(Spinコード)下記のような感じとなります。

{{
 I2C接続温度センサ STTS751を使う
}}

CON
    {システムクロック設定 6Hhz×16=96Mhz}
    _clkmode = xtal1 + pll16x
    _xinfreq = 6_000_000
    
    I2CADR  = $72    'I2Cスレーブアドレス
    SCL_PIN =  28    'I2C SCLピン番号
OBJ
    i2c     : "Basic_I2C_Driver_1"
    cn      : "Parallax Serial Terminal"

{メイン処理}

PUB main | v,tH,tL,s,t1,t2, dt
    cn.Start (115200)
    i2c.Initialize(SCL_PIN)
    
    '設定
    stts751_writeByte(3,%1000_11_00)    'Configurationレジスタの設定   :EVENT無効、解像度12ビット
    stts751_writeByte(4,5)              'Conversion rateレジスタの設定 :1秒間に2回サンプリング
    
    '製品情報取得
    v := stts751_readByte($fd)
    cn.Str (string("Product ID register: "))
    cn.Hex (v,2)
    cn.str (string("h",13))
    
    v := stts751_readByte($fe)
    cn.Str (string("Manufacturer ID: "))
    cn.Hex (v,2)
    cn.str (string("h",13))

    v := stts751_readByte($ff)
    cn.Str (string("Revision number: "))
    cn.Hex (v,2)
    cn.str (string("h",13))
   
    '温度データ取得
    repeat
        tH:= stts751_readByte(0) '上位
        tL:= stts751_readByte(2) '下位(小数点以下)
        s := tH & $80            '符号取得
        t1:= th & $7f
        t2:= 0
        if tL & %1000_0000 <> 0
            t2+= 5000
        if tL & %0100_0000 <> 0
            t2+= 2500
        if tL & %0010_0000 <> 0
            t2+= 1250
        if tL & %0001_0000 <> 0
            t2+= 625

        cn.Str (string("temperture: "))
        if s <> 0
            cn.str (string("-")) '0度以下の場合、符号表示                   
        cn.dec(t1)
        cn.str(string("."))                    
        cn.dec(t2)
        cn.Char (13)                    
        waitcnt(cnt+80_000_000)      

{
  STTS751のレジスタ値参照
  adr : レジスタアドレス
  戻り値: レジスタ値
}
PUB stts751_readByte(adr)
    '参照レジスタの設定
    i2c.Start(SCL_PIN)
    i2c.Write(SCL_PIN, I2CADR)
    i2c.Write(SCL_PIN, adr)

    '1バイトデータ取得
    i2c.Start(SCL_PIN)    
    i2c.Write(SCL_PIN, I2CADR|1)
    result := i2c.Read(SCL_PIN,1)
    i2c.Stop(SCL_PIN)

{
  STTS751のレジスタ値設定
  adr : レジスタアドレス
  d   : 設定値  
  戻り値: なし
}
PUB stts751_writeByte(adr,d)
    '参照レジスタの設定
    i2c.Start(SCL_PIN)
    i2c.Write(SCL_PIN, I2CADR)
    i2c.Write(SCL_PIN, adr)
    i2c.Write(SCL_PIN, d)

実行結果はこんな感じです。

01

プログラム的にはデバイスの初期設定として、EVENTを使わない設定と解像度を12ビット
とする指定とサンプリング周期を1秒に2回としています。
初期化後は、製品情報を表示後、1秒間隔で温度データを取得して表示しています。

プロトコル的には非常にシンプルなので3.3V系のARMベースのラズパイ、Icihgojamでも
簡単に使えると思います。

2016年1月 1日 (金)

2016年がスタートしました

2016年がスタートしました。とりあえず明けおめ!

子供の頃と比べると年末年始の伝統というか文化的というか、イベント性が薄れて
来ています。今年は暖冬のせいか季節の移り変わり感も薄く、今一新年という実感がないです。

去年は特に変わりなく比較的良い年でした。ブログの趣旨のIT的には、
Windows 10の導入、ラズパイ、ARM系電子工作に着手、プロペラの電子工作に着手と
新しいことにもチャレンジしてみました。
今年はロボットなどの動きのある電子工作にチャレンジしてみようと思います。

もう一つの趣旨の猫的には、我が家の愛猫さん達は怪我や病気もなく元気です。

猫のたま吉さんは、ほとんど毎日、仕事の帰宅時に玄関で出迎えてくれます。
玄関外から「ニャーニャー」泣いており、音で私だと識別できるようです。

Dscn4654

ルミちゃんは相変わらずの人見知りで、私以外には触れない状態です。
ただし、私に対しては甘えん坊で膝の上に乗って来たり、布団の中に
潜って来たりとベタベタ状態です。

喉を鳴らす音が爆音で鳴き声が「ぐぬっ」「ふんがー、ふんがー」と猫とは違う生物の
鳴き声で愛嬌のある猫です。

Dscn4650

1月1日の我が家の行事として墓参りに行って来ました。天気が良く一年の始まりの日
としては、良い日となりました。

« 2015年12月 | トップページ | 2016年2月 »