フォト
2025年3月
            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年4月 | トップページ | 2015年6月 »

2015年5月の15件の記事

2015年5月31日 (日)

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

IchigoJamを赤外線リモコンで操作する試みで、
この前やった、Arduino を使った赤外線リモコン受信LPC810(通称 どんぐり)を使って
やってみました。まずはブレッドボード上にて実装しました。

結論としてはかなり使えそうです。3メール離れても受信出来ました。
基板実装して、ロボットカーをリモコン操作をやってみようと思います。

Dscn3858

方式は下記のように、LPC810をI2CスレーブとしてIcihoJamから赤外線リモコンの
受信データを読みにいきます。

03

LPC810まわりの実装は、下図の通りです。
赤外線リモコン受信モジュールは、秋月電子で購入したPL-IRM2161-XD1
使っています。2個で100円と安価な部品です。

01

シリアル通信(115200)はデバッグ用に利用します。通常は接続しなくてもOKです。
赤外線リモコンは、こんな感じのを使いました。ボタンに割り当てられている
コードは写真の右側の値となります。NEC方式の通信方式です。

I2Cのアドレスは適当に0x40(8ビットアドレス)を割り当てました。

機能としては単純で4コマンドのみです。
コマンドコードを1バイト送信して、直前に押したリモコンボタンのコードと状態コードの
計4バイトを取得します。

送信コマンドは下記の通り
  00 通常受信(リピート機能OFF)
  01 リピート機能有効受信
  FF デバッグモードON受信
  FE デバッグモードOFF受信

受信データ4バイト
  2バイト: 状態コード   (0:新しい値  1:前回済み)
  2バイト: ボタンコード  00~ FF

リピート機能OFFの場合、ボタンを押しっぱなしにした場合は1回だけ押されたと判断
します。リピート機能ONの場合、ボタンを押しっぱなしは"連打"に相当します。

IchigoJamで使う場合、次のような感じで使います。

10 'I2C IR remote
20 CLS:CLV:POKE #700,1
30 X=16:Y=12
40 R=I2CR(#20,#700,1,#8CC,4)
50 LC 0,0:?HEX$(B,2);:?" ";:? A
60 IF A=1 GOTO 110
70 IF B=#88 IF Y>1  Y=Y-1
80 IF B=#98 IF Y<22 Y=Y+1
90 IF B=#28 IF X>1 X=X-1
100 IF B=#68 IF X <30 X=X+1
110 LC X,Y:? "O"
120 GOTO 40

これを実行した画面はこんな感じです。単純に○をリモコンで上下左右動かすだけです。

02

40行のI2CRコマンドでコマンドの送信とリモコン操作のボタンコードを取得しています。
#8CCのアドレスに受信データを格納します。このアドレスから4バイトは変数のA、B
の領域です。そのためプログラムで変数A、Bを使って値判定しています。

変数領域#800~#8FFの内訳は次のようになっているようです。
1変数あたり2バイトを使用します。
  #800  - #8C9  配列変数  [00] - [100]
  #8CA - #8CB  空き
  #8CC - #8FF  変数 A - Z

次にLPC810のプログラムについてです。
IR受信処理はarduinoのソースをちょこと修正しただけで利用できました。
I2Cスレーブまわりはライブラリを自作しました。LPC810のマニュアルを読み込んで
実装したのですが、取りあえず動いているといった感じです。

ソースを置いておきます。

LPC810ソース ダウンロード IRtoI2C_050531.zip (281.3K)

関連記事
  LPC810を使ってIchigoJamで赤外線リモコン受信を行う       ・・・ この記事
  LPC810を使ってIchigoJamで赤外線リモコン受信を行う(2) ・・・ 基板実装
  LPC810を使ってIchigoJamで赤外線リモコン受信を行う(3) ・・・ 改良版
  LPC810を使ってIchigoJamで赤外線リモコン受信を行う(4) ・・・ サーボモーターの制御
  IchigoJamでDVR8830を使ったロボットカー制御(2)            ・・・ 赤外線リモコンで操作

2015年5月27日 (水)

STM32F103C8T6ボードでLチカ

「arduino IDE 1.6.4 で ARM STM32F103C8T6を使ってみる」で試した
ARM STM32F103C8T6 ボードをSTM32開発環境を使てLチカを実装してみました。

01

今回の目標は、
  「PC13ポートに接続のLEDを1秒間隔で点滅させる」
です。

開発環境の準備
STM32マイコン用 無償統合開発環境として2の環境をインストールして試してみました。
Atollic TrueSTUDIO Version: 5.3.0 Lite
System Workbench for STM32
(ダウンロードを上記のリンクからダウンロード出来ます。要ユーザー登録

試した感じではどちらもeclipceベースでLPC810の開発で使ったLPCXpressoと
同じような感じです。環境的には大差がないのですが、TrueSTUDIOは、
メニュー表示等、日本語対応されています。また、他のLPC等の他のARM CPUにも
対応しているので、こちらを選択しました。

17

上記の様に、全て日本語表示で分かりやすです。

Lチカプログラムの実装
プログラム作成にあたり、必要ライブラリ・初期設定等のプロジェクトファイル一式
を生成してくれるSTM社の「STM32CubeMX」というツールを使うことにしました。
下記からダウンロードできます。
  STM32CubeMXSTM32Cube initialization code generator (UM1718)

STM32CubeMXは使いたいベリフェノール(UART、GPIO、I2C等の機能)を選択して、
ライブラリ等の一式を含めた開発環境用のプロジェクトを自動生成してくれます。

生成したmain.cのソースは次のような感じです(ヘッダー部のコメントは省略しています)。

/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);

/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();

  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */
	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,1);
	  HAL_Delay(1000);
	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,0);
	  HAL_Delay(1000);

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);

}

/** Configure pins as 
        * Analog 
        * Input 
        * Output
        * EVENT_OUT
        * EXTI
*/
void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __GPIOC_CLK_ENABLE();
  __GPIOD_CLK_ENABLE();
  __GPIOA_CLK_ENABLE();

  /*Configure GPIO pin : PC13 */
  GPIO_InitStruct.Pin = GPIO_PIN_13;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

#ifdef USE_FULL_ASSERT

/**
   * @brief Reports the name of the source file and the source line number
   * where the assert_param error has occurred.
   * @param file: pointer to the source file name
   * @param line: assert_param error line source number
   * @retval None
   */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */

}

#endif

上記のソースでは、main()のwhile()内にLチカ用に4行だけ追加しています。
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,1);
  HAL_Delay(1000);
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,0);
  HAL_Delay(1000);

STM32CubeMXの使い方

プロジェクトを新規作成します。

02

プロジェクトを作成する際、ターゲットMCUを指定します。
ここでは、STM32F103C8xを指定しています。

04

Toolchain/IDEにTrueSTUDIOを指定します。

12

プロジェクト作成時に必要なモジュール等のダウンロードが行われます。
プロジェクト作成後は、下記の画面となり左側の「ベリフェノール」にリストで利用したい
機能を選択しパラメタ等を指定します。中央のICのピンをクリックしてピンに機能を
割り当てることもできます。

05

私のマイコンボードでは2つの水晶振動子で外部クロックされているのでその設定が
必要となります。またLEDを点灯されるためにPC13ピンにGPIO の出力を定義します。
また、ST-LINKでデバッグできるようにSWCLK、SWIOによるシリアル通信が出来るように
定義します。

PC13のピンを GPIO_Outputを設定
06

ベリフェノールの設定
RCCのHigh Speed ClockとLow Speed Clockに水晶振動子の接続を設定します。
SYSのDebugにSerial-Writeを選択します。

08

この設定により、ICの対応するピンに機能が割り当てられます。

23

次にClook Configrationタブの画面でクロック関連の設定を行います。
水晶振動子のクロック周波数や、クロック供給の設定を行います。

09

設定が完了したのでにコード生成を行います。
メニューの[Project] - [Generate Code]で生成出来ます。


開発環境 TrueSTUDIOを使う

開発環境 TrueSTUDIO を起動して生成したコードをインポートします。

13

14

15

インポートすると自動でコンパイルするのですが、エラーが発生します。

16

どうも、生成したコードのSTM32F103C8_FLASH.ldというファイルがまずいようです。
このファイルはリンカー用のスクリプトファイルです。

ここで、ちょとハマりましたが、このファイルを作成すればよいようなので
プロジェクトのプロパティ設定で、下記の設定を変更してもとに戻す操作をして
スクリプトファイルの作成を行くことでエラーを回避出来ました。

18

コンパイル後、デバックモードで実行するとLチカが動作しました。

念のため、ブレークポイントを設定してデバック出来るかも確認していました。

20

生成したプロジェクトにはなぜかデバックモードの実行形式ファイルしか生成して
くれません。一応、デバッグで実行するとボードへの書き込みも行ってくれるのですが、
デバッグ用のコードのため、プログラムサイズが大きいです。

手動でReleseモードの環境を作成する必要があります。
構成の管理画面で新規に作成します。

25_2

24

Debugの構成をコピーして作成します。その後、Relese環境のデバックレベルの設定で
Assembler と C Compiler のDebuggingのDebug Levelの設定をNoneを指定します。

26

さらに、ST-LINK Utilityでボードに書き込むためのHexファイルも生成する設定を
行っておきます。

27

コンパイル後、ST-LINK Utilityでもボードに書き込んで動作することを確認しました。
(Hexの他にs-recordという出力形式でも書き込むことが出来ました)

22

おおよその感覚で、作成方法が把握出来ました。

次の調査としては、ボード上のUSBの利用ですね。
STM32CubeMXでUSBまわりのドライバーと初期化処理部を自動生成してくれる
ようなのでそのあたりを調べてみます。

2015/05/28 追記

ライブラリ等はSTM32CubeF1 をダウンロードしてIDEに組み込んでも良さそうです。
この中にマニュアルやサンプルが含まれています。

2015年5月26日 (火)

IchigoJamで自分自身をLIST表示するプログラム

IcigoJamでは現在実行している(RAMにロードしている)プログラムは、
#C00のアドレスから次のような感じで管理されています。

       1行ごとの格納形式は下記の通りです。
        先頭3バイト+プログラム文となります。
      
      
      
         ・・・・・
      
       プログラム(テキスト文字列)部の終端にはNULL文字が付くためデータ長は
       行内プログラム長さ+1バイトとなります。
       また、バウンダリー調整のためテキスト文字列部の後半はNULL文字が埋まって
       いる場合があります。

       次の行のアドレスは3+行内プログラム長さ+1 となります。
       行番号が0の場合が未使用領域となるようです。

       行番号2バイトが1バイト目が下位8ビット、2バイト目が上位8ビットです。
       10行の場合は、 #0A #00 となります。

       この領域もPEEK、POKE命令で読み書き出来ます。
       下記は「自分自身のプログラムを表示するプログラム」です。

 
10 'ジブンヲヒョウジスル プロウラム
20 P=#C00
30 'ギョウバンゴウ シュトク
40 N=PEEK(P)+PEEK(P+1)<<8
50 IF N=0 THEN END
60 ? N;" ";
70 P=P+2
80 'ナガサノシュトク
90 L=PEEK(P)
100 P=P+1
110 FORI=0 TO L-1
120 ?CHR$(PEEK(P));
130 P=P+1
140 NEXT
150 ?""
160 P=P+1
170 GOTO 30

          実行結果
          04_2

          LISTコマンドのような結果が出力出来ました。
          このプログラムで、管理構造が把握出来ました。

 

2015年5月25日 (月)

arduino IDE 1.6.4 で ARM STM32F103C8T6を使ってみる

2017/04/22 追記
本ページへのアクセスが多いので、Blue Pillのセットアップの良記事を紹介いたします。
・DEKOさんのSTM32F103C8T6の記事
   http://ht-deko.com/arduino/stm32f103c8t6.html

   私も最近ではDEKOさんページの内容を参考にしてセットアップしています。

・Arduino STM32については、下記にまとめを作成しました(2017/10/31 追記)
  Arduino STM32関連情報
  Arduino STM32 リファレンス

----

arduino IDEの 1.6.x 系列で安価なARMボードが動くらしいので試してみました。
2017/10/31 追記 この記事は古いです。最新の1.8.x系列を使いましょう)

試したのはSTマイクロエレクトロニクス社(本社 スイス)のARM(ARM 32 Cortex-M3 CPU)を
搭載したボードです。動作クロック 72MHz、64Kbフラッシュメモリ、20kバイトSRAM搭載です。

いつものAliexpressで購入しました。

01

んで、実物がこれです。

03

このボードに関する情報はここにまとまってあります(ピンレイアウトを除く)。
   (2016/12/03追記)
   こちらの記事も参考になると思います。 「Red Pill or Blue Pill?
   「Red Pill or Blue Pill?」によると、私のはBlue Pillボードで、USB接続に問題ありとの
   情報があります(USB用のPA12ピン接続のR10の抵抗に問題あり?) 。
  Problem

USB経由でプログラム書き込みが出来ないっぽいので、ST-Link V2を追加購入しました。
ST-Link V2 は STM32/STM8系CPU用のプログラマーです。

02

こんな感じで接続して使います。

Dscn3853

ドライバー、ユーティリティソフト類は、STマイクロエレクトロニクスの下記のサイトから
入手しました。
  ST-LINK/V2ST-LINK/V2 in-circuit debugger/programmer for STM8 and STM32
  ST-LINK/V2 in-circuit debugger/programmer for STM8 and STM32 (2016/09/20 更新)

ユーティリティソフトを起動してARMボードに問題なく接続出来ました。

04

次にarduino IDEの 1.6.4にSTM開発環境を組み込みます。
Arduino STM32という環境を利用します。下記のサイトで配布・情報公開が行われています。
  rogerclarkmelbourne/Arduino_STM32
  https://github.com/rogerclarkmelbourne/Arduino_STM32/wiki

上記サイトの「Installation」の内容に従って環境を構築しました。
特につまづく箇所もかなく構築出来ました。

07

該当するボード、書き込み手段としてSTLinkを指定します。

06

Lチカを試してみます。ここでハマりました。

デフォルトで用意されている「スケッチの例 /Basics/Blink」を
試してみましたが、コンパイルと書き込みは出来たものの、Lチカしません。

ボード上のLEDは、デジタルピン13ではないようです。
ただし、ボード上のLEDの脇にPC13とのラベルが印刷されています。

インストールしたファイルをチェックすると
.\hardware\Arduino_STM32\examples
にサンプルソースがありました。その中の\Digital\Blink\Blink.inoを見ると
  digitalWrite(PB1, HIGH);   // turn the LED on (HIGH is the voltage level)
となってました。

これをヒントにデジタルピンの指定を13からPC13に変更するとLチカ出来ました。
ピン設定は互換性が無いようです。

選択したボードGeneric STM32F103C8 のボード関連の設定ファイルを覗いてみると、
(\hardware\Arduino_STM32\STM32F1\variants\generic_stm32f103c\board\board.h)
下記のように定義されています。

#define CYCLES_PER_MICROSECOND    72
#define SYSTICK_RELOAD_VAL     71999 /* takes a cycle to reload */

#define BOARD_NR_USARTS           3
#define BOARD_USART1_TX_PIN       PA9
#define BOARD_USART1_RX_PIN       PA10
#define BOARD_USART2_TX_PIN       PA2
#define BOARD_USART2_RX_PIN       PA3
#define BOARD_USART3_TX_PIN       PB10
#define BOARD_USART3_RX_PIN       PB11

#define BOARD_NR_SPI              2
#define BOARD_SPI1_NSS_PIN        PA4
#define BOARD_SPI1_MOSI_PIN       PA7
#define BOARD_SPI1_MISO_PIN       PA6
#define BOARD_SPI1_SCK_PIN        PA5

#define BOARD_SPI2_NSS_PIN        PB12
#define BOARD_SPI2_MOSI_PIN       PB15
#define BOARD_SPI2_MISO_PIN       PB14
#define BOARD_SPI2_SCK_PIN        PB13

#define BOARD_NR_GPIO_PINS        35
#define BOARD_NR_PWM_PINS         12
#define BOARD_NR_ADC_PINS          9
#define BOARD_NR_USED_PINS         4


#define BOARD_JTMS_SWDIO_PIN      22
#define BOARD_JTCK_SWCLK_PIN      21
#define BOARD_JTDI_PIN            20
#define BOARD_JTDO_PIN            19
#define BOARD_NJTRST_PIN          18

#define BOARD_USB_DISC_DEV        GPIOB
#define BOARD_USB_DISC_BIT        10

// Note this needs to match with the PIN_MAP array in board.cpp
enum {
    PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13,PA14,PA15,
	PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13,PB14,PB15,
	PC13, PC14,PC15
};

これでGPIO,UART、SPIの指定方法・接続ピンが分かりました。

Arduino STM32のサイトのLibrariesの内容を読むと現在のサポート状況が分かります。
I2Cは現状は、"software (bit-banged) implementation" のようです。

I2C. Working, However this is a software (bit-banged) implementation,
and has a maximum speed of around 250kbps. Speed improvements.
Hardware I2C has been tested by some users, but is not integrated into
the normal Wire library.


ライブラリの利用には色々と制約があるようです。

現状は強引にArduino IDE環境で使うよりはARM開発環境を使った方がよさそうです。
ということで、ARM開発環境も構築してみます。

2016/09/21 追記

公開されているモジュールにいくつか進展があるようで、
USB経由でプログラムの書込みが出来ると分かり早速やってみました。
下記の情報を見てやってみました。

GitHub - rogerclarkmelbourne/Arduino_STM32 stm32duino bootloader

ただしブートローダ書き込みの書込みが なぜかstm32flash.exe コマンドで出来ない
ので(P9,P10ピンにUSB-UART接続のシリアルポートを認識せず。やり方がマズい? )
STM32 ST-LINK Utility を使って書き込みました。

02

ブートローダはgeneric_boot20_pc13.bin を使いました。
(ブートローダ起動時にLEDを点滅させるのでその対応のブートローダのようです)

ドライバ(Arduino_STM32\drivers\winにあるドライバ)のインストールも行いました。

Arduino IDEにて書込みに"STM32duino bootloader"を選択します。

06

スケッチの書込みを行うとUSB経由で書込みが出来ました。

04

ただし、書込み後の後に変なエラーで出ています。書込み後にリセットを行う処理っぽいです。

スケッチ的には問題なしです。アスキーコードをシリアル出力するスケッチが
ちゃんと動きました。USB経由にて読めています。

05

以前より、使いやすくなった感じなのでちょっと使い込んでみてもよいかも。


2016/09/23 追記

専用のプログラマを利用ではなく、シリアル通信経由でもブートローダやプログラムの
書込みが出来ること判明、試してみました。

Dscn5769

黄色いジャンパーピンの仕様がここにありました。
シリアル経由でプログラムを書き込むにはこのジャンパーを写真のようにセットします。
これでリセットするとISPモードとなります。

この時、シリアル通信を行うためのピンは
  A9:TXD  、A10:RXD 

です。これにクロス接続してUSB-UARTモジュールなんかを使ってパソコンから
シリアル通信出来るようにします。

この状態で、STM32 Flash loader demonstratorを使ってプログラムの書込みが出来ます。

01

設定値は上記の通りです(Parity Evenもそのままで.. 私はこれでちょっとハマりました)。
NexTを押して、次のステップに進みます。次の画面状態になります。

02

Nextを押して次に進みます。

03

設定はそのままで、Nextで次に進みます。
Dounload to device を選択し、ブートローダのファイルを指定します。
(ファイル選択時に拡張子にBINを指定することに注意)

05_3

これでNextを押して書込みが行われます。

06_2

これでブートローダの書込み完了です。
ジャンパスイッチを元に戻してArduino IDEからはUSB経由で書き込みできるようになります。

2017/01/03 追記

追加購入した左3つ、USB経由の書き込みが出来ませんでした。

Dscn6335

ただしその3つ、USBシリアル通信が全く使えないわけではなく、
STLINK経由でUSBシリアル通信を行うスケッチを書き込むと、
USBシリアル通信は行うことが出来ました。

シリアルポートとしては認識しており、
スケッチ書き込み時のリセット等のタイミングがまずいような感じです。
抵抗補正をやっても出ダメでした。

このBlue Pillボード、見た目は同じでも微妙に異なるようです。
基板のパターンは同じようですが、左3つと右2つ、利用している部品が微妙に異なります。

ます、左3つはCPUが中国工場製、右2つはマレーシア工場製です。
LEDの色も左は赤、右は青です。クリスタルも異なります。

上記の左3つのUSB経由の書込みが出来るようになりました。

2019/02/14
永続モードについての修正

ブートローダの書込み後、書き込みがうまくいかない場合、ブートローダを
永続モード(ユーザープログラムの実行に移らず、書き込みを待ち続ける)にすると
上手く書き込める場合があります。

BluePilボードまたは、ブートローダにgeneric_boot20_pc13.bin を使うボードでは、
永続モードにするには、以前はPC14ピンだったのですが、
新しいブートローダでは、BOOT1ピンを1に設定するに変更となりました。

BOOT1ピンを1にした状態で永続モードにして、スケッチを書き込むと上手くいきます。

一旦スケッチを書き込むと、スケッチに不随するシリアル通信ドライバ経由で、
書き込み時にリセットを書けて、DFUに切り替わることが出来るようです。

スケッチで書き込んだプログラムが暴走した等の場合、
書き込み時、シリアル経由でのリセットがかけられない場合があり、
この時は、手動でリセットボタンを押すか、再度永続モードで書き込めばよいようです。

1017/01/07 追記
(仮のメモ)
タイマー割り込み、SPI、DMA周りの機能が理解出来てきたので、
NTSC信号を生成してビデオ出力を実装してみました。 

実装において、
「建築発明工作ゼミ2008」さんの四角を表示する解説が大変参考になりました。
http://kousaku-kousaku.blogspot.jp/2008/06/arduino_26.html

さすがARM、高機能なタイマーが利用出来ます。
SPI+DMAを使ってのビットデータ出力も非常に便利です。
(スケッチはここ

01

解像度は224x192ドットです。美咲フォントを使って文字を表示してみました。

03

この当たりはブログ再開時に紹介していきます^^

デモ動画その1(解像度208×216)

デモ動画その2(解像度416×216)



1017/01/10 追記
(仮のメモ)
STM32用のTVout互換ライブラリを作成中です。


ArduinoUnoに比べSRAM容量が大きいのでちょっとしたゲームなんかつくれそう。


2015年5月24日 (日)

IchigoJamでQRコードを表示してみる

以前「IchigoJamで疑似グラフィックを使った画像の表示」の記事で紹介したツールの
修正後の動作確認でホームページのQRコードを作成し変換してみました。

IcigoJamで実行すると、こんな感じです。

Dscn3849

ちゃんと認識します(QRコード表示のアイデアはIchigoJam-FANから頂きました)。

Dscn3852

画像はこんな感じです(キャプチャー画面)。
画像は大きいですが、実際のドットサイズは64x48ドットです。

QRコード

QRコードはWord2013の「差し込み文書」の機能を使って作成しています。
参考文献: office ワード エクセル - QRコードの作成 (http://e-yan.net/?p=739)

利用したのは自作ツール「IcigoJam画像コンバータ」ですが、
従来機能にEEPROM書き込みソースを生成する機能を追加しました。

02

「EEPROM書き込み」にチェックを入れて、EEPROM上の書き込み領域の指定として、
書き込みプログラム番号(100~227)を指定します。

生成したプログラムを実行するとEEPROM上のプログラム番号に該当する領域に
画像データ(最大768バイト)を保存します。

保存したデータは、Icihojam上で下記のようなプログラムを実行することで
簡単に画像が表示出来ます(ソースは配布ファイルに添付)。

10 CLS:?"No=";:INPUT A
20 F=(A-100)%64*#400
30 POKE#8D0,F>>8,F&#FF
40 R=I2CR(#50,#8D0,2,#900,768)
50 IF INKEY()=32 GOTO 10
60 GOTO 50

実行すると番号を聞いてくるのでツール利用時に指定した番号を入力します。
該当する画像が表示されます。スペースキーを押すと、再び番号入力となります。
ESCキーを押すとプログラムが終了します。

※EEPROM書き込みの機能を利用するには、EEPROMを別途用意する必要があります。
   IchigoJamでEEPROMで使う情報は下記を参考になります。
    イチゴジャムレシピ - 周辺機器 - 外部記憶装置 EEPROM

ツールはこちらにおいておきます。
   ダウンロード IchigoBmpConv3.zip (13.7K)

【注意】
画像データは、EEPROMに書き込みますので指定した番号にプログラムが保存
されている場合は、上書きされて無くてしまいますのでご注意下さい。

2015年5月22日 (金)

Icihojamの特殊キャラクタ入力

IcihoJamの特殊キャラクタの入力方法が今一分からなかったのでまとめてみました。

01_2

上記のALTはキーボードの左側ALTキーです。

利用できるキャラクタは、公式サイトの「キャラクターコードテーブル(ver0.9.7)」を
参照して下さい。

IchigoJamのファームウェアのアップデートについて

IcigoJamoのファームウェアのアップデートの参照のアクセスが多いので、
情報を改めて掲載します。

1.最新ファームウェアの入手方法

以前はFaceBookの「IchigoJam-FAN(https://www.facebook.com/groups/ichigojam/)
でののみ公開されれていましたが、現在は公式サイト「ichigojam.net」でも公開されています。
現時点の最新版は、1.0.0.b13です。現在の状況としてはかなり頻繁に更新されています。
ダウンロードして解凍すると、次のようなファイルが得られます。
(2015/07/05 現時点では1.01です)

03
この中でファームウェア更新に利用(FlashMagic使用時)するファイルは、
   ichigojam.hex             ・・・ 通常利用ファームウェア
   ichigojam-us.hex        ・・・ USキーボード対応ファームウェア
   ichigojam-xtal.hex      ・・・ 水晶発振子利用ファームウェア
   ichigojam-xtal.hex      ・・・ USキーボード対応&水晶発振子利用ファームウェア

のうちの1つです。各自の環境に合わせて利用します。 
通常はichigojam.hexを利用します。

水晶発振子利用についてちょっと補足します。
Icihojamに搭載しているCPUにクロックを供給する部品です。
IcihojamのCPU内部にもクロックを発生する回路が組み込まれていますが、
CR発信という仕組みのため、ノイズや温度変化に影響を受けます。
影響を受けると、映像が揺らいだりします。利用している表示機器によっては
映らない場合があるようです。

水晶発振子(12MHz)を利用するとクロックの精度が上がり映像安定します。

下の写真のような部品です。

Dscn3841

下の写真のように接続して利用します。

Dscn3843

秋月電子あたりだと1個30円で購入出来ますが、送料が500円かかります。
送料込みだとエレショップが244円(本体124円、送料120円)で購入で出来ます。

水晶発振子を利用する場合は、水晶発振子用のファームウェアを利用する必要が
あります。

2.現在のファームウェア更新状況

1.0版のリリースに向けて、仕様変更・機能追加が激しい状況です。更新によっては、
前回の機能が無くなったり、不具合が発生したりICのピンに割り当ててられた機能が変更
されたりと、利用者側からすると戸惑う変更も多々ありますが、方向としては、より良いもの
に仕上がってきています。

公式サイトでは、修正の経緯については、掲載されておりません。修正履歴等を知りたい
方は、「イチゴジャムレシピ(http://15jamrecipe.jimdo.com)」のIchigoJam バージョン履歴を
閲覧すると良いでしょう。

3.ファームウェアの更新方法
ファームウェアの更新はIchigoJam単体では行えません。ファームウェアを書き込むための
親機(Windows、Mac、Linux等のOSが乗ったパソコン)が必要となります。

ここでは、私の環境であるWindows 8.1のを使った場合の更新方法について説明します。

   1)必要機材
     ・USB-シリアル通信変換モジュール
       IchigoJamとパソコン間でデータ通信を行うための製品です。
       TXD(送信)線、RXD(受信線)、GNDの3線を接続して通信を行います。

     ・ジャンパワイヤー 4本
       接続ケーブルです。
       3本は IcihoJamとUSB-シリアル通信変換モジュールを接続します。   
       もう1本は、IcihoJam上のGNDとISPを接続します。

     全体としての接続は下図のような感じです。

   02 

       まずは、USB-シリアル通信変換モジュールについて補足します。
       高い製品ではありませんが、「シリアル通信? TXD、RXD?、なにそれ?」と
       いう方には、具体的に何を入手したらよいか戸惑うかと思います。

       似たようなものが多数あります(写真は私が持っているものです)。

      

       選択条件は、
         「3.3V対応」、「自分のパソコン用のドライバーソフトがある
       ことです。

       個人的には、Silicon Labs製のCP2102を使った製品がおすすめです。
       3.3V/5.0Vを気にせずに使えます。
       具体的に利用出来そうな入手先は下記の通りです。
      
         ・ ショップのふうせん   USB-シリアルモジュール
           IchigoJam-FANのメンバーが運営しているサイトです。
           税込・送料込みで1,150円です。Silicon Labs製のCP2102搭載製品です。
           IchigoJamでの利用動作確認の上、販売しているのでハズレはないです。
           ジャンパワイヤー付きなので、すぐに利用出来ます。

        ・aitendo USB-UART変換モジュール [USB2UART-CP2102]
           Silicon Labs製のCP2102搭載製品です。税別価格で600円ですが、
           税、送料を含めると1,138円です。ここは知名度のあるショップです。

         ・amazon シリアル·コンバータ UART モジュール CP2102 STC 6ピンケーブル
           税込・送料込みで400円です。Silicon Labs製のCP2102搭載製品です。
           レビューを読むと、IchigoJamでも利用出来ているとの報告があります。
           中国からの直接発送のようで到着まで時間がかかります。

         ・Aliexpress New 6Pin CP2102 Module USB 2.0 To TTL On STC
          海外通販サイトです。現時点で多分これが最安値です。
          送料込みで日本円で182円です。Silicon Labs製のCP2102搭載製品です。
         01
   
         私もこれを使っています。注文から到着まで2週間はかかります。
         値段も安いので、これを機会にAliexpressの利用を始めるとよいと思います。

         Dscn3839

         次にジャンパワイヤー 4本の補足です。
         USB-シリアル通信変換モジュールの形状によりますが、金属端子が
         出ているオスとIcihojamのソケット(メス)を接続するためには、
         メス - オス の形状のものが3本必要です。
         また、Icihojamのソケット(メス)のGNDとISPを接続するにはオス-オスの
         ジャンパワイヤーが必要です。

     2)必要ソフトウェア
        ・USB-シリアル通信変換モジュール 用ドライバソフト
        ・ファームウェアの更新用ソフトウェア  FlashMagic

        Silicon Labs製のCP2102のドライバソフトは下記のサイトから入手出来ます。
          CP210x USB - UART ブリッジ VCP ドライバ
 
        上記のページの「Windows XP/Server 2003/Vista/7/8/8.1 (v6.7) 用をダウンロード」の
         「VCP をダウンロード (3.66 MB)」をクリックしてダウンロードしてインストールします。

         
         書き込みツールはいくつかありますが、FlashMagicを利用します。
         Icihojamが採用しているCPUの製造メーカーのNXPセミコンダクターズも
         FlashMagicを紹介していますので信頼性のあるソフトです。
           NXPセミコンダクターズジャパン - 開発環境 & パートナー、書き込みツール、ISP
         
         上記のサイトの「Flash Magicのダウンロードはこちら」のリンクから入手出来ます。
         
     3)ファームウェアの更新
        (1)結線
         IchigoJamの電源を切った状態で、USB-シリアル通信変換モジュール、パソコン
         を接続します。また、GNDとISPを結線します。
         下記の図のようになります。キーボード、マイクロUSBケーブル、ビデオ出力は
         つなげていても、外しておいてもどちらでも構いません。                  

1_2

           (2)電源を入る
               IcigoJamのスライドスイッチで電源をONにします。
               LEDが点灯し、書き込みモードで起動します。
               (このとき、ビデオ端子を接続していても映像出力されません)

           (3)FlashMagicを起動を起動し、書き込みのための設定を行う
               次のような設定をします。

              COM Portは各自の環境に合わせて設定して下さい。
               Hex ファイルはダウンロードして解凍した中にあるファイルを指定します。
               各自の環境にあうファームウェアを指定します。
               Boad Rateは115200を指定します。

            04

               COM Portが何番か分からない場合は、コマンドプロンプトで、
               modeコマンドで確認出来ます。コマンドプロンプトの起動は、
               windows 8.1ではタスクバーのスタートボタン上でマウス右クリックメニュー
               からコマンドプロンプトを選択します。

             06

             FlashMagicの[虫メガネ]ボタンをクリックしてデータが読めるか確認します。
             下の画面のようにデータが読めれば正常です。

             05

             もし、エラーが発生する場合はCOM Port、TXD、RXDの接続等を見直して
             下さい。

             [start]ボタンを押すと書き込みが開始されます。数十秒で完了します。            

      07

              書き込みが完了したら、IchigoJamの電源をOFFにして
              ISP接続のジャンパワイヤーを外します。シリアル通信を行わないのであれば
              USB-シリアル通信変換モジュール の結線も外します。

              次に電源を入れてファームウェアの更新が正常に行えたが確認します。
              最新の ファームウェア(現時点)1.0.0.b13では、起動時に「プッ」と音が鳴ります。            

              08

以上でファームウェアの更新が出来ます。             
             

2015年5月17日 (日)

UART-I2Cブリッジの使い方 - リアルタイムクロックの調査 -

以前作成したLPC810を使って作成した「UART-I2Cブリッジ」ですが、
用途としてIC2デバイスの動作確認ツールとして活用しています。
ちょっとした調査ならプログラムを作成しないで行えます。

その活用方法のご紹介です。
試しに、Aliexplressで購入したI2C接続のリアルタイムクロックの動作確認をしてみます。

05_2

実物はこんな感じです。送料無料で$1.20(150円)で購入できます。

Dscn3824

使い方や仕様については、デジットさんのブログ
「I2Cバス接続のリアルタイムクロックモジュール入荷!」の記事が参考になります。

基板上にはI2C接続デバイスである、リアルタイムクロック DS1307 と
EEPROM  AT24C32 (4キロバイトEEPROM)が搭載されています。

早速、UART-I2Cブリッジに接続してみます。

Dscn3826

動作確認のツールとしてTeraTermを使います。
通信条件と、端末設定は次の通りです。

01_2

端末の設定では改行コード、ローカルエコーの設定をします。

03_2

@vと入力してバージョンが正常に表示されることを確認します。

04_3

これで準備終了です。

まずは、リアルタイムクロックモジュール上の「リアルタイムクロック DS1307」の
動作確認をしてみます。

デジットさんのブログで公開している「取扱説明書(PDF)」と、DS1307のメーカーの
公開資料を参考にします。
  Maxim S1307 64 x 8、シリアル、I2Cリアルタイムクロック

Maximの資料によると、I2CアドレスはD0でレジスタの内容は下記の通りです。

06_2

I2C接続によるこのデータのは受信は下記の通りです。

10

I2Cアドレスが0xD0で、取得したいレジスタのアドレスを送信してデータを
受信する仕様です。

早速やってみます。
00hから3Fhの64バイトを取得してみます。
UART-I2Cブリッジのコマンドにすると次のようになります。
 @rd040@h00

一括データ送受信を使います。書式は下記の通りです。
  @r[I2Cアドレス][受信データ長][送信データ指定部][改行]

受信データ長は0x40は64バイトを指定、受信前に送信するデータは00です。
@hはデータを16進数で指定するコマンドです。

実行すると下記の結果となります。

08_3

00が実行結果(正常終了)、その下の128桁の文字列が取得データです。
デフォルトでは、16進数の連続文字列として返されます。

これだと結果が分かりにくいので、出力形式を16進ダンプ形式に変更してみます。
 @o2@rd040@h00

出力形式を指定する@oコマンドを頭につけて実行します。
こんな感じでちょっと分かりやすくなります。

09

データを確認すると、このモジュールは正しい時刻が設定されていないようです。
時間も進まず止まっています。レジスタ00のCHに1がセットされているために
時計が止まった状態です。

次にデータの設定を行ってみます。
コマンドとしては、
  一括データ送信   @w[I2Cアドレス][送信データ指定部][改行]
を利用します。

現在の時刻 2015/05/17 (日) 21:00 を設定してみます。
レジスタと設定する値は次の通りとなります。00~07のレジスタに設定すます。

レジスタアドレス:設定値、説明
00:  00   CH=0, SEC = 00秒
01:  00   00分
02:  21   21時 
03:  01   日曜
04:  17   17日
05:  05   05月
06:  15   2015年
07:  00   外部出力なし

UART-I2Cブリッジのコマンドにすると次のようになります。
上記のデータの前に書き込みアドレスの00を付けて送信します。
  @wd0@h000000210117051500

11_2

設定した値を読んでみます。
  @o2@rd008@h00

時計が動いているかを確認するため、3回実行してみます。

12

右から 15年、5月、17日、01(日曜)、21時、01分、25秒と読めます。
また3回の実行で秒が進んでいるのが分かります。

リアルタイムクロックはちゃんと動作しているようです。

次にEEPROM  AT24C32を使ってみます。I2Cアドレスは0xA0です。

EEPROM内アドレス0000に"Hello,World"を書き込んでみます。
データ部の@h0000がアドレスを16進数で指定、@sがデータを文字で指定しています。
AT24C32の仕様では、ページ単位(1ページ32バイト)の書き込みとなります。

書き込み
@wA0@h0000@sHello,World.

13_2

書き込んだデータの読出し

@oで出力形式をバイナリ(無変換)を指定、@ra00cがI2CアドレスA0から12バイトを
データ送信後に読みだす命令です。読み出す前のデータを@hで16進数で指定して
います。ここではアドレスを指定しています。

@o1@ra00c@h0000 

14

一度に読み出せるデータはコマンドの仕様上、255バイト(0xFF)となります。
ちょっと試すとこんな感じです。
@o2@ra0ff@h0000

アドレス00から255バイトを読んで見ました。

15

ここは仕様的に00を指定すると256バイト表示出来るように修正したいですね。

このリアルタイムクロック、コマンド的にはシンプルなので
IchigoJamでも使えそうですね。

接続しているデバイスをスキャンしてリスト表示する機能と
モニター機能(I2Cバス上のデータを表示)も欲しくなってきました。
改造の余地ありです。

関連記事
LPC810を使ったUART-I2Cブリッジの改良版が出来ました (16/07/21)
LPC810を使ったUART-I2Cブリッジの機能拡張の検討中 (16/07/13)
UART-I2Cブリッジの使い方 - リアルタイムクロックの調査 (15/05/17) [この記事です]
Wiiヌンチャクの動作確認しました (15/05/17)
LPC810を使ったUART-I2Cブリッジがやっと出来ました (15/04/15)
ATtiny13AでUART-I2Cブリッジを試作したが微妙 (15/03/29)
ATtiny13AでUART-I2Cブリッジの製作 - まずその準備3 (15/03/26)
ATtiny13AでUART-I2Cブリッジの製作 - まずその準備2 (15/03/25)
ATtiny13AでUART-I2Cブリッジの製作 - まずその準備 (15/03/24)

公開・ダウンロードサイト
GitHub - LPC810 UART-I2Cブリッジモジュール


Wiiヌンチャクの動作確認しました

以前購入したWiiヌンチャク用(多分ぱちもん)
ブレッドボードやArduinoに接続するアダプタが到着したので動作を確認しました。
動作確認にはちょっとハマりました。

アダプタはこんな感じの製品です。

Dscn3820

Wiiヌンチャクの端子にこんな感じで接続します。

Dscn3821

早速、arduinoに接続して動作を確認します。

arduinoでの使い方は次のサイトを参考にしました。
todbot blog - “WiiChuck” Wii Nunchuck Adapter Available

アダプタの接続はアナログポート A2からA5を使います。
A2 : Lレベル  0V出力 (GND)
A3 : Hレベル  5V出力
A4 : I2C SDA
A5 : I2C SCL

電圧は、3.3V推奨のようですが、5Vでも動作します。

Dscn3818

次にプログラムを参考サイトのリンクから入手しArduinoの書き込みます。
todbot/wiichuck_adapter - https://github.com/todbot/wiichuck_adapter

早速動かして見たのですが...

04

値がちゃんと取れません。プログラムを修正してエラーを返すようにしても
エラーは発生していないようです。
アダプタを抜くと、I2Cの通信エラーとなるのでI2Cのアドレスが正しく、かつ
データ取得も正常のようです。

05

そこで、以前製作したUART-I2C変換モジュールで動作確認してみました。

Dscn3819

接続して、TeraTermからサンプルソースを参考にして、I2Cのコマンドを
送信してみます。

@wA4@h4000 がハンドシェイク用のコマンド、@wA4@h0000が利用開始、
@gA406がデータ取得です。

06

試した感じでは、I2Cの通信は問題なさそうです。
ただし、読み取り値がFFFFFFFFFFと正常な値ではありません。

「うーん、これは不良品ではないだろうか」
取りあえず、WiiヌンチャクのI2Cコマンド仕様を探して調べてみることに...
多くのサイトで紹介されており、今回使ったコマンドで問題ないようです。
下記のサンプルやI2Cの解説も同じ感じです。
http://www.robotshop.com/media/files/PDF/inex-zx-nunchuck-datasheet.pdf

ところが、下記の資料の中で
http://web.engr.oregonstate.edu/~sullivae/ece375/pdf/nunchuk.pdf

次の文面を発見
To communicate with the Nunchuk,we must send a handshake signal.
If you are using a black Wii Nunchuk, send 2 bytes 0xF0, 0x55 to initialize
the first register and 0xFB, 0x00 to initialize the second register of the Nunchuk.
On a white Wii Nunchuk, send 0x40, 0x00 followed by 0x00.

要するに、「黒ヌンチャク」と「白ヌンチャク」でハンドシェイクで送るデータが違うようです。
サンプルソースや、出回っている情報は「白ヌンチャク」のものだけです。

私のは「白ヌンチャク」ですが、ぱちもんなので「もしかしたら...」と思い
「黒ヌンチャク」用のハンドシェイクを行ってみると、

07

それらしい値が帰ってきました。
私のは「黒ヌンチャク」のようです。

この修正をArduinoに反映してみると、それっぽい値が取れました。

08

ヌンチャクの操作によって値が変わります。
加速度センサーもちゃんと動いているようです。

I2Cで送信するコマンドは単純なので、IcihoJamでも使えそうです。

(追記)
IchigoJamでも試したのですが、結果はダメでした。
IchigoJamに、データ取得だけを行うコマンドがありません。
I2CR(I2Cアドレス、送信データアドレス、データ長、受信データアドレス、データ長)
というコマンドは、データ送信付きの受信コマンドのため使えませんでした。
データ長に0を指定すると256バイト送信されます。

今回は諦めることにします。


※上記のIchigoJamに関する記載は古いです。
最新のファームウェア1.2.2βでは利用できます。

(参考情報)
福野泰介の一日一創 IchigoJam trying to connect Wii Nunchuck via I2C

関連記事
LPC810を使ったUART-I2Cブリッジの改良版が出来ました (16/07/21)
LPC810を使ったUART-I2Cブリッジの機能拡張の検討中 (16/07/13)
UART-I2Cブリッジの使い方 - リアルタイムクロックの調査 (15/05/17)
Wiiヌンチャクの動作確認しました (15/05/17) [この記事です]
LPC810を使ったUART-I2Cブリッジがやっと出来ました (15/04/15)
ATtiny13AでUART-I2Cブリッジを試作したが微妙 (15/03/29)
ATtiny13AでUART-I2Cブリッジの製作 - まずその準備3 (15/03/26)
ATtiny13AでUART-I2Cブリッジの製作 - まずその準備2 (15/03/25)
ATtiny13AでUART-I2Cブリッジの製作 - まずその準備 (15/03/24)

公開・ダウンロードサイト
GitHub - LPC810 UART-I2Cブリッジモジュール

2015年5月10日 (日)

Wii用ヌンチャクを購入しました

Aliexplressで任天堂ゲーム機 Wii用のヌンチャクを注文し、商品が到着しました。

01

注文から6日で到着しました。送料無料では今までで最短で到着です。

Dscn3814

Wiiは持ってないのですが、I2C接続で利用できると知り、購入しました。
機能としてモーションセンサー(3軸)、ジョイスティック、Cボタン、Zボタンがあります。

Arduino用のライブラリもあり、簡単に利用出来るようです。
  https://github.com/todbot/wiichuck_adapter

Arduinoに接続するための変換アダプタも製品化されており販売されています。

その部品がまた到着しないためまだ実験に着手出来ない状況です。

02

手にフィットしていい感じに使えそうです。

Dscn3815

I2C-UART変換、I2C-PS/2キーボードIF変換等をしてパソコンやIchigoJamに接続して
面白そうなことが出来そうです。

2015年5月 9日 (土)

Word2013(Windows 8.1環境)で中国語(簡体字)にルビを振る

Wordで中国語(簡体字)にルビを振りについてのお話です。

去年試したところ出来なかったのですが、現時点では対応出来ているようです。

下記のサイトにて知りました。大変参考になりました。
中文学習 http://zwxuexi.sakura.ne.jp/index.html
    ・ win8.1でピンインを表記 http://zwxuexi.sakura.ne.jp/page127.html

  本サイトは、簡体字入力のための設定方法等の解説もあり大変参考になります。

実際に試してみました。
Word2013で、言語の選択を中国語(中国語)に指定して文書を入力後、日本語文書と
同じように、ホームタブのフォントリボンのルビでルビ振りできました。



デフォルトのフォントとサイズだと見にくいため、フォントをSimHei、サイズを8ptにしました。



一旦、中断(挫折?)した中国語学習、また始めようかな


関連記事
Windows 8.1のIMEで簡体字(中国語)を入力できるようにする
Windows 8.1で簡体字の手書き入力を行う

2015年5月 6日 (水)

IchigoJamでDVR8830を使ったロボットカー制御(1)

IchigoJamで何か動くものを製作したいと思い、試してみました。
Aliexpressでよさげな、商品を見つけ注文しました。
三輪の形状で二輪駆動のロボットカーです。

01


10日ほどで到着しました。
中華製品にしては珍しく、説明書がついていました。

Dscn3795

当然、説明は中国語です。

Dscn3796

んで、早速組み立てました。

Dscn3800

モーターの制御は以前利用したDRV8830を利用しました。
モーターを2つ制御するので2つ利用しました。

利用したのは秋月電子で購入した次のようなモジュールです。
I2Cバス接続でDCモーターの駆動制御が行えます。
Hブリッジ構成(モーターの正転、停止、逆転の制御)でPWM制御による
モーターの電圧を制御できます。

DRV8830の日本語データシートが下記にあります。
   TEXAS INSTRUMENTS http://www.tij.co.jp/jp/lit/ds/symlink/drv8830.pdf
その他の資料はこちら
   http://www.tij.co.jp/product/jp/DRV8830/description

モーター1つにつき、次のような結線を行います。
C1、C2のコンデンサはパスコン、C3のコンデンサはモーターのノイズ対策用です。
R1、R2はI2Cバス用のプルアップ抵抗です。
R3は、電流制限値1Aとして0.2Ωを抵抗を選定しています。

今回はFAULTnピンによる障害状態のチェックは行っていません。

02

2つのうち一方は、I2Cバスのプルアップ抵抗は不要、
I2Cアドレスが重ならないようにA0、A1をGNDに結線します。
2つのモジュールのI2Cアドレスは0xC0と0xC8(8ビット表記)となります。

モーターの制御は次の簡単な2バイトのコマンドを送るだけです。
1バイト目: レジスタアドレス(=0x00)
2バイト目: VSET(電圧コード)+CTRL(スタンバイ、正転、逆転、ブレーキ)

VSETの値


CTRLの設定値(2進数)
  00  スタンバイ
  01   逆転
  10   正転
  11   ブレーキ

IchigoJamで1つのモータに対して、正転で1.20Vの電圧を付加して回す場合は、
100 POKE #700,0,#F<<2+'10
110 R=I2CW(#64,#700,1,#701,1)


という感じになります。
取りあえず、本体を浮かせて走らない状態でプログラムでモーターを回してみました。
一応、ちゃんと回りました。

電源は、エネループ4本 4.8VからDC-DCコンバータを使って3.3Vを生成して
IchigoJamとDVR8830、モーターに供給しています。

Dscn3805

電流は800mAまで流せます。
基板上に半固定抵抗がついており出力電圧の調整ができます。
これもAliexplressで購入しました。140円くらいで購入できます。

全体としてはこんな感じです。

03

さて、組み上げて色々とセンサーを付けて動かして見たいところですが、
購入した三輪ロボットカー(2輪駆動+キャスター)がどんな動きをするのか
想像が付きません。曲がるには、片輪だけを回せば良いのか、どのくらい小回りが
きくのかさっぱり分かりません。

そこで、まずは先日作成した12ボタンを使った有線リモコン形式にしてみました。
手動操作でどんな動きが可能か、ボタンに色々な動作を割り当てて試したいと思います。

Dscn3801

100円ショップで2mのステレオ延長コードを購入してケーブルを延長しました。
長すぎでノイズが乗って誤動作の感はありますがまあ、よしとしましょう。

Dscn3798

早速、試運転です。プログラムとしては、
前進・行進・停止、右のみ正転・逆転、左のみ正転・逆転をボタンで行えるようにしました。
操作としては、7種類となります。


今回も助手のルミちゃんが走行試験を手伝ってくれました。
意外とよい動きをします。ただ、キャスターが機能していないっぽい。
キャスターのベアリングが固くて全然回らないです。

もう少し、旋回等を試してからセンサー等を付けて自動運転させたいと思います。

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

10 CLS:CLV:
20 POKE #700,0,0,0,0
30 LET[0],80,150,250,400,500,600,650,720,800,840,880,950
40 LET[20],#F<<2+`10,0,#F<<2+`01,#0
50 B=-1:I=0
60 A=ANA()
70 IF A<[I] THEN B=I:GOTO 100
80 I=I+1:IF I<12 GOTO 60
90 GOTO 50
100 LC 0,0:? B;" ";A;"    "
110 IF B=0 C=[20]:D=[21]:GOTO 200
120 IF B=1 C=[21]:D=[21]:GOTO 200
130 IF B=2 C=[22]:D=[21]:GOTO 200
140 IF B=4 C=[20]:D=[20]:GOTO 200
150 IF B=5 C=[21]:D=[21]:GOTO 200
160 IF B=6 C=[22]:D=[22]:GOTO 200
170 IF B=8 C=[21]:D=[20]:GOTO 200
180 IF B=9 C=[21]:D=[21]:GOTO 200
190 IF B=10 C=[21]:D=[22]:GOTO 200
195 C=[21]:D=[21]
200 GOSUB 500
210 GOTO 50
500 'MTR DRV(C,D)
510 POKE #701,C:POKE #703,D
520 R=I2CW(#60,#700,1,#701,1)
530 R=I2CW(#64,#702,1,#703,1)
540 RETURN

500行以降がモーターの制御です。
残りはリモコンの判定と各ボタンを押したときのモーターの挙動を設定しています。



2015年5月 4日 (月)

IchigoJamでアナログ入力を使った6ボタン入力

IchigoJamのアナログ入力(IN2ピン)を使った6ボタン ON/OFF判定を試してみました。
IchigoJamとの接続は3線のみのです。外観は次のような感じです。

ボタン名称は左から、A、B、C、D、E、Fボタンとします。

Dscn3789

プログラムは、次のような感じです。
アナログ値を読み取り、値によってどのボタンが押されたか判定します。

10 CLS
20 LET[0],100,200,400,500,700,800
30 A=ANA():B=-1:I=0
40 IF A<[I] THEN B=I:GOTO 60
50 I=I+1:IF I<6 GOTO 40
60 LC 0,0
70 IF B<0 ? "---";" ";A:GOTO 30
80 ? "[";CHR$(65+I);"]";" ";A;"    "
90 GOTO 30


実行して、動作確認をします。押したボタンとアナログ値(0~1023)を表示します。

ボタンを押していない場合
10

Aボタンを押した場合
04

Bボタンを押した場合
05

Cボタンを押した場合
06

Dボタンを押した場合
07

Eボタンを押した場合
08

Fボタンを押した場合
09

ちゃんと判定出来ました。

結線は次の通りとなります。ブレットボード上にタクトスイッチと抵抗を結線し、
配線をIchigoJamのVCC(3.3V)、ANA(IN2ピン)、GNDに接続します。

02_2

ボタンを押した場合は、GND-ANA間の電圧は図の右表のようになり、
IchigoJamのANA(IN2)から読み取った値はほぼ、表の数値となります。
この値と比較してどのボタンが押されたかを判定します。

             
計算式は下記の通りです。
Bボタン: 330/(330+2200)*1024-1 = 132
Cボタン: (330+680)/(330+680+2200)*1024-1 = 321
Dボタン: (330+680+1000)/(330+680+1000+2200)*1024-1 = 487
Eボタン: (330+680+1000+1800)/(330+680+1000+1800+2200)*1024-1 = 648
Fボタン: (330+680+1000+1800+3300)/(330+680+1000+1800+2200+3300)*1024-1 = 781

押していないとVCC-ANA間はVCC(3.3V)なので、1023となります。
Aボタンを押すと、ANAがGNDにつながるのでANAの電圧は0Vで値は0となります。
B~Fのボタンを押すと、抵抗による分圧で上記の式の計算値となります。

判定処理が必要なので、シューティングゲームなどのリアルタイム操作を
行う場合は遅くなりそうですが、3線でボタンが増やせるのは便利です。

この回路では、ボタンの同時押しには対応していません。
同時に押した場合、図では上部のボタンが押されたと判定します。
(例:Bボタン、Eボタンを同時に押すとBボタンと判定します)

今回の実験では、6ボタンでしたが頑張れば12ボタンくらいは実装出来そうです。

11

もっと頑張れ15ボタンくらいいけるかもしれません。

最新ファームウェア 1.0.0b6ではアナログ入力が2ポートに増えたので、
4線の接続で30ボタンいけるかもしれませんね。

2015/05/05 追記

12ボタンバージョンを基板実装しました。
以前購入した、「秋月電子 お楽しみ袋」にタクトスイッチがいっぱい入っていたので
有効活用しました。

Dscn3791

この基板では12個が限界です。基板が大きければ頑張れば15個はいけますね。

Dscn3792

裏はいつもの、段ボールです。

Dscn3793

ねじを外せばいつでも配線にアクセス可能です。
動作確認のIcigoJamソース

10 CLS
20 LET[0],80,150,250,400,500,600,650,720,780,840,880,950
30 B=-1:I=0
40 A=ANA()
50 IF A<[I] THEN B=I:GOTO 70
60 I=I+1:IF I<12 GOTO 40
70 LC 0,0
80 IF B<0 ? "---";" ";A;"    ":GOTO 30
90 ? "[";CHR$(65+I);"]";" ";A;"    "
100 GOTO 30

問題なく動作しました。

20150505161110

3線で12個のボタンが使えます。
基板のレイアウトはこんな感じです。

13

2015/05/06 追記
このスイッチの他に、色々とデバイスを接続すると電源の電圧変動やノイズがのり
アナログ値が揺らぐようです。ですのでボタン間の数値の幅が狭いとご判定するようで
12個当たりが限界のようです。


2015年5月 3日 (日)

IchigoJamとArduinoでI2Cバス通信を試してみる (2)

前回の続きです。

ちょっと実用的な実装をやってみました。
Arduinoに赤外線リモコン受信機能を実装して、IchigoJamからI2C経由で
参照できるようにしました。

ちなみに、IchigoJamのファームウェアのバージョンは1.0.0B6です。

Dscn3786

配線は、前回の回路に赤外線リモコン受信モジュールを追加したのみです。

01
秋月電子で販売されているPL-IRM2161-XD1 という製品を利用しました。

Arduino用のプログラムは以前作成したものを流用してます。
赤外線リモコンのフォーマットはいくつかありますが、今回はNECフォーマットのみ
の対応です。

赤外線リモコンは、その辺に転がってた中華製ポータブルプレイヤーに付属していた
ものを利用しました。カスタムコードは00FD、各ボタンに割り付けられているコードは
下記の通りです。

Dscn3787

IchigoJamでは、上記リモコンの"2"、"8"でキャラクタを上、下、"4"、"6"で左右に
移動させます。

IchigoJamのプログラム

10 'I2C IR remote
20 CLS:CLV:POKE #700,0,0
30 X=16:Y=12
40 R=I2CR(#10,#700,2,#800,4)
45 LC 0,0:?HEX$([0],4);" ";HEX$([1],4)
50 IF [0]=0 GOTO 100
60 IF [1]=#28 X=X-1:GOTO 100
70 IF [1]=#68 X=X+1:GOTO 100
80 IF [1]=#88 Y=Y-1:GOTO 100
90 IF [1]=#98 Y=Y+1
100 LC X,Y:? "O"
110 GOTO 40

40行のI2CR命令でArduinoからデータを取得しています。
取得したデータはアドレス#800から4バイト格納されます。
この#800から始まる領域は、IchigoJamの配列変数に利用されるています。
配列変数 [0] が#800~#801、[1]が#802~#803用です。
ちょっと、分かりにくですが直接配列変数に取得データをセットしています。

[0]は、既に取得しているデータかをArduinoから受け取っています。
[1]は、リモコンの押したボタンコードを受け取っています。

Arduinoのプログラム

#include <Wire.h>

// for I/O Port
#define IR    4
#if !defined(PORTD) 
 #define IR_DDR    DDRB
 #define IR_PORT   PORTB
 #define IR_PININ  PINB
#else
 #define IR_DDR    DDRD
 #define IR_PORT   PORTD
 #define IR_PININ  PIND
#endif

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

uint16_t ir_customCode = 0;   // カスタムコード
uint8_t ir_data = 0;          // コマンドデータ
uint8_t lfgnewData = 0;       // 新規IRデータフラグ

//
// 赤外線リモコンコード取得
// 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 receiveEvent(int howMany) {
  byte d;
  //Serial.println(howMany);
  if(Wire.available()) {
      d = Wire.read()  ;
  }
}
  
// I2CマスタからのIR受信データ取得要求の処理
// 送信データ
//  属性: 0x00:新規データなし 、0x01:新規データあり
//  カスタムコード:2バイト
//  コマンドデータ:1バイト
void requestEvent() {
    byte d[4];
    d[0] = lfgnewData;
    d[1] = 0;
    d[2] = ir_data;
    d[3] = 0;
    Wire.write(d,4);
    //Serial.println("req"); 
    lfgnewData = 0;   // 新規IRデータフラグ
}

void setup() {
  IR_DDR &= ~_BV(IR);  // IRピンのみ入力設定する
  Serial.begin(115200);
  Wire.begin(0x10) ;                    // I2Cの初期化、自アドレスを8とする
  Wire.onRequest(requestEvent) ;     // 割込み関数の登録
  Wire.onReceive(receiveEvent) ; 
}

void loop() {
  uint32_t rc =  Read_IR();  // IR受信
  if (rc) {
    if (rc != 0xFFFFFFFF) {
      ir_customCode = (uint16_t)(rc>>16);
      ir_data = (uint8_t)(rc>>8&0xff);
      lfgnewData = 1;
      //Serial.print("custom="); Serial.print(ir_customCode,HEX);
      //Serial.print(" data=");  Serial.println(ir_data,HEX);
    }
  } else {
    //lfgnewData = 1;
    //serOut("Repeat\n\r");
  }
}

setup()でI2Cのスレーブの設定を行い、IchigoJamからの要求に対処するための
コールバック関数を登録しています。これは前回と同じです。

loop()ではRead_IR()で赤外線リモコン受信処理を行っています。
データを受信するまで復帰しない関数です。受信するとそのデータを変数に格納します。
非同期でのIchigoJamからのデータ要求でこの変数の値を渡しています。

IchigoJamで動かすと、赤外線リモコン操作でキャラクタが移動します。
ボタンを押すたびに移動します。押し続けても連続移動しません。
もし、押し続けてる間移動したい場合は、
Arduinoのプログラムのコメントアウトしている//lfgnewData = 1; の// をとってください。

20150503121026

なんか、これはいい感じに使えそうです。
LPC810で実装してモジュール化してもいいかも。

2015年5月 1日 (金)

IchigoJamとArduinoでI2Cバス通信を試してみる

IchigoJamとArduino間でI2Cバスを使ってデータ通信を試してみました。
Arduinoをスレーブとして接続し、マスタであるIchigoJamからの要求に答えます。

04

             Dscn3780

先に結論をいうと、ArduinoのI2Cライブラリ Wireにバグがあるため、
Arduinoをスレーブとして完全に使い込むことは出来ません。
ライブラリの修正が必要となります。

 
   => 2016/05/36 追記

        バグは1.6.6で対応されているようです。
        よって、本記事の内容はArduino IDE 1.6.5までのお話しです。
        また、ArduinoのSDA/SCL端子はプルアップ抵抗有効化されているため
        回路図の2.2kΩ抵抗は無くても動作します。

まずは、正常に動作するIchigoJamからArduinoにデータを送信するパターンの
動作確認です。

1)IchigoJamからコマンド2バイト+データ4バイトをArduinoに送信する例

IchigoJam側のプログラム(I2Cマスタ)
    10 'send data
    20 POKE #700,1,2
    30 POKE #702,3,4,5,6
    40 R=I2CW(#10,#700,2,#702,4)
    50 ?R
    60 END

#700番地から格納されている2バイトデータ 1, 2 をコマンド、
#702番地から格納されている4バイトデータ 3,4,5,6 をデータとして
I2Cアドレス #10(7ビット)に送信します。

Arduinoのプログラム   

#include <Wire.h>

// マスターからを受信
void receiveEvent(int n) {
  byte d;
  Serial.println("recept data");
  for (int i=0; i < n; i++) {
    if(Wire.available()) {
        d = Wire.read();
        Serial.print(d,HEX);
        Serial.print(" ");
    }
    Serial.println();
  }
}

//セットアップ
void setup() {
  Serial.begin(115200);
  Wire.begin(0x10) ;                 // I2Cの初期化、自アドレスを10とする
  Wire.onReceive(receiveEvent) ;     // マスタからのデータ送信対応のコールバック関数登録
  Serial.println("i2c slave test");
}

void loop() {
}

I2Cアドレスとして#10を設定し、データ受信時に呼び出されるコールバック関数
recevEventを登録し、その関数内でデータを表示しています。

実行結果

IchigoJam側

03

正常終了しました。

arduino側も受信したデータを問題なく表示しました。

02

次に問題のIchigoJamからのデータ取得要求について試してみます。
IchigoJamでArduinoから送られてくるデータを受信するパターンです。

2)IchigoJamでArduinoからのデータを受信する

具体的な例としてはEEPROMからデータを取得するような通信です。

05

一回の通信で、IchigoJamからI2Cアドレスとデータを送信し、Arduino側からの
送信データを受信するパターンです。

IchigoJam側のプログラム

 10 'request data
 20 POKE #700,0,0
 30 R=I2CR(#10,#700,2,#702,4)
 40 ?R
 50 FOR I=0 TO 3
 60 ?HEX$(PEEK(#702+I),2)
 70 NEXT
 80 END

#700番地から格納されている2バイトデータ 1, 2 をコマンド、
#702番地から4バイト分がスレーブから受信データを格納する領域として指定、
I2Cアドレス #10(7ビット)にデータをリクエストします。

Arduino側のプログラム

#include <Wire.h>

// マスターからを受信
void receiveEvent(int n) {
  byte d;
  Serial.println("recept data");
  for (int i=0; i < n; i++) {
    if(Wire.available()) {
        d = Wire.read();
        Serial.print(d,HEX);
        Serial.print(" ");
    }
    Serial.println();
  }
}

// マスターからのリクエストに対するデータ送信
void requestEvent() {
  Serial.println("resept request.");
  Wire.write("Hello");
}

//セットアップ
void setup() {
  Serial.begin(115200);
  Wire.begin(0x10) ;                 // I2Cの初期化、自アドレスを10とする
  Wire.onRequest(requestEvent) ;     // マスタからのデータ取得要求のコールバック関数登録
  Wire.onReceive(receiveEvent) ;     // マスタからのデータ送信対応のコールバック関数登録
  Serial.println("i2c slave test");
}

void loop() {
}

データ取得要求に対して、requestEvent()で応答を返します。 これを実行すると
IchigoJamにデータが返されず、通信もエラーとなります(Rの値が0でない)。

07

Arduino側のターミナル出力にはrequestEvent()で記述しているメッセージが
表示されません。
ロジックアナライザで調べてみると、

01

2バイトのデータ送信後、受信に切り替えるリピートStart+I2Cアドレス送信が
うまくいってないようです。
当初、原因が分からなかったのですが、Arduino側が明らかにおかしいと判断し、
I2Cライブラリ Wireを調べると、原因がわかりました。

\libraries\Wire\utility\twi.cのISR(TWI_vect)のリピートStartの処理で次のようなことを
行ています。

    case TW_SR_STOP: // stop or repeated start condition received
      // put a null char after data if there's room
      if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
        twi_rxBuffer[twi_rxBufferIndex] = '\0';
      }
      // sends ack and stops interface for clock stretching
      twi_stop();
      // callback to user defined callback
      twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
      // since we submit rx buffer to "wire" library, we can reset it
      twi_rxBufferIndex = 0;
      // ack future responses and leave slave receiver state
      twi_releaseBus();
      break;

TW_SR_STOPはSTOPまたは、リピートSTARTを受信時に処理を行う箇所です。
この中で、リピートSTART受信のため、直前に受信したバッファ内データを
twi_onSlaveReceive()を実行してrecevEvent()を呼び出しています。
これにより、IchigoJamからの送信データは受信できます。

その後の処理が問題でこのタイミングでtwi_stop()を実行しています。
明らかにおかしいと思い、色々と調べると、同様のことを指摘している情報が
いくつかありました。次のリンクはその一つです。

Wire Library doesn't handle Repeated START commands in I2C slave mode [imported] #848

上記の文書では、twi_stop()をコメントアウトすることで対応可能と書かれています。

実際にやってみると、

08

正常に動作しました。

Arduino側のモニター出力にも正常に呼び出されたメッセージが表示されました。

ということで、ArduinoのI2Cライブラリのスレーブ処理にはバグがあります。
最新版の1.6.4でも試したのですが、いまだに対処されていないようです。

なぜ、対応されないのでしょうね。まあ、スレーブとして使うことはあまりないですからね。

2016/04/30 追記
上記のバグは1.6.6で対応されているようです。

リリースノートの抜粋

01

下記は1.6.8(現時点最新版)
  \Arduino 1.6.8\hardware\arduino\avr\libraries\Wire\src\utility\twi.cのISR(TWI_vect)
 
    case TW_SR_STOP: // stop or repeated start condition received
      // ack future responses and leave slave receiver state
      twi_releaseBus();
      // put a null char after data if there's room
      if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
        twi_rxBuffer[twi_rxBufferIndex] = '\0';
      }
      // callback to user defined callback
      twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
      // since we submit rx buffer to "wire" library, we can reset it
      twi_rxBufferIndex = 0;
      break;

« 2015年4月 | トップページ | 2015年6月 »