フォト
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      
無料ブログはココログ

« 2016年7月 | トップページ | 2016年9月 »

2016年8月の11件の記事

2016年8月31日 (水)

IchigoJamのシリアル通信速度の設定(BPSコマンド)について

IchigoJamの公式サイトのドキュメントが説明不足(実際は私の理解不足です^^)、
シリアル通信の速度の設定でちょっとハマりました。

IchigoJamでシリアル通信の速度設定はBPSコマンドを利用します。
下記は公式サイトのリファレンスマニュアルからの引用(見やすいようにちょっと修正)です。

BPS 数 / ビーピーエス:
  シリアル通信速度を変更する
        (0で初期値の 115,200bps、-1:57600bps、-2:38400bps)
  例: BPS 9600

IchigoJamにて38400bpsで通信したかったのですが、
BPS 38400

とやっても38400bpsで通信出来ません。データが化けます。なぜ?

  IchigoJam上
  01

  接続先 Tera Term
  02


実はIchigoJamの整数値の範囲が2バイト(short型)なので、
オーバーフローがおきてしまうんですね。オーバーフローが原因です。

次のようにやって、OKが出ているので 変数A34800が代入されていると思いきや、
表示してみるとマイナスの値です。

  05_2

なので、 BPS 38400  は実際には BPS -30736 として実行されたんですね。

ということで、
BPSコマンドのカッコ内の説明の BSP -2 を実行すると通信出来ました。

   IchigoJam上
  03

  接続先 Tera Term
  04

ただし、BPS引数-30736と指定してもエラーでないのはちょっと困りもの..
この場合、どういう通信速度になっているんでしょう..
(後でロジックアナライザーで調べてみます)

  06


2016年8月30日 (火)

Arduino IDEを使ったATtiny13用スケッチの開発について

ATtiny13用のプログラム(スケッチ)作成にはArduino IDEを使っています。

赤外線リモコン受信モジュール作成でATTiny13Aを利用したのですが、
環境によって動かない(どの環境を利用したか忘れた.. OTZ ..)

そこで、利用している開発環境を再認識するためまとめてみました(自分のためですが..)。
(現状、用途に合わせて複数使っています)

1)kosakalabさんが公開しているモジュール
    Arduino IDEでATtiny他の開発(Arduino-ISP編) / (AVRISP編)

    ATtiny13A以外の ATtinyシリーズにも対応しています。
    現状、いちばんちゃんと動くモジュールだと思います。

    ただしArduino IDE 1.0.6までの対応となります。
    またデフォルトでは低速クロックでの利用には未対応です。
    (例えばATtiny13A を128kHzで動かすなど)

2)smeezekittyさんが公開しているCore13 モジュール
    Core13 prealpha - Arduino core for Attiny13
        このモジュールはArduinoのフォーラムにて問題点や改善点が議論されています。
        core13: An Arduino core for the Attiny13 *testers wanted*

   Arduino IDE 1.0.X系(未確認)、1.6.x系(1.6.9にて確認済)で動作します。
   ATtiny13A の低速クロックにも対応しています。

   時間系の関数(特にmicros、mills)に若干問題があります。
   赤外線リモコン受信のデコード処理においてmicros()を使っているのですが、
   ちゃんと動作しませんでした( Arduino Unoと異なる仕様の挙動をする、正確でない)。 

   現在、ちょうどこの部分の問題が議論されているようです。
   (対策として、モジュール内のソースwiring.cを 1)のkosakalab のモジュールの
     wiring.c に差し換えると解消されます)

3)hansibullさんが公開しているMicroCore モジュール
    MicroCore(https://github.com/MCUdude/MicroCore)

    このモージュールは 2)のCore13をベースに使い勝手を良くしています。
    Core13ではピン指定が分かりにくかったのですが、きちんとドキュメント化しています。
    また、オプションを色々と指定出来て使いやすい環境です。   

    01

   Clock、GCCコンパイルオプション、書き込み装置(低速対応もあり)の指定が
   追加されています。
   2)では低速クロック128kHzで利用する際には、書き込み装置の低速対応を
   自分で行う(定義を追加する)必要がありました。

   このモジュールも2)のCore13と同様、時間系の関数に問題があります。
   (対策として、モジュール内のソースwiring.cを 1)のkosakalab のモジュールの
     wiring.c に差し換えると解消されます)

   時間系の関数(micros、mills、delay)取りあえず、精度が悪くても動けば良いので
   あれば、このモジュールの利用が一番おすすめです。

   一時、ボードマネージャーにてインストール出来る機構を公開していたのですが、
   現在は利用出来ないようです。

番外
   Spence Konde (aka Dr. Azzy)さん公開の
   SpenceKonde/ATTinyCore(https://github.com/MCUdude/MicroCore)   
    ATtiny13Aは未対応ですがそれ以外のATtinyシリーズに対応しているモジュールです。
    まだ利用していませんが、ATtiny85当たりを使う機会があれば利用しようと思います。

他にも色々とあるのですが、
上記2),3)の開発環境は今後もうちょっと改善される雰囲気ですので、この当たりの
利用が無難でしょう。3)はインストールと設定が簡単なので特に注目しています。

2016年8月29日 (月)

ATTiny13Aを使ってIchigoJamで赤外線リモコン受信を行う(1)

ここしばらく安価なLPC810を赤外線リモコンの受信処理に使っていたのですが、
LPC810が高騰して秋月電子では320円に..

ということで、「安価なATTiny13Aでやってみるか」と思い、実際にやってみると、
LPC810よりも簡単に出来てしまいました。

(以前作成したダイソー プチ電車の赤外線リモコン制御のスケッチを流用)

Dscn5651

回路図

Photo_2
これだと、パーツ的には100円位で実装出来ますね。

IchioJamには3線(3.3V->VCC、GND-> GND 、TxD-> RxD)を接続ます。
シリアルポートの通信速度は、ATiny13Aの都合で 38400bpsとなります。

受信した赤外線リモコンのボタンコード(1バイト)は、IchioJamのINKEY()コマンドで
取得出来ます。事前にボタンコードを調べる必要がありますが、普通のキーボード入力
と同じように処理出来ます。

20160829225214

実行すると赤外線リモコンのボタンに応じて操作出来ます。

20160829225252

プログラムを実行していない状態で、赤外線リモコンのボタンを押すと、
ボタンコードに対応する文字が画面に表示されます。

20160829225107

ATTiny13A用のプログラム作成はArduino IDE 1.06(+kosakalabさん公開モジュール)を使っています。
(ちょっと環境構築が面倒なので、後ほど別途記事にまとめます)

スケッチサイズは752バイトでした。
  ダウンロード IRremote_Ichigo.zip (1.8K)
  (シリアル通信用ライブラリBasicSerial3が別途必要です)

//
// 赤外線リモコン信号読み取り(IcigoJam連携バージョン)
// 2016/08/29 たま吉さん

//
//       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 BAUD_RATE 38400
#include <BasicSerial3.h>

// for I/O Port
#define IR    4
#define Rx    1
#define Tx    0

#define IR_DDR    DDRB
#define IR_PORT   PORTB
#define IR_PININ  PINB

#define IRbitRead()    (IR_PININ&_BV(IR))
#define RC_RDH_TS      9000    // リーダコードOFF間隔  9ms判定用
#define RC_RDL_TS      3800    // リーダコードON間隔   4.5ms判定用
#define RC_BITLOW_TS   1000    // ビットデータON間隔   1.69ms判定用  
#define RC_TMOVER      8000    // タイムオバー

//
// 赤外線リモコンコード取得
// 4バイトのデータを返す
// CCCCDDdd
//    CCCC カスタムコード
//    DD   データコード
//    dd   データコードのビット反転(データチェック用)
// ただし、
//    リピートコードの場合  0
//    エラーの場合          0xFFFFFFFF
//  を返す.
//
uint32_t Read_IR() {
  uint8_t  repeat = 0;  // リピートコード検出フラグ
  uint32_t  dt    = 0;  // 赤外線リモコン読み取りデータ
  unsigned long t ;     // 信号長計測用

  // リード部の取得
  // 受信データはH/L反転で読まれる
  while(1) {
    while(IRbitRead());  // OFF検出受信待ち   
    t = micros();        // OFF検出時刻取得
    while(!IRbitRead()); // ON受信検出待ち 
    t = micros() -t;     // OFF->ONの時間間隔取得
    if (t > RC_RDH_TS) { // 9ms以上ならリーダコードとみなす
        t = micros();      // ON検出時刻取得
        while(IRbitRead());// OFF検出待ち
        t = micros() -t;   // ON->OFF時間間隔取得
        break;
    }
  }
  
  // データ部取得
  if (t < RC_RDL_TS) {
    // 0N->OFF がリピートコードの場合、データ取得はスキップ
    repeat = 1;          
  } else {
    // 0N->OFF がリダーコードの場合、データを取得
     for (uint8_t i = 0; i <32; i++) {  //32ビット分取得ループ
        // ビット開始待ち
        while(!IRbitRead());  // ON待ち
        t = micros();
        while(IRbitRead());  // OFF待ち
        t = micros() -t;
        if (t>RC_TMOVER)
          return 0xFFFFFFFF;  // エラー
        dt<<=1;
        dt |= (t>RC_BITLOW_TS) ? 1:0;     
    }
  }
  // ストップビットの待ち
  while(IRbitRead());  // OFF待ち  
  if (repeat)
    return 0;
  return dt;
}

// 文字列出力
void serOut(const char* str) {
   while (*str) TxByte (*str++);
}

// 整数を16進数で出力
void serOutHex(uint16_t h) {
  uint8_t c;
  for (int8_t i=12; i>=0; i-=4) {
    c = h>>i & 0xf; 
    c = c >9 ? c+'A'-10: c+'0';
    TxByte ((uint8_t)c);
  }
}

void setup() {
  IR_DDR &= ~_BV(IR);  // IRピンのみ入力設定する
}
uint8_t prv =0;
void loop() {
  uint32_t rc =  Read_IR();  // IR受信
  if (rc) {
    if (rc != 0xFFFFFFFF) {
     TxByte((rc>>8)&0xff);
     prv=(uint8_t)((rc>>8)&0xff);
    }
  } else {
     TxByte(prv);
  }
}
 

LPC810と比べると、ATTiny13Aのプログラムの書き込みがちょっとハードルが高いのが難点です。

ブログ内関連記事
  Arduino IDEを使ったATtiny13用スケッチの開発について (2016/08/30)
 
  LPC810を使ってIchigoJamで赤外線リモコン受信を行う(4) (2016/08/17)
  LPC810を使ってIchigoJamで赤外線リモコン受信を行う(3) (2016/08/15)
  LPC810を使ってIchigoJamで赤外線リモコン受信を行う(2) (2015/06/06)
  LPC810を使ってIchigoJamで赤外線リモコン受信を行う(1) (2015/05/31)

  IchigoJamとArduinoでI2Cバス通信を試してみる (2) (2015/05/03)
  IchigoJamとArduinoでI2Cバス通信を試してみる (2015/05/01)

  ATtiny13Aで赤外線リモコン受信センサーを使う (2014/11/15)
  ATtiny13Aでシリアル通信(UART)を行う (2014/11/12)
  Arduino IDEでUSBaspを使ってATtiny13へプログラムの書き込み (2014/01/29)
  Arduino IDEでATtiny13でのLED点滅アプリの作成 (2014/01/26)

IchigoJam T用のお洒落なアクリルケース

工房Emerge+さんよりIchigoJam T用の「アクリルケース for IchigoJam T」を頂きました。

早速組み立てて装着しました。カッコよくなっていい感じになりました。

Dscn5650

このケース、良く考えられて設計されています。

全てのピンソケットへのアクセスが可能なのはもちろん、基板上のタクトボタン、
スライドスイッチ(電源用)もちゃんと操作出来るようになっています。

これで、部品が散乱している机でパーツ類と接触してショートなんかの心配無しです。

アクリルケース for IchigoJam Tはamazonでも購入出来ます。

2016年8月19日 (金)

Arduino用 美咲フォントライブラリ I2C EEPROMをGitHubにて公開

以前作成したArduino用の美咲フォントライブラリ I2C EEPROM版をGitHubにて公開しました。
(ほとんど自分で利用しやすくするための公開ですが..)

・Tamakichi/Arduino-misakiUTF16Full
   Arduino用 美咲フォントライブラリ I2C EEPROM乗せフルフォント版
   https://github.com/Tamakichi/Arduino-misakiUTF16Full
ブログでは、関連記事が分散してしまいバージョン的な視点で管理出来ないですね。
今後はブログでのソース配布は止めて、配布はGitHubに集約し、ブログには
GitHubへのリンクを貼る形式にしたいと思います。

美咲フォントLittle Limitさんが公開している8x8フォントです。
電子工作においては、大変重宝するフォントです(公開に感謝!!)

GitHub公開関連記事
  ・Tamakichi/Arduino-misakiUTF16
    Arduino用 美咲フォントライブラリ 教育漢字・内部フラッシュメモリ乗せ版
    https://github.com/Tamakichi/Arduino-misakiUTF16

  ・Tamakichi/Arduino-KanjiFont-Library-SD
    Arduino用のマルチサイズ漢字フォントを利用するためのライブラリ(SDカード版)
    https://github.com/Tamakichi/Arduino-KanjiFont-Library-SD

  ・Tamakichi/ESP8266-KanjiFont-Library-SPIFFS
    ESP8266用漢字フォントライブラリ SPIFFS版
    https://github.com/Tamakichi/ESP8266-KanjiFont-Library-SPIFFS

  フラッシュROM版も近いうちに登録します。
 
ブログ関連記事

結構、中途半端で終了している記事が多いですね。

2016年8月17日 (水)

LPC810を使ってIchigoJamで赤外線リモコン受信を行う(4)

作成した赤外線リモコン受信モジュールのテストとしてサーボモータを操作してみました。


IcigoJamのプログラムはこんな感じです。

20160817235717

赤外線リモコン受信、お手軽に遠隔操作でいて良い感じです。


サーボーモータは安価で省電力化で動作するSG90というのを2個使いました。
専用のカメラ用マウントに取り付けています。
SG90は秋月電子で1個 400円、Aliexpress で送料無料で1個 $1.2くらいです。マウントは$1.38くらい。

IchigoJamのVCC(3.3V)で2つモータを同時に動かせました。
3.3Vでも動いたけど、実際は4.8V~6Vが動作電圧なので別電源にて5Vを取った方がよいでしょう。

Dscn5619

IchigoJamのPWM出力について

下図の黄色記載部がPWMとして利用出来るピンです。OUTピンの2~5のピンとなります。

Ichigojam121

PWMコマンドの使い方はリファレンスよりも下記の記事を参考にしたほうが良いです。
  福野泰介の一日一創 - 世界一簡単なサーボモーター制御、ロボットに一歩近づくIchigoJam

2016年8月15日 (月)

LPC810を使ってIchigoJamで赤外線リモコン受信を行う(3)

以前作成したLPC810を使ったIchigoJam用赤外線リモコン受信モジュールを改良しました。
対象とするIchigoJam はファームウェア 1.2.1です。

    Dscn5582

前回からの改良点
  1)I2C用プルアップ抵抗不要。
    内部のプルアップ抵抗を利用するようにしました
  2)赤外線リモコンのボタンコードを調べる機能の追加(強化)
    シリアルTXDポート(2番ピン)から随時ボタンコードをテキスト形式で出力します。
 3)IchigoJam BASICによるプログラミングでPOKEを使わないでI2CRを使える
 インタフェースにしました。

仕様および機能
  ・インタフェース
      I2C(アドレス 0x20)                : ボタンコード取得用
      UART (115200bps,TXDのみ)  : 赤外線リモコンのボタンコード調査用
  ・機能
      赤外線リモコン受信モジュールが直前に受信したボタン情報を返す(I2C)
      赤外線リモコン受信モジュールが受信したボタン情報を随時出力(UART)

回路図

               Photo
                       IchigoJamとの必須接続はSCL、SDA、GND、VCCの4ピン
                      TXD(UART)は赤外線リモコンのボタンコード調査時に利用
                       LPC810にプログラム書き込み時には、TXD、RXD、GND、VCC、ISPの5ピン利用
                      
※内部でプルアップしているのですが、ブレッドボード上で実装する場合、
                      SCL,SDAにプルアップ抵抗を入れた方がよいようですです。
                      (中華製の安価なブレッドボードに問題がありそうです)。

構成部品
   ・LPC810  32ビットARM マイコン(ARM Cortex-M0+, Flash 4KB, SRAM 1KB)
   ・TL1838   赤外線リモコン受信モジュール (他の類似品でもOK)
   ・線材等

    ※TL1838はArliexpressにて10個 $1.2で購入しました。
       amazonでも販売されているようです。
       LPC810秋月電子は値上がりしてしまったので別のところでの購入がよいです。
       スイッチサイエンスマルツはまだ100円以下で購入出来ます。


LPC810用のプログラムソース(書き込み用HEXファイル含む)
   ダウンロード IRtoI2C_20160817.zip (281.9K) (最新版)

   2016/08/16 フリーズする不具合があり、修正しましたがまだ問題ありです。対応中!
   2016/08/17 プルアップ抵抗を入れると安定するようです。調査中.

                    (IchiogamのI2C周りが意外と怪しいのでちょっと混乱中)

   
2016/08/17 プルアップ抵抗の件、ユーニバーサル基板実装版は問題かく動作します。
                    ブレットボード上だと問題ありで、プルアップ抵抗を入れると安定します。
                    プログラムのI2Cタイムアウト周りを少し修正しました。

   解凍したフォルダ内の \IRtoI2C\Release\IRtoI2C.hex が書き込み用のHEXファイルです。
   プログラムの書込み方法は、下記を参考して行って下さい。
       「LPC810のフラッシュへの書き込みをシリアルインターフェースで行なう 」
        http://www.nxp-lpc.com/programming_note/note3.html

        関連情報(書き込みツールFlash Magic 公式サイト)
          Flash Magic

IchigoJamで使ってみる
   赤外線リモコン受信モジュールのI2Cスレーブアドレスは #20 です。 
   IchigoJamからの利用はI2CWコマンドを使って利用します。

1)赤外線リモコンのボタンコードを調べる
     本モジュールを使うには、赤外線リモコン(NEC方式)が必要です。
     小型で安っぽいものはほぼNEC方式です(写真は手持ちのNEC方式リモコン)。 

      Dscn5587

     ・LPC810のGND、VCC、2番ピン(TXD)をIchigoJamのGND、VCC、RXDピンに
       接続してIcigoJamを起動させます。
      (ボタンコードを調べる場合に限りRXDピンにつなげます)

     ・赤外線¥リモコンのボタンを押すと、ボタンに対応するコードが表示されます。

    20160813215500   

     IR=90 の2桁の16進数90がボタンコードとなります。
    
     IR=** と表示されるのは、リピート(ボタンを押し続けている状態)を意味します。

     注意)
        対応していない赤外線リモコンの場合では何も表示されません。
        1つのボタンに複数のコードが割り当てられている場合があります。

     これにより、手持ちの赤外線リモコンのボタンコードを調べることが出来ます。
 
      実際に調べたコードの例
      Dscn3787
     通常、赤外線リモコン上のボタンは全て異なるコードとなります。

2)プログラムでボタンコードを取得する   
   
   IcigoJamのI2CRコマンドを利用します。利用可能なコマンドは2つです。

    (例)  R=I2CR(#20, "0", 1, #800, 4)
          朱色部は可変 部(任意に指定)、黒字分は固定(変更不可)

           変数RはI2CRの実行結果を取得するためのものです。他の変数でも良いです。
           I2CRの実行が正常の場合は0、異常の場合は1がセットされます。
 
           #20は、本赤外線リモコン受信モジュールのI2Cスレーブアドレスです。
           固定値となります。
         
           "0"は、I2CRのコマンド指定部です。次の指定が可能です。
             "0" : ボタンコード取得(赤外線リモコンのリピート機能無効指定)
             "1" : ボタンコード取得(赤外線リモコンのリピート機能有効指定)
          
           1 は コマンド指定部のデータ長(バイト数)です。常に1を指定します。

           #800 は、取得したボタンコードを格納するアドレスです。
           書込み可能な領域であれば任意のアドレスの指定が可能です。
           (例)では、配列変数領域 [0]のアドレスである #800 を指定しています。
           この場合、配列変数[0]、[1]にて取得した値を参照することが出来ます。

           4 は  取得したボタンコードを格納するために使用するデータ長です。
           常に4を指定します。

     コマンドの詳細
         "0" : ボタンコード取得(赤外線リモコンのリピート機能無効指定)
         "1" : ボタンコード取得(赤外線リモコンのリピート機能有効指定)

          上記2つのコマンドは、赤外線リモコン受信モジュールが受信した最新の
          ボタンコードを取得します。違いは赤外線リモコンのリピート機能を使うか
          使わないかです。
 
          リピート機能とはボタンを押しっぱなしにした時に、何回もボタンを押した(連打)
          ことにする機能です。有効にすると連打となり、無効にすると1回だけ押された
          ことになります。

          その結果をI2CRコマンドの第4パラメタで指定したアドレス(例では#800)に
          返します。返す情報は、"状態コード + ボタンコード"の4バイトとなります。

           状態コード   :#0000 前回のコマンド実行から、新たにボタンが押された
                             :#0001 前回のコマンド実行から、操作なし

           ボタンコード : #0000~ #00FF
                                直前に押したボタンコードです。                               


         ちょっと分かりにくですが、押されたボタンを単純に調べるのであれば、
              状態コード 0 の場合にのみ ボタンコード を利用
         すれば良いです。
         リピート機能の有効・無効の指定により押しっぱなしが連打となります。

    サンプルプログラムその1
         コマンド:ボタンコード取得(赤外線リモコンのリピート機能有効指定)
         ボタンコードを取得し、その結果(配列変数[0][1])を表示する例です。      

      10 'I2C IR Sample1
      20 CLS:CLV:CLP
      30 @LOOP
      40 R=I2CR(#20,"1",1,#800,4)
      50 PRINT "STS=";[0];" BTN=";HEX$([1],2)
      60 WAIT 50
      70 GOTO @LOOP

          実行結果      
        20160814115742

        出力の①部分は実行後何も操作をしていない状態です。
        初期値00が返されます。1回目は状態コードが0、2回目以降はボタンコード
        の変化がないので状態コードが1となります。

       2016/08/15 初期は#FF に変更しました。上記画像の00はFFになります。
        複数のリモコンを調べたところ、00は良く使われるコードのためFFに変更しました。

        現状、リモコンにボタンコード00がある場合、初期値00との判別が出来ませんので
        ボタンコード00の利用は避けて下さい。


        出力の②部分はボタンコード48のボタン[3]操作を操作しています。
        上から5つは状態コードが0であることから"5回ボタンを押した"ことを意味します。
        実際は、押しっぱなしにしていて、リピート機能が有効のため5回の連打となりました。
        6行目以降は状態コードが1であることから、ボタンを離した状態です。
        ボタンコードは直前に押されたボタンコード48が返されます。         

    サンプルプログラムその2
         コマンド:ボタンコード取得(赤外線リモコンのリピート機能無効指定)
         ボタンコードを取得し、その結果(配列変数[0][1])を表示する例です。      

      10 'I2C IR Sample1
      20 CLS:CLV:CLP
      30 @LOOP
      40 R=I2CR(#20,"0",1,#800,4)
      50 PRINT "STS=";[0];" BTN=";HEX$([1],2)       60 WAIT 50       70 GOTO @LOOP

          実行結果      
         20160815090714

        出力の①部分は実行後何も操作をしていない状態です。
        初期値00が返されます。1回目は状態コードが0、2回目以降はボタンコード
        の変化がないので状態コードが1となります。
        2016/08/15 初期は#FF に変更しました。上記画像の00はFFになります。

        出力の②部分はボタンコード48のボタン[3]操作を押しっぱなしにしています。
        リピート機能が無効のため最初の状態コードだけが0となり、以降は1となります。
         これで1回だけ押されたと判断出来ます。

    サンプルプログラムその3
       キャラクタをリモコンで操作するプログラムです。
       [2] (#88) 、[8](#98) で上、下、 [4](#28)、[6](#68)で左、右の操作です。
       リピート機能を有効にしているのでボタンを押している間、キャラクタが動きます。

     10 'I2C IR SAMPLE3
     20 CLS:CLV:CLP:X=16:Y=12
     30 @LOOP
     40 R=I2CR(#20,"1",1,#800,4)
     50 IF[0]=1 GOTO @PRN
     60 IF [1]=#88 IF Y>1  Y=Y-1
     70 IF [1]=#98 IF Y<22 Y=Y+1
     80 IF [1]=#28 IF X>1  X=X-1
     90 IF [1]=#68 IF X<30 X=X+1
     100 @PRN
     110 LC X,Y:? "O"
     120 WAIT 10
     130 GOTO @LOOP 

       実行結果
       20160815095250

       40行の"1"を"0"としてリピート機能を無効にすると、ボタンの押しっぱなしで
       は動かなくなり、何回も押さないとキャラクタが動かなくなります。

       50行を
        50 'IF[0]=1 GOTO @PRN

       とコメントアウトして状態コードによる判定を利用しないようにすると、
       キャラクタが常に動くようになります。
       ヘビゲーム(長さを競う、自分の身体、壁にぶつかるとゲームオーバー)なんか
       に使えそうです。

追記
   ユニバーサル基板に実装してみました。
   せっかくなので、新しく販売されました「IchigoJam T 」用に小型化しました。
   こんな感じす。

      Dscn5574

   IchigoJam T には、I2C利用のための端子が別途あります(写真の右側の5ピン)。

     Dscn5576

   ここに直接装着して利用します。いい感じに乗りました。

     Dscn5580

   
   基板図(左:表、右:裏)

    Photo
   実物(裏)

       Dscn5592

   なんとかプリント基板化したいなぁ   

2016年8月 7日 (日)

Arduinoで8x8LEDマトリックスを直接(直結)で制御する

以前、IchigoDotSが電流制御抵抗なしにマイコンでLEDマトリックスを制御しており、
「どういう制御しているのだろう?」と疑問に思い、調査がてらArduinoでやってみました。

※注意 真似するとArduinoが破損する場合があります。

動作の様子



LEDマトリックスは秋月電子で購入した MNA20SR092G を利用しました。

組み立て
D7、D8ピンは隙間が空いているのですが、LEDマトリックスのピンを広げて装着させました。

Dscn5520

反対側のピンは、ジャンパワイヤー(メス・オス)で結線しました。

Dscn5515


回路図(結線図)

02


     接続ピンの対応表
        2つの表は同じものです(左がLED PIN順 、右がMATRIX割り付け機能順)。
        表のLEDピンは上図のPIN1~PIN16に対応します。
        MATRIXはPINに割り当てられている機能を示しています。       

                     LED PIN順                          MATRIX 割り付け順
      01_2

      アナログピンA0~A3もデジタル入出力として利用しています。
      A0~A3はデジタルピンとして使う場合ピン番号14~17として利用出来ます。

スケッチ
  ダウンロード matrix4.zip (22.8K)

メイン処理部のみ掲載しました。

#include <avr/interrupt.h>
#include <TimerOne.h>
#include "misakiUTF16.h"

//*************************************
//   出力ピンの定義(MNA20SR092G接続用)
//*************************************
// 横
#define COL1  10
#define COL2  7
#define COL3  6
#define COL4  16
#define COL5  4
#define COL6  15
#define COL7  12
#define COL8  13

// 縦
#define ROW1  17
#define ROW2  11
#define ROW3  2
#define ROW4  14
#define ROW5  9
#define ROW6  3
#define ROW7  8
#define ROW8  5

#define UARTBPS 9600
#define TIMERTIK 100

//*****************************
// グローバル変数
//*****************************
// COL,ROWのピン割り付けテーブル
uint8_t col[8] = {COL1,COL2,COL3,COL4,COL5,COL6,COL7,COL8};
uint8_t row[8] = {ROW1,ROW2,ROW3,ROW4,ROW5,ROW6,ROW7,ROW8};

// 表示用バッファ(8x8ドット分)
uint8_t pdata[8];
uint8_t line, colno;

//*********************************
// ドットマトリックス表示用関数
//*********************************

//
// digitalWrite高速化版
//
void new_digitalWrite(uint8_t pin, uint8_t val) {
  uint8_t bit = digitalPinToBitMask(pin);
  volatile uint8_t *out = portOutputRegister(digitalPinToPort(pin));
  if (val == LOW)
    *out &= ~bit;
  else
    *out |= bit;  
}

// 点灯する行の選択
// y: 行(0〜7)
void selectRow(uint8_t y) {
  for(uint8_t i=0; i <8; i++)
    new_digitalWrite(row[i], HIGH);   
  new_digitalWrite(row[y], LOW);
}

// 1行分データの出力
void setData(uint8_t d) {
  uint8_t msk = B10000000;
  for (uint8_t i = 0; i<8; i++) {
    if (msk & d) { 
      new_digitalWrite(col[i], HIGH);
    } else {
      new_digitalWrite(col[i], LOW);
    }
    msk>>=1;
  }  
}

// ドット単位のダイナミック駆動
void update_dot() {
  setData(0);
  selectRow(line);
  setData(pdata[line] & (B10000000>>colno));
  colno++;
  if (colno == 8) {
    colno =0;
    line++;
    if (line==8) 
      line = 0;  
  }
}

// ドットマトリックスの表示OFF
void matrix_off() {
  for (uint8_t i = 0; i < 8; i++)
       new_digitalWrite(row[i], HIGH);
}

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

// バッファへの書き込み
// 8x8フォントパターンを表示用バッファに書き込む
void write_buf(uint8_t* dat) {
  for (uint8_t i=0; i<8; i++)
     pdata[i]= dat[i];
}

// 指定座標にフォントパターンをセット
void write_bufat(uint8_t* fptr, uint8_t x, uint8_t y) {
  uint8_t w;
  
  if (x>7 || y >7)
    return;     
  for (byte j=y,i=0; j < 8; j++,i++)
    pdata[j] = (pdata[j]>>(8-x))<<(8-x) | fptr[i]>>x;
}

// バッファーデータのスクロール
// h_mode : 0 なし,1 左 ,2 右 
// v_mode : 0 なし,1 上, 2 下      
void scroll(uint8_t h_mode, uint8_t v_mode) {
  if (h_mode ==1) 
    for (byte i = 0; i < 8; i++) 
      pdata[i] = pdata[i]<<1;
  if (h_mode ==2)
    for (byte i = 0; i < 8; i++)
      pdata[i] = pdata[i]>>1;
  if (v_mode ==1) {
    for (byte i = 0; i < 7; i++)
     pdata[i]= pdata[i+1];
    pdata[15]=0;
  }
  if (v_mode == 2) {
    for (byte i = 7; i >0; i--)
     pdata[i]= pdata[i-1];
    pdata[0] = 0;    
  }
}

// スクロールしながらパターンを表示
void scrollout(uint8_t* fptr, uint16_t dly) {
  for (byte i=0; i<8; i++) {
    scroll(1, 0);
    write_bufat(fptr, 7-i, 0) ;
    delay(dly);
  }
}  

char buf[129];
bool lfgMsg;

//*********************************
// メッセージ受信チェック
//*********************************
void chekMessage() {
  // シリアルデータ受信
  uint8_t n=0;
  while (Serial.available() > 0) {
    buf[n] = Serial.read();
    n++;
    if (n>128) {
      break;  
    }
  }

  buf[n] = 0;
  lfgMsg = true;
  Serial.println("OK");
  Serial.flush();  
}

//*********************************
// メイン処理
//*********************************
void setup() {
  for (uint8_t i=0; i <8; i++) {
    // ピンモードの設定
    pinMode(col[i], OUTPUT);
    pinMode(row[i], OUTPUT);
  }
  Serial.begin(UARTBPS);
  clrar_buf();
  line = 0;
  colno = 0;
  lfgMsg = false;
   
  Timer1.initialize(TIMERTIK); 
  Timer1.attachInterrupt(update_dot);  
  //setfull();
}

char *str="こんにちは さいたま県♪ 今、さいたまがアツい!";
uint8_t fnt[FONT_LEN];
char *pUTF8;

void setfull() {
  for (uint8_t i=0; i <8;i++) 
    pdata[i] = 0xff;
}

void loop() { 
  if (lfgMsg) {
    pUTF8 = buf;
    lfgMsg = false;
  } else {
    pUTF8 = str;  
  }
  while(*pUTF8) {
    pUTF8 = getFontData(fnt, pUTF8,true);     // フォントデータの取得
    scrollout(fnt, 70);                      // スクロールしながら文字を表示
    if (Serial.available() > 0 && !lfgMsg) 
      chekMessage();      
  }
  delay(1000);
}

解説

1)LEDの駆動
電流制御抵抗なしでも、LEDにかける電圧のディューティー比 とパルス幅を調整すると
定格内でLEDの駆動が行えます。
(専門家ではないので、間違えているかもしれませんが..)

まずは、利用したLEDマトリックス MNA20SR092Gのデータシートに下記の記載があります。

  03

    IPF 100mA が注目する数値です。
    ディューティー比 1/10サイクル パルス幅 0.1ms内なら100mAまで可能です。

    これを守れば、通常の30mA(IAF)を超えてもOKです。
    これがまず可能にする理由の第一点
    ((パルス幅 0.1msはちょっと短すぎです。別製品 OSL641501-ARAだと1ms)

LEDに関しては問題なしです。

参考にしたサイト
   ikkei blog -  Arduino UNO にLEDを直結して電流を測ってみた


2)Arduino
Arduinoの出力ポートの出力抵抗(インピータンス)が30Ω程度あります。

LEDのVfが2.0Vなので、
ソース(HIGH)→ LED → シンク (LOW)で点灯させた場合に流れる電流は
  (5.0 - 2.0) / (30+30) = 0.0645 = 50mA
となります(自信はないので断言は出来ません)。

arduino的には最大定格40mAを超えていますね。

一方別の記載で1ピンで推奨の20mA超えても
ソースで他ピンを含めた合計で100mA厳守、同シンクで150mA厳守の記載があります。
インターネット上で調べると定格以上でも70mA位流せるようです。
ただし、動作保証範囲外の利用となります。

ここは、趣味で利用する範囲で許容範囲としましょう。


実際にオシロスコープで測定でしてみて、
3.3V稼働時に28mA、5V稼働で48mA流れていることを確認しましった。

スケッチの実装について

Arduin IDE 1.6.9にて実装しています。

ハードウエア的制約を考慮して実装しました。
ダイナミック駆動は1ドット単位で制御するようにしました。
(瞬間的には常に最大で1点しか点灯していないことになります)
ボタン電池による駆動を視野にいれ省電力化に貢献すると思います。

パルス幅 0.1ms内を考慮し、0.1ms間隔のタイマー割り込みを利用し、
1回の割り込みで1ドットの制御、64回の割り込みで1画面分64ドットの制御を
行うようにしました。ディューティー比 1/64 となります。
    
6.4msで1画面の更新となります。
人間の目で1/60秒以内ならチラついて見えないのでこの更新なら十分でしょう。

この周期でタイマ割り込みで行うにおいてOneTimerライブラリを使いました。
更に0.1ms内でのLED制御を考慮してdigitalWrite()を高速版に置き換えました。

実際にオシロスコープで測定すると、0.1ms幅のパスルは出ていなくて0.04msでした。
パルス周波数は156.2Hzであるため正確な間隔で割り込みが発生しています。
(周期 0.1ms x 64 = 6.4 ms   1/6.4ms = 156.25Hz)

日本語表示は、美咲フォントを利用しています。

機能的には、固定文字列 "こんにちはさいたま県.."を表示しています。

さらに、シリアル通信にて受信した文字列を表示出来るようにしました。
(まだ作りが甘いです。たまにおかしくなります) 

実際の実装は、3Vボタン電池稼働でやろうと思っています。
電流制御抵抗使用しないのも省電力につながると思います。
ほとんどIchigoDotのマネですが..
Atmega328(中身はArduino) 3V 内部RCクロック 8MHzにて動作しました。

Dscn5511



2016年8月 4日 (木)

Synology のNAS(DS216j)でインターネットラジオを楽しむ

最近、購入したSynology社製のNAS、DS216jを色々といじっているのですが、
NAS以意外の機能がかなり使えます。

オーディオソフト 「Audio Sation」はなかなかの優れものです。
NAS(DS216j)にUSBスピーカーを繋げて、音を出すことが出来ます。

Dscn5500

写真はELECOMのUSBスピーカー MS-P05UBKをDS216j(後ろの白いやつ)に接続して
インターネットラジオ「SmoothJazz」を流しています。

ちなみにMS-P05UBKは、安い割には良い音が出ます。ただしNAS接続においては
ボタン ミュート・音量調整は動作しませんでした。NASから制御出来るので問題はないですが..

オーディオソフト 「Audio Sation」ですが、NAS上の音楽ファイルの他に
インターネットラジオにも対応しています。
(※radiko、らじる らじるには対応していません)

インターネットラジオは、SHOUTcastというストリーミング配信のラジオです。
下記のサイトからも直接聞くことが出来ます。
  SHOUTcast https://www.shoutcast.com

09

再生先もブラウザを表示しているパソコンのスピーカーの他、NAS接続のUSBスピーカー、
LAN上に接続しているDLNA対応のAV機器の指定が可能です。
USB-Bluetoothドングルを使えば、Bluetoothスピーカーも利用出来るようです。

04

イコライザもあります。

05

更にスマートフォン向けのアプリ「DS Audio」が無料で利用出来ます。
スマートフォンからも再生したい音楽やインターネット局の選択が出来ます。

Dscn5501

インターネットラジオ、特にJazz系の曲は部屋のBGMに重宝します。

2016年8月 3日 (水)

Synology のNAS(DS216j)上にgitサーバーを構築する

Synology製 のNAS、DiskStation DS216j上にgitサーバーを構築する手順メモです。


下記の情報を参考にして構築しました。

   参考ししたサイト
      Instructions for setting up git server on Synology Diskstation


構築の方針

・gitリポジトリ領域(保存する領域)は /volume1/git とし、シンボリックリンクにて
  /git  にてアクセスできるようにする。
  書込み権限はroot、gitusersグループに付与する。

・gitサーバーの利用権限はgitusersグループに所属するユーザーのみに付与する。
  これにより、権限を持つ複数のユーザーでの利用可能

・プロトコルはssh利用限定として、公開鍵暗号方式にて認証出来るようにする。
  (これはgitクライアント SourceTree の利用を考慮)

構築するもの
  NAS側
   インストールおよび有効化するサービス
     ・gitサーバー
     ・ターミナルサービス (ssh)

   アカウント関連
     ・gitusers グループの作成

   リポジトリ領域(保存領域)作成
     ・/vokume1/git (所有者 admin グループ gitusers)

   利用者の設定
     ・利用者をgitusers、administratorsグループに登録
     ・利用者のホームディレクトリ 下 ~/.ssh の作成と公開鍵の配置

   gitクライアント側
     ・SourceTree(var sion 1.9.5.0)のインストール
     ・ssh接続用 公開鍵と秘密鍵の作成
     ・SourceTreeにリモートレポジトリの登録

構築手順
1.gitサーバーのインストール
   DiskStation Manager(以降、DSMと略)に管理者権限のあるユーザーでログインし、
       「パッケージセンター」にて「Git Server」をインストールします。
   インストールすると、メインメニューに「Git Server」アイコンが登録され、稼働します。

   05

2.ターミナルサービスの有効化
   DSMの「コントロール」を開き、「端末とSNMP」の「ターミナル」の「SSHサービスを有効化する」
   にチェック(☑)を入れて「適用」を押します。

   07

3.gitusersグループの作成
   「コントロール」の「グループ」にてgitusersを作成します。

4. gitリポジトリ 保存領域作成
   ターミナルソフト等でsshにてログインします。
   sudo sh
   midir /volume1/git
   ln -s /volume1/git /git
   cd /git

   git --bare init <repo-name>.git
   chown -R admin:gitusers <repo-name>.git
   chmod -R g+w <repo-name>.git
   cd <repo-name>.git
   git update-server-info

   13

   ここで、<repo-name>はarduinoのスケッチを管理するためにarduino としました。
   必要に応じてgit下に領域を作成していきます。

   git --bare init <repo-name>.git を
   git init --bare --shared <repo-name>.gitとすれば
   git update-server-info の実行は不要のようです。

5.利用者の設定
   ・「コントロール」の「ユーザー」にて利用するユーザーを
     gitusers、administratorsグループに登録します。
   ・ gitサーバーの設定画面にて利用するユーザーの利用権限を付与します。

6.gitクライアントSourceTreeのインストール
  SourceTreeではなく、別のgitクライアントでもよいです。
  インストール作業については省略します。
  入手先 : https://www.sourcetreeapp.com

7.公開鍵と秘密鍵の作成
   SourceTreeでは、SSHクライアントの設定に「OpenSSH」と「PuTTY/Plink」の指定
   が出来ます。「PuTTY/Plink」は秘密鍵のファイル形式が特殊なようなので、
   他のアプリ(TeraTermやgit shell)でも利用できる「OpenSSH」に設定しました。

   「OpenSSH」と「PuTTY/Plink」では鍵の作成方法が異なります。
   「OpenSSH」では、TeraTermやssh-keyhenコマンドで作成した鍵が利用出来ます。

   ここでは、SourceTreeの「ターミナル」にて作成します。
   ターミナルを起動し、下記のコマンドを実行します。
    $ ssh-keygen -t rsa

   あとは、指示に従って入力して公開鍵と秘密鍵を作成します。
   作成先のパスはデフォルトのままとします。
   ターミナル上ででgitコマンドを使って鍵認証を行う場合は、ホームディレクトリの
   .sshに鍵がある必要があります。
  (下図では既存ファイルへの上書き防止のため別の場所に作成しています)

   passphraseは秘密鍵につけるパスワードです。各自の判断で任意に設定します。
   デフォルトのファイル名は秘密鍵がid_rsa、公開鍵がid_rsa.pubとなります。

   08

8.公開鍵をNASに登録する
  ここでは、NAS上のユーザー tamakichi のアカウントを使ってgitサーバーを利用する
  ものとします。公開鍵の登録は利用するアカウントごとに行います。

  7.のターミナル上で作成した公開鍵をNAS上のユーザー tamakichiの
  ホームディレクトリに転送します。

   $ scp id_rsa.pub tamakichi@192.168.0.25:
    09

  同ターミナル上でNASにログインします。
   $ ssh tamakichi@192.168.0.25
   10

  公開鍵を配置します。ディレクトリ(.sshが既にある場合はディレクトリ作成不要)
     $ mkdir .ssh
     $ chmod 700 .ssh
     $ cat id_sra.pub >> .ssh/authorized_keys
     $ chmod 600  .ssh/authorized_keys
    $ chmod 755 ~          <= この設定をしかなったため、私は数日ハマりました

   11

   NASからログアウトして今度は秘密鍵を使ってログイン出来ることを確認します。 
     $ exit
     $ssh -i id_rsa.ppk tamakichi@192.168.0.25

     -iにて秘密鍵のファイルパスを指定します。
    ホームディレクトリの~/.sshに鍵を作成した場合(デフォルトのまま作成)は省略可能です。
     $ssh tamakichi@192.168.0.25

   passphraseを聞いてくるので、鍵作成時に設定したpassphrase を入力します。

  12

  ここで、passphraseを入力した後にさらにパスワード入力を要求された場合は、
  公開鍵を使った認証に失敗していることを意味します。  設定を見直して下さい。

9.ターミナル上でのpushを行う
  あらかじめローカル環境にてローカルのリポジトリが作成されていているものとします。
  私の環境ではArduinoのスケッチを保存しているE:\arduino\srcにて
    git cd /e/arduino/src
    git init
    git add .
    git commit -m '最初のバックアップ'
なんかをやった状態です。

リモートへのpush
  $ git push ssh://tamakichi@192.168.0.25/git/arduino.git

  15

  passphrese(パスフレーズ)を聞いてくるので入力します。
  問題なくpush(プッシュ)出来ました。

10. SourceTreeからpushを行う
  ・事前にローカルの作業領域を追加してあるものとします。
    (ここでは、説明を省略します)

  ・リモートのリポジトリを追加します。
    追加したいのは "ssh://tamakichi@192.168.0.25/git/arduino.git"  です。

   メニュー [リポジトリ] - [リモートを追加]にて「リポジトリ設定」画面を開きます。
   [追加]ボタンにて 追加します。

  16

  ・秘密鍵の登録
   メニュー [ツール] - [オプション] から「オプション」画面を開きます。
   [全般]タブの「SSHクライアント設定」の「SSHキー」に作成した秘密鍵を指定します。
   「SSHクライアント」の設定を「OpenSSH」にします。

   18

   次にメニュー [ツール] - [SSHキーを追加]にて作成した秘密鍵(id_rsa)を選択します。

   

19

  選択するとpassphrase(パスフレーズ)を聞かれるので入力します。

   20

   これで設定完了です。

  ・push
   画面上部のプッシュボタンを押します。「プッシュ」画面が表示されるので
   プッシュ先を確認の上、   ローカルブランチ、リモートブランチの設定します。

   21

   設定後、[プッシュ]ボタンを押します。

   22

   NASへのプッシュが実際されます。

11.NAS上のgitレポジトリの確認
NAS上にログインして、ログを見てみます。

23

ちゃんとPushされているようです。

なんとなく、ちゃんと動作している感じですが、
gitに関しては、まだまだ利用し始めたばかりなので問題があるまもしれませんね。
ですので、記事の内容を実施して被害を講じても責任は持てません。


 

Synology のNAS(DS216j)に公開鍵暗号方式を使ってsshログイン

ちょっとハマッたのでメモ "φ(・ェ・o)~メモメモ

Synology製 のNAS、DiskStation DS216j上にgitサーバーを構築して、
作成したプログラムや文書ファイルをバージョン管理しつつ、一元管理しようと思っています。
利用するgitクライアントとしてはWindows上にて、SourceTreeを使っていこうと思っています。

このSourceTreeにてgitサーバーにプログラムソース等をpush(アップロード)する場合、
プロトコルでsshを使うのですが、SourceTreeでは公開鍵暗号方式にて接続の認証を
行う必要があります(通常のプレインパスワードでもやればできるのかも?)

  参考: SSHで公開鍵認証を使った認証手順

sshにて公開鍵を使って、認証を行うには公開鍵と秘密鍵をセットで作成し、
接続先(サーバー)に片方の公開鍵を登録しておく必要があります。
sshにて接続時にその秘密鍵を指定することで接続先との認証を行います。

この設定において何故か上手く認証出来ず、ここ数日ハマっていました。
何回やっても、パスワード認証方式に切り替わってしまいます。
(公開鍵認証が上手く行かないと、プレインパスワード認証に切り替わります)

他のLinuxマシンで同じ手順で登録したところ、問題なく行えたことから、
NASのsshd環境に問題があると思い、色々調べ原因を特定出来ました。

原因は、DS216jの個人ホームディレクトリのデフォルトのアクセス権限にありました。
(本質的にはsshの仕様なのですが)

  参考にした情報
     Synologo Community Forrum - SSH RSA-key login

ユーザー tamakichiのホームディレクトリのアクセス権限は次のようになっていました。

他ユーザーでも書込み出来る設定ですね。デフォルトがこれなのはマズイですね。
   drwxrwxrwx /var/services/homes/tamakichi

これを本人以外は書き込み出来ないようにします。
  sudo chmod 755 /var/services/homes/tamakichi

変更後のアクセス権限
   drwxr-xr-x /var/services/homes/tamakichi

この設定変更で、sshにて公開暗号方式による認証が出来るようになりました。
(あっけない対処による解決。こんなんで数日ハマっていたのか.. 泣きたい)

sshは設定ファイル等のアクセス権限の設定に厳しいんですよね。

ホームディレクトリ自体もアクセス権限をしっかりと設定する必要があるみたいです。

sshの公開鍵はホームディレクトリ下の.ssh/ に登録するのですが第三者に内容を
読まれないよう、アクセス権限をしっかりと設定する必要があります。
このあたりの設定方法は手順書に書かれているのですが、ホームディレクトリ自体の
アクセス権限の設定に関しては記載は無く盲点でした。

なんとか、SourceTree にてPush出来ました。

04

この当たりの構築作業についても、忘れないようまとめます。

« 2016年7月 | トップページ | 2016年9月 »