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

arduino

2019年3月21日 (木)

BluePillボードで4桁7セグLEDの制御

先日のArduino STM32用タイマー割り込みライブラリを使って、
BluePillボードを使って、4桁7セグLEDをダイナミック点灯にて制御してみました。

Dscn9818

動いている様子



以前、秋月電子で入手して放置していた 4桁7セグLEDはOSL40562-IG を利用しました。
このOSL40562-IGアノードコモンでVFが3.3Vと高く 少々使いにくです。

  ダイナミック接続4桁高輝度緑色7セグメントLED表示器 アノードコモン アノード共通接続 OSL40562-IG

  01


03

とりあえず、次のような回路で駆動させてみました。

02

BluePillボードの5Vトレラント対応のピンを使って駆動させます。
各LEDに流れる電流は5mA程度にしています。
I = (5[V] - Vf[V] ) / 330[Ω]  = (5 - 3.3) /330 = 0.00515[A] ≒ 5[mA]

各桁セグメントDIG1 ~ DIG4は、LED8個分の40mAが流れます。 
BluePillボードでは20mAまでしか流せないため、PNPトランジスタ 2SA1015を使って
駆動させるようにしました。

スケッチ
//
// 4桁高輝度緑色7セグメントLED表示器(アノードコモン) OSL40562-IG の制御
// 2019/03/17 たま吉さん 
// 利用パーツ
//  BluePillボード
//  4桁7セグメントLED  OSL40562-IG x 1
//  桁制御用トランジスタ    2SA1015L-GR x 4
//  LED電流制御用抵抗       330Ω x 8
//  トランジスタベース抵抗  10kΩ x 4
//

#include "TimerEvent.h"

// タイマー割り込み管理
TimerEvent ticker;     
#define REFTIME 4

// デジタルピンの定義
#define DIG1  PB12
#define DIG2  PB13
#define DIG3  PB14
#define DIG4  PB15
#define SEGA  PB3
#define SEGB  PB4
#define SEGC  PB6
#define SEGD  PB7
#define SEGE  PB8
#define SEGF  PB9
#define SEGG  PB10
#define SEGP  PB11

// 桁表示ON・OFF
#define DIG_ON   0
#define DIG_OFF  1

// セグメント表示ON・OFF
#define SEG_ON   0
#define SEG_OFF  1

// セグメントビット定義
#define BIT_A 0b10000000
#define BIT_B 0b01000000
#define BIT_C 0b00100000
#define BIT_D 0b00010000
#define BIT_E 0b00001000
#define BIT_F 0b00000100
#define BIT_G 0b00000010
#define BIT_P 0b00000001

// フォントの定義
const uint8_t font[12] = {
  BIT_A|BIT_B|BIT_C|BIT_D|BIT_E|BIT_F,       // 0
  BIT_B|BIT_C,                               // 1
  BIT_A|BIT_B|BIT_G|BIT_E|BIT_D,             // 2
  BIT_A|BIT_B|BIT_G|BIT_C|BIT_D,             // 3
  BIT_F|BIT_B|BIT_G|BIT_C,                   // 4
  BIT_A|BIT_F|BIT_G|BIT_C|BIT_D,             // 5
  BIT_A|BIT_F|BIT_E|BIT_D|BIT_C|BIT_G,       // 6
  BIT_A|BIT_B|BIT_C,                         // 7
  BIT_A|BIT_B|BIT_C|BIT_D|BIT_E|BIT_F|BIT_G, // 8
  BIT_A|BIT_B|BIT_C|BIT_D|BIT_F|BIT_G,       // 9
  0,                                         // ブランク
  BIT_G,                                     // -
};

// 桁制御ピン
const uint8_t pin_dig[4] = {
  DIG1, DIG2, DIG3, DIG4,
};

// セグメント制御ピン
const uint8_t pin_seg[8] = {
  SEGA, SEGB, SEGC, SEGD, SEGE, SEGF, SEGG, SEGP,
};

// 表示用データ
volatile uint8_t digit[4];

// タイマー割り込み呼び出し関数
void dinamic_update() {
  static uint8_t cnt = 0;
  for (uint8_t i = 0; i < 4; i++)
    digitalWrite(pin_dig[i], DIG_OFF); 
  for (uint8_t i = 0; i < 8; i++)  
     digitalWrite(pin_seg[i], digit[cnt] & (0x80>>i) ? SEG_ON:SEG_OFF);
  digitalWrite(pin_dig[cnt], DIG_ON); 
  cnt++; if (cnt == 4) cnt = 0;
}

// データのクリア
void cls() {
  digit[0] = 0; digit[1] = 0; digit[2] = 0; digit[3] = 0;
}

// 数値の設定
void setNumber(uint16_t n, uint8_t dt = 0) {
  if (n>9999)
    return;

  cls();
  uint8_t dec = 0;
  // 4桁目
  if (n >= 1000) {
    digit[0] =font[ n / 1000]; n = n % 1000; dec = 1;
  }
  // 3桁目
  if (n >= 100) {
    digit[1] = font[n / 100]; n = n % 100; dec = 1;
  } else if (dec) {
    digit[1] = font[0];
  }
  // 2桁目
  if (n >= 10) {
    digit[2] = font[n / 10]; n = n % 10; dec = 1;
  } else if(dec) {
    digit[2] = font[0];
  }
  // 1桁目
  digit[3] = font[n];

  // 小数点
  if(dt && dt <=4) {
    digit[4-dt] |= BIT_P;
  }
}

void setup() { 
  //  桁ピンの初期化
  for (uint8_t i = 0; i < 4; i++) {
    pinMode(pin_dig[i], OUTPUT_OPEN_DRAIN);
    digitalWrite(pin_dig[i], DIG_OFF);
  }

  //  セグメントピンの初期化
  for (uint8_t i = 0; i < 8; i++) {
    pinMode(pin_seg[i], OUTPUT_OPEN_DRAIN);
    digitalWrite(pin_seg[i], SEG_OFF);
  }

  // 表示データの初期化
  for (uint8_t i = 0; i < 4; i++) {
    digit[i] = 0;
  }

  // LEDダイナミック点灯用割り込み設定
  ticker.set(REFTIME, dinamic_update);  // REFTIME間隔で dinamic_update()を呼び出す
  ticker.start();                       // タイマー割り込み実行開始
}

void loop() {
  static uint16_t n = 0;
  setNumber (n,millis()%1000>500?1:0);
  delay(100);
  n++; if (n>9999) n = 0;
}

タイマー割り込みは4m秒間隔で実行させています。
一回の割り込みで4桁のうちの1つを表示させています。
全桁更新周期は 4m秒 x 4 = 16m秒 ≒ 1/60秒 です。
これは、人間の目がちらつきを感じない周期です。
これ以上遅くすると、ちらついて見えます。

電圧を5Vではなく、3.3Vにしても問題なく点灯出来ました。
VF 3.3Vとありますが、実際はもっと低い値のようです。

2019年3月17日 (日)

Arduino STM32用タイマー割り込みライブラリを作成しました

Arduino STM32用のタイマー割り込みライブラリを作成しました。

・Arduino STM32用 簡易タイマー割り込みライブラリ (Tamakichi/STM32_TimerEvent)
  https://github.com/Tamakichi/STM32_TimerEvent

Arduino STM32では、最初から強力なタイマー割り込みライブラリがあるのですが、
少々設定が面倒なので、もう少しお手軽に使えるライブラリを作成しました。
(正確には、ラッパークラスライブラリですね)

次のような感じで使います。
BluePillボード上にあるLEDを0.5秒間隔で点滅するスケッチです。
#include "TimerEvent.h"

#define LED_PIN  PC13 // LEDピン

// タイマー割り込み管理
TimerEvent ticker;     

// タイマー割り込み呼び出し関数
void handle_timer() {
  static uint8_t sw = LOW;
  sw = !sw;
  digitalWrite(LED_PIN, sw);      // LEDの制御
}
 
void setup() {
  pinMode(LED_PIN, OUTPUT);
  ticker.set(500, handle_timer);  // 0.5秒間隔で handle_timer()を呼び出す
  ticker.start();                 // タイマー割り込み実行開始
}

void loop() {

}
 

設定できる割り込み間隔は 1ミリ秒 ~ としています。
利用するハードウェアタイマを明示的に指定することが出来ます。

次のような感じで複数のタイマー割り込みを同時実装することも出来ます。
また、割り込み優先度を指定することが出来ます。

// タイマー割り込み管理
TimerEvent ticker1(Timer1);
TimerEvent ticker2(Timer2);
TimerEvent ticker3(Timer3);
TimerEvent ticker4(Timer4);
・・・

ticker1.set(100, handle_timer1); ticker1.setPriority(14);
ticker2.set(200, handle_timer2);
ticker3.set(400, handle_timer3);
ticker4.set(800, handle_timer4);
・・・

ticker1.start();
ticker2.start();
ticker3.start();
ticker4.start();

上記では、ticker1の優先度をticker2 ~ ticker4 よりも上げています。
ticker1は、ticker2 ~ ticker4の割り込み処理実行中に更に割り込んで実行できます。
ticker1の割り込み実行中は、ticker2 ~ ticker4の割り込み実行は保留されます。

割り込み優先度の設定については、シリアル通信、I2C、ピン変化等の割り込み優先度も
考慮して設定する必要があります。

割り込み優先度は0~15の16レベルがあり、
デフォルトでは、すべての割り込み優先度は最低の15が設定(0が最優先)されています。
ただし、同一の優先度の場合は、割り込みベクター番号が小さいほど優先度が高いです。

このたりの詳細については、Arduino STM32の低レベルAPI nvic.h が参考になると思います。
Nested Vector Interrupt Controller (NVIC) support(nvic.h)


元祖 AVR版Arduinoでも割り込み機能はあるのですが、
優先度が固定のため、特定の割り込み処理中でI2C通信が出来ない等、
(I2Cの割り込み優先度は最低レベルに近い)
多重割り込みを使う場合、場合によっては色々と難儀しました。

その点、ARM cortex M3 の割り込み機構 NVIC はかなり強力で自由度があり
使いやすいです。

2019年3月13日 (水)

M5Stack用CardKBをPS/2インタフェース対応にしてみる(3)

前回の続きです。
専用ケーブルを作りました。
また、ファームウェアは若干問題があり、 2019/03/10に修正しています。

Dscn9806

USBコネクタは、秋月電子で販売されている
ケーブル取付用USBコネクタ(Aタイプ オス)を利用しました。

03

熱収縮チューブで固定し、その上から結束バンドで固定しました。

Dscn9808

これなら、抜き差しに耐えられると思います。

ケーブルは、スイッチサイエンスのM5Stack用GROVE互換ケーブル 50 cm(2個入り)
に変更しました。

04

とりあえず、これで完成とします。

今回の製作では、ボードにのっているNeoPixcelで若干ハマりました。

制御に使っているAdafruit NeoPixel ライブラリがNeoPixcel へのデータ送信で
割り込み禁止をかけていて、起動直後のPS/2イニシャル処理を邪魔します。
対策として、起動時のLEDの点滅処理を削除しました。

Arduino(AVR)で割り込みを併用するようなプログラムでは
Adafruit NeoPixel ライブラリは使わない方が良さそうです。

2019年3月 8日 (金)

M5Stack用CardKBをPS/2インタフェース対応にしてみる(2)

前回の続きです。

GithubにてPS/2インタフェース対応ファームウェアを公開しました。

・ CardKeyBoard PS/2 インタフェース版 ファームウェア
   https://github.com/Tamakichi/CardKeyBoard_PS2
  (2019/03/10 更新しました:  (内容) PS/2イニシャル時0X00送信削除、応答無しでも次に進む、LED点滅廃止

オリジナル版になかった [カナ] [Insert][F1] [F10] キー等を追加しました。
IchigoJamでのローマ字カタカナ入力にも対応しています。

プログラム入力には困らないと思います。

Dscn9772

Dscn9774

ケーブルには次の信号を割り当てています。

02

03

IchigoJamで利用する場合、
ジャンパーワイヤー(オス - オス)を使って、端子に接続でも利用出来ます。
   GND    - GND
   VCC    - 5V or 3.3V
   KBD1  - CLK
   KBD2  - DATA

Dscn9783

USBコネクタ(オス)を用意して、結線してUSB接続でも利用出来ます。

04

キーを押すのが固めですが、公開されているこのキーボード用ケースの
3Dプリンター用データを出力して装着すると、かなり改善されて入力しやすくなりました。

Dscn9780


ファームウェアの書き込みが少々面倒ですが、下記のサイトにて詳しい方法が
分かりやすく解説されています。大変参考になりました。
しかるのち - M5Stack:CardKB ファームウェア更新


2019/03/10 追記

IchigoJam(V1.3.1)での利用で、キーボードを認識しないとの報告があり、
手持ちの世代の違うIchigoJamを試したところ、認識出来ないボードが1つありました。

Dscn9799

下段のビデオ端子が白いボードが認識出来ませんでした。
ファームウェアは1.2.1と古いですが、安定したバージョンです。

調べると、キーボード起動時のLED(NeoPixel)点滅が原因のようです。

制御を行うAdafruit NeoPixelライブラリが内部で割込停止を行っており、
PS/2イニシャル処理(ピン変化を割込みで検知)の邪魔をするようです。

点滅を無くすと認識出来るようになりました。
他のボードは問題なかったので、起動時の微妙なタイミングで発生するようです。
(電源周りの差異で立ち上がりが微妙に違う等)


2019年3月 7日 (木)

M5Stack用CardKBをPS/2インタフェース対応にしてみる(1)

先日入手したI2Cインタフェースの小型キーボードM5Stack用CardKB、
ファームウェアを修正してPS/2 インタフェース対応にしてみました。

I2C接続用端子をそのまま、PS/2 インタフェース用に利用しています。

IchigoJam
豊四季タイニーBASIC Arduino STM32版にて動作確認しましたが、
とりあえず、使えています。

IchogoJamでの利用

Dscn9738

豊四季タイニーBASIC Arduino STM32での利用

Dscn9746

動いている様子(動画)


修正したスケッチはこちらです。

追加としてF1 F10 キー対応、
HOMEInsertPageUpPageDownEndキーが使えるようにしました。

詳細については、週末に整備し、GitHubにてドキュメントを付けて公開したいと思います。

2019年3月 6日 (水)

I2Cインタフェースの小型キーボードを試してみる

AliexpressにてM5Stack用のI2Cインタフェースのキーボードを見つけ、入手しました。

  M5Stack Official CardKB Mini Keyboard Unit MEGA328P GROVE I2C

  02

CardKBに関する情報
  ・M5Stack - docs CardKB
  ・Github M5-ProductExampleCodes/Unit/CARDKB/
  ・frame and key-top for M5Stack CardKB


送料がちょっと高めで、1個だけ購入すると割高のため2個購入しました。
M5Stack公式製品なので、そのうちスイッチサイエンスでも販売されるかもしれません。


到着した製品

Dscn9721

ボード

Dscn9722

ATmega328Pが乗っています。ボードの左下にISP用の端子用のランドがあります。

公開されているファームウェアのソースを見ると、Arduinoでベースのようです。
水晶振動子が無いので、内部RC発信8MHzっぽいです。

とりあえず、豊四季Tiny BASIC for STM32環境でI2C接続で使ってみました。

Dscn9729

コネクタがGROVE仕様のため、長足のシングルピンソケットを加工して、
ブレッドボードでつかえるようにしました。
2mmピッチなので、微妙にピンを曲げています。

Dscn9726 Dscn9727

とりあえず、動作しました。
ただし、豊四季Tiny BASICのI2CR()関数に不具合を見つけ、豊四季Tiny BASICを
少々、修正しました。

01

3.3Vで動作しました。
I2Cのバスクロックは100kHz、400kHzとも試してみましたが動作しました。

ボード上にNeoPixel(LED)が乗っているのですが、
シフトキーのロック、シンボルキーのロック等の状態を、色や点滅で状態を教えてくれます。
文字入力は意外とストレスを感じないですが、タクトスイッチのボタンが固いのが残念です。

ファームウェアがArduinoなので、改造してPS/2インタフェースに変更できるかもしれません。


追記

IchigoJamでもI2Cインタフェースで利用出来ました。

Dscn9733

2019年2月22日 (金)

MSXのジョイスティックポートを使ったシリアル通信 (1)

MSXでジョイスティックポートを使ったシリアル通信が出来るらしいので、
事例を少々調べてみました。

シリアル通信が使えると、パソコンとの通信やArduinoとの連携等が出来るので、
色々とと楽しいことが出来ます。

ジョイスティックポートを使ったシリアル通信の事例

・Joy232
  HAKADAY.IO Print using RS232 on the joystick port of MSX computers
  https://hackaday.io/project/18552-joy232

  github - Danjovic/Joy232
  https://github.com/Danjovic/Joy232

・Akio Hiramatsu's Home Page - MSXでH8内蔵EEPROMを焼く
・FSW倉庫(通信) - アクロバット232

・JoyNet
  まとめサイト http://map.grauw.nl/resources/joynet/

まずは、一番簡単そうなJoy232を試してみました。


Joy232  Print using RS232 on the joystick port of MSX computers

01

joy232は、シリアル通信の出力のみ対応ですが、
BASICのLPRINTコマンドで出力することが出来るので、使い勝手が良いです。

早速試してみました。
ホームページの解説を参考にして、Dサブ9ピン コネクタで通信用コネクタを作りました。

Dscn9652 Dscn9653

USB-シリアル変換モジュールを使ってパソコンとの通信を試してみます。

Dscn9630

ホームページに公開されている、「STEP 1 Method 2」のBASICプログラムを、
MSX1(カシオ PV-7)で実行し、更にテスト用プログラム を実行してみました。

TeraTerm (通信速度 9600bps)にて、受信することが出来ました。

Term

MSXからの出力は、
  LPRINT "Hello,World"

みたいに、LPRINTコマンドで任意のデータを出力出来ます。

意外と簡単に出来ました。色々と遊べそうです。
Arduinoと通信を試そうと思い、
とりあえず、以前作成したLEDマトリックスを試してみました。

Dscn9658

シリアル通信でLEDマトリックスを制御できるモジュールです。
Arduino pro miniに8x8LEDマトリックスを直付けしただけです。
(LEDは定格許容範囲内の短いパルス出力では大きな電流を流せます)

Dscn9656

LPRINT "@?1234567890"
と実行すると、

Dscn9659

表示出来ました。

念のため、機種を切り替えてMSX2でも動作確認してみました。
結果は、...

動きません。MSX2が暴動しました。
調べてみると、マシン語プログラムの配置アドレスがまずいようです。
下記はプログラムの問題箇所の抜粋です。

60 EI=&HFAF5:SIZE=63
70 FOR A = EI TO EI+SIZE
80 READ B$: POKE A,VAL("&H"+B$)
90 NEXT A
100 REM
110 POKE &HFFB8,&HFA
120 POKE &HFFB7,&HF5
130 POKE &HFFB6,&HC3

LPRINTのフック(マシン語プログラム)の配置アドレス &hFAxxxx は
MSX2で新たにワーク領域と使われているようです。
基本的に &hF380H番地から&hFFFEH番地 はワーク領域なので使用禁止です。

プログラム自体はリロケータブルなようで、配置位置を&hF200 に変更したところ、
問題なく動作しました。

修正したプログラム(修正箇所のみ抜粋)

60 EI=&HF200:SIZE=63
70 FOR A = EI TO EI+SIZE
80 READ B$: POKE A,VAL("&H"+B$)
90 NEXT A
100 REM
110 POKE &HFFB8,&HF2
120 POKE &HFFB7,&H0
130 POKE &HFFB6,&HC3

Dscn9669

動いている様子



LEDマトリックスを制御しているMSX BASICプログラム
前半は1ドット単位の表示、後半はメッセージを1文字単位で
スクロール方向を変えて表示しています。

10 LPRINT "@?{}"
20 FOR Y=0 TO 7
30 FOR X=0 TO 7
40 LPRINT "@?{";CHR$(48+X);CHR$(48+Y);"1}"
50 NEXT X
60 NEXT Y
70 LPRINT "@?{}"
80 S$="Hello,Wrld.I love MSX!"
90 L=LEN(S$)
100 FOR I=1 TO L
110 R=INT(RND(1)*13)
120 LPRINT "@scrl ";R;",40"
130 LPRINT "@?";MID$(S$,I,1)
140 GOSUB 180
150 NEXT I
160 GOTO 100
170 END
180 TIME=0
190 IF TIME <20 GOTO 190
200 RETURN

上記のプログラムでは、シリアル通信の出力のみなので、
LEDマトリックスにコマンド送信した際の実行完了待ちが出来ないため
180行のサブルーチンで適当な時間待ちを行っています。

出力のみでも、十分遊べると思います。

2019年2月18日 (月)

入手したボード用 Arduino STM32用ブートローダの作成

AliexpressにてSTM32F103RCT6搭載miniボード(写真の上のボード)を
入手したのですが、Arduino STM32環境で使うためのブートローダが
用意されていないため、ソースからビルドして用意しました。

その時のまとめメモです。

ブートローダの作成はWindows 10環境にて行いました。

Dscn9600


ボードの調査


ボート別にたくさんのブートローダが用意されていますが、基本的な相違は、
  1) ボード上のLEDの制御用ポート番号
  2) 永続モード設定用のボタン用のピート番号

です。この修正版を用意すれば良いわけです。

今回入手したボードは、2つのLEDがPC0、PC1に接続、1つのボタンがPC2に接続しています。

02

ボタンは、押すとLOWになるタイプです。

03

そこで、ブートローダで利用するLEDをPC0、ボタンをPC2として利用することにします。

ブートローダの作成には、下記の情報が大変参考になりました。

ただし、参考にした情報はLinux環境でのビルドのため若干方法が異なります。

参考サイト
   ・Visuariddim - STM32Duino Bootloaderの自前ビルドとか


ブートローダのビルドに必要なものの用意

1)Arduino STM32ブートローダのソースファイル

  STM32duino-bootloader
  https://github.com/rogerclarkmelbourne/STM32duino-bootloader

上記からダウンロードまたは、gitコマンドでcloneを作成します。
ここでは、解凍したフォルダを D:\work\STM32duino-bootloader とします。

2)makeコマンド

  Cygwinのmake.exeを利用しました。
  ※Cygwinのインストール時にmakeパッケージのインストール指定が必要です。   

04

インストールしたCygwin環境のコマンドパスを調べておきます。
ここでは、C:\cygwin64\bin とします。


3)arm-none-eabi-gcc 4.8.x

  Arduino IDEの環境のものを利用しました。   

  arm-none-eabi-gccの絶対パスの調査

05

Arduino IDEの環境設定画面下の赤枠部分のパスをクリックすると、
エクスプローラーが起動します。
そこから、フォルダpackagesに下記のパスがあることを確認します。
\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\bin\

エクスプローラーのアドレスバーの絶対パスをコピペして、
D:\work\STM32duino-bootloader\ の下に
環境設定用のバッチコマンド makeenv.bat をメモ帳で作成します。

makeコマンドへのパスが通っていない場合、
一緒にmakeコマンドのパスの設定します。

makeenv.bat の中身

PATH=%PATH%;C:\Users\Owner\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\bin;C:\cygwin64\bin; 

※ アップデート等により、4.8.x以降のパス名称は異なる可能性があります。

ファイルの修正

新しいボード用のブートローダ作成にために、
D:\work\STM32duino-bootloader\にあるMakefile、config.h を修正します。

追加は面倒なので、既存のgeneric-pg15 用の定義をgeneric-pc0に変更します。

1)Makefileの修正
  メモ帳で開いて、置換機能でpg15 ⇒ pc0、PG15 ⇒ PC0に置換して保存します。

06_2

07

2)config.hの修正

メモ帳でconfig.hを開き、PG15で検索して該当する定義を参照します。

08

次に、下記の修正をします。
ターゲット
  PG15 ⇒ PC0
LED
  GPIOG ⇒ GPIOC
  15 ⇒ 0
Button
  14 ⇒ 2
  1 ⇒ 0

この修正は、LEDがPC0(1でON)、ボタンにPC2(0でON)を割り当てるためです。

09

保存してメモ帳を閉じます。


ブートローダのビルド

コマンドプロンプトを起動し、 D:\work\STM32duino-bootloader  フォルダに移動し、
作成しておいた環境設定バッチコマンドを実行します。

さらに、makeコマンドを実行します。
ターゲットは generic-pc0 を指定します。

> make generic-pc0

12

ビルド処理が実行されて、程なく genenic_boot20_pc0.bin が
D:\work\STM32duino-bootloader\bootloader_only_binaries\ に
作成されます。

13


ボードへのブートローダの書き込み

ST-Linkを使って書き込みを行いました。

Dscn9661

ボードを接続し、STM32 ST-Link Utilityにて、genenic_boot20_pc0.bin を読み込んで
書き込みを行いました。

14

ブートローダの書き込み後は、USB経由でのスケッチ書き込みです。

ボードを永続モード(スケッチ書き込み待ち状態)にて、最初のスケッチを書き込ます。
永続モードの設定は、ユーザーボタンを押したまま、リセットボタンを押します。
LEDが点滅して永続モードの状態を示します。

16

スケッチも問題なく書き込めました。

Dscn9662

スケッチ書き込み後は、COMポートも認識出来ました。

以後、このボードはArduino IDE環境でUSB経由でスケッチが書き込めます。
ブートローダのコンパイルはLinux環境の方が楽ですね。




2019年2月15日 (金)

Arduino STM32のBluePill用ブートローダについて

Arduino STM32のBlue Pill用のブートローダ、
いつの間にか、いくつか修正があるようです。私も把握していませんでした。


Blue Pill用の3種類のブートローダ
1)bootloader_only_binaries/generic_boot20_pc13.bin
2)bootloader_only_binaries/generic_boot20_pc13_fastboot.bin
3)binaries/generic_boot20_pc13.bin

1)は従来のものですが、永続モードの設定ピンがPC14から、
PB2(=BOOT1のピン、ボードの黄色いピンです)に変更されています。

ここで、永続モードとはリセット直後にスケッチ書き込みを待ち続けるモードです。
初回のスケッチ書き込み時に利用します。

2)は、リセット直後0.5秒間のスケッチ書き込み待ちを省略したバージョンのようです。
まだ試していないため、挙動は不明です。

3)は1)にLチカスケッチを結合したバージョンです。
スケッチが結合されているため、永続モードに設定して
最初のスケッチを書き込む作業が省略できます。

永続モードからみで少々考察し、まとめてみました。
もしかしたら正しくないかもしれません。

USB経由でのスケッチ書き込みについて
Arduino STM32では、
Arduino IDEからUSB経由(Upload methodにSTM32duino bootloader指定)での
スケッチの書き込みは、次の手順で行われます。

1)USBシリアルポート経由でBluePillボードをリセットさせる
2)リセット後、ブートローダが0.5秒間書き込み待ちを行い、スケッチを書き込む

02

この手順では、スケッチに組み込まれているUSBシリアル通信ドライバも必要です。
ですので、初回のスケッチ書き込みが重要となります。
スケッチが書き込まれていないと、自動でのスケッチ書き込みが出来ません。

ブートローダだけ書き込んだ際の状態は...
・ブートローダには、USBシリアル通信ドライバは組み込まれていません。
・DFUはリセット直後時のみ有効、パソコンに接続してもデバイス認識されません。
・BluePillをパソコンに接続しても、COMポートへの接続は見えません。
・BluePillにブートローダだけでは、Arduino IDEからはリセットがかけられません。


ですので、初回のスケッチ書き込みは重要です。

初回スケッチ書き込み対策
・書き込みのタイミングで、手動でリセットボタンを押す
・または、永続モードに設定してスケッチの書き込み待ちを行った上で、
  スケッチの書き込みを行い、その後、永続モードの設定を解除する。

Arduino IDEのシリアルポートの設定を行っていない場合や、
ことなるシリアルポートを設定している場合でも、リセットボタンを押す、
永続モードに設定することでスケッチの書き込みを行うことが出来ます。

また、スケッチプログラムが暴走している場合、シリアルポートを経由での
リセットが機能しない場合があります。この場合も、リセットボタンを押す、
永続モードに設定することでスケッチの書き込みを行うことが出来ます。


USB経由の書き込みはトラブルも多いので、
上手くいかない場合は、ST-LINNK経由での書き込みを推奨します。

関連記事
・FASTBOOT option has been added to the maple bootloader

・BluePill bootloader updated to use boot1 as the button

2019年2月 6日 (水)

Arduino Basicを改良してシリアルコンソール対応

Robin Edwards氏が開発し、公開している「Arduino Basic」を
シリアルコンソールで使えるように改良しました(ArduinoArduino STM32対応)。

Dscn9589

オリジナル版
・Arduino Basic

改良版
・Arduino Basic (シリアルコンソール対応版)
  https://github.com/Tamakichi/ArduinoBASIC


Arduino BASICは、Tiny BASICとは異なり、小数、文字列、多次元配列が利用出来ます。
変数名も8文字まで付けられます。かなり本格的なBASIC言語です。

オリジナル版は、OLED画面+PS/2キーボードで利用する形式なのですが、
プログラミング言語としてどれくらい使えるのかを評価するため、
プログラミング効率向上のために、シリアルコンソール利用に変更しました。

こんな感じで、TermTerm等で利用出来ます。

01

簡単なスクリーン制御(CLS、POSITIONコマンド、BSキーで文字削除)にも対応しました。
ただし、オリジナル版と同様にスクリーンエディタは未対応です。

02

改良点
  ・画面表示をOLEDからシリアルコンソールに変更
  ・PS/2キーボード利用は廃止(シリアルコンソールから入力)
  ・コマンド実行後、OKプロンプトを表示するように変更
  ・Arduino STM32 (Blue Pill対応) 、ただしLOAD、SAVE、TONEピンは未対応
  ・プログラムソースに日本語コメント追加、ソースの整形
  ・ファイル名arduino_BASIC.ino をarduinoBASIC.ino に変更
  ・プログラムの中断は[ESC]キーまたは、[CTRLC]で行う。

今後の改良を考えて、コメントに日本語訳、説明追記を行いました。

03

Blue Pillボード(STM32F103C8T6)でも、I/Oピンを使ったデジタル入出力が可能です。

Lチカプログラム

10 pc13=32
20 PINMODE pc13,1
30 PIN pc13,1
40 PAUSE 500
50 PIN pc13,0
60 PAUSE 500
70 GOTO 30

スクリーンエディタ対応は、やってみようと思います。
利用出来るコマンドについては、配布ページのドキュメントに記載しています。

追記

プログラムソースを読んでいると、このArduino BASIC
変数の管理方式があまり良くないです。
中間コード方式を採用しているのに、変数名はコード化せず、
そのまま文字列で管理しています。

マズい処理方式
・実行時に、変数テーブルに変数を変数名(文字列)で登録
・変数参照の都度、変数テーブルを単純文字列検索でなめて該当変数にアクセスする

この作りだと、変数を多用すると指数的(実際は2乗)に実行速度が落ちると思われます。
行入力時の中間コード化の時点で、変数テーブルへの登録を行い、
変数はコード化して、中間コード化したプログラムに埋め込み等の修正が必要です。

本格的に改造して利用しようと思ったのですが、
ちょっとテンション(モチベーション)下落、ちょっと微妙になってきました。

追記 2019/02/08

別途、Arduino STM32対応版をおこしました。

・Arduino Basic シリアルコンソール対応(Arduino STM32専用)
https://github.com/Tamakichi/ArduinoBASIC_STM32

変更点
  ・プログラム領域を4096バイトに増量
  ・フルスクリーンエディタ対応(全角文字 シフトJISも利用可能)
  ・LOAD [n] 、SAVE [n] でロード、セーブ対応(nは0~ 5)

コンパイルにはArduino STM32が必要です。
Blue Pillボード(STM32F103C8T6)、フラシュメモリ128kバイト利用です。




より以前の記事一覧