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

« 2014年10月 | トップページ | 2014年12月 »

2014年11月の14件の記事

2014年11月28日 (金)

Aliexpressで購入したCH340搭載USB to Serialモジュールが届いた

Aliexpressで注文していたCH340搭載のUSB - シリアル変換モジュールが届きました。
注文して6日で到着です。最近のAliexpress、上場後は若干配達が早くなった感があります。

FTDI社搭載のUSB - シリアル変換モジュールのパチモンを使うのも、あれなので
安いCH340搭載のものを試しに購入してみました。

01

送料込みで、2個で$3.57、日本円で430円くらいです。
まあ、安いですが最近の円安で円換算だと以前より30%高いです。

Dscn3281

動作確認をすると、2つのうち1つが動作しませんでした。
販売者に問題点を連絡し、交渉して今回は次回の注文時に代替品を一緒に再送して
もらうことにしました。

まあ、値段が値段だし1個だけを梱包して国際郵便で再送ってのも大変でしょう。
安い分、こういった問題も発生するでしょう。

Aliexpressの利用履歴を見ると、今までの買い物が80回、そのうち不良品ありが
今回含めて5回です。販売者のミスで注文したものが2回届いたり、1個のはずが
10個入っていたりなんかもありますね(払った金額は1個分)。
安い分、ある程度妥協が必要です。

2014年11月26日 (水)

Arduino Uno で006P(9V)電池を使って電源を確保する

秋月電子 八潮店で先週買ったプラグ付きスナップ(60円)を試してみました。

arduino Unoの外部入力電源端子は、
   外形            5.5mm
   内径            2.1mm
   中心軸電極   +(プラス)
   推奨電圧  7〜12V(互換製品によって異なる)
です。このDCプラグはこの仕様を満たしています。

2つのタイプを買ってみました。ケーブルの長さは20cmです。

Dscn3259

電池はダイソーで100円で買った006P(9V)を利用しました。

Dscn3260

こんな感じで、ケーブルの長さは調度よいです。

Dscn3263

問題なく稼働しました。

Dscn3262

006P(9V)アルカリ電池でどれくらい使えるのでしょうか?
写真の16x16 LEDマトリックスで、最大消費電流を調べてみると168.3mAでした。

測定箇所は9V電池 - DCジャック間です。
消費電力は 1.51W(= 9x168.3/1000) ですね。

< 2014/11/29 訂正
 本記事の測定値間が違っていました。
 「こんな低いはずない」と思い測定し直すとやはり間違えていました。
 テスターの設定がDCではなくてACになってました。記事と写真を修正しました。

>

 

006P(9V)アルカリ電池を携帯電話充電利用を例に調べてみると
容量は300〜500mAh位あるみたいです。

9V電池 - DCジャック間なので三端子レギュレータの変換効率は考えなくてよいので
単純に計算して
  300mAh  ÷ 168.3mA = 1.78 h

2時間弱。あまり連続稼働できないです。
(当初測定ミスで、「7時間持つスゲー」と感動したが萎えました)

電池代とスナップ代の合計は 168円でした。

番外
実験ついでに、安価な中華製DC-DCコンバータを使って単5電池で稼働させてみました。

Dscn3267

取りあえず稼働します。

Dscn3278



2014年11月24日 (月)

ATtiny13Aでウォッチドッグタイマを使ったタイマー割り込み

ATtiny13Aでウォッチドッグタイマを使った簡易的なタイマー割り込みを試してみました。
本来、ウォッチドッグタイマはハングアップを監視して復旧するために使うのですが、
一般的なタイマーとしても利用できます。

ATtiny13Aは通常のタイマー/カウンタが1つしか無く、かつ
arduino環境で使うとシステム用に使われて利用出来ません。
タイマー割り込み、PWM出力、tone()なんかは使えません。

強引に使うことも可能ですが、その場合、一部の機能が使えなくなります。
delay()、micros()などのシステム稼働時間を使っている関数は機能しなくなります。

そこでウォッチドッグタイマを使って簡易的なタイマー割り込みを実現します。
テストとして、0.5秒周期でカウントをして10回目で割り込みを停止するプログラムを
作成してみました。取りあえず動作するようです。

ダウンロード test_tinyTimer.zip (1.4K)
#define BAUD_RATE 38400
#include <BasicSerial3.h>
#include <avr/interrupt.h>

//WDT利用のための定義
#define WDT_reset() __asm__ __volatile__ ("wdr")
#define sleep()     __asm__ __volatile__ ("sleep")
#define WDT_16MS    B000000
#define WDT_32MS    B000001
#define WDT_64MS    B000010
#define WDT_125MS   B000011
#define WDT_250MS   B000100
#define WDT_500MS   B000101
#define WDT_1S      B000110
#define WDT_2S      B000111
#define WDT_4S      B100000
#define WDT_8S      B100001

// WDTタイマー開始
void WDT_start(uint8_t t) {
  cli();                             // 全割り込み禁止
  WDT_reset();                       // ウォッチドッグタイマーリセット
  WDTCR |= _BV(WDCE)|_BV(WDTIE);     // WDCE:ウォッチドッグ変更許可、WDTIE:動作種別=割り込み
  WDTCR |= t;                        // 割り込み間隔設定  
  sei();                             // 全割り込み許可
}

// WDTタイマー停止
void WDT_stop() {
  cli();                             // 全割り込み停止
  WDT_reset();                       // ウォッチドッグタイマリセット
  MCUSR &= ~_BV(WDRF);               // ウォッチドッグリセットフラグ解除
  WDTCR |= _BV(WDCE)|_BV(WDE);       // WDCEとEDEに1をセット
  WDTCR =  0;                        // ウォッチドッグ禁止
  sei();                             // 全割り込み許可
}

uint16_t count =0;

// タイマー割り込みで呼び出される関数
// 1〜10までカウントしたら停止する
ISR(WDT_vect) {
  count++;
  serOutHex(count);
  serOut("\n\r");
  if (count == 10) {
    WDT_stop();
    serOut("STOP\n\r");
  }
}

// シリアル出力整数を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 serOut(const char* str) {
   while (*str) TxByte (*str++);
}

void setup() {
  WDT_stop();           // 起動直後に念のためにWDTを停止
  serOut("START\n\r");
  WDT_start(WDT_500MS);    // ウォッチドッグタイマ 0.5秒間隔で割り込み実行
}

void loop(){
  sleep();  
}

2014/11/30 追記
Arduino UNOの場合、WDTCRはWDTCSR、WDTIEはWDIEに変更する必要があります。

実行すると、こんな感じになります。

01

シリアル出力用ライブラリは「ATtiny13Aでシリアル通信(UART)を行う」で試した
basicserial3を使っています。スケッチのサイズは636バイトでした。

割り込みの停止、割り込みの再開、カウントにリセットも出来ました。十分使えます。

ウォッチドッグタイマを使うにあたっての問題点等
 ・ウォッチドッグタイマの利用はヒューズビットの設定が必要です。
 ただし、arduino IDEのブートローダ書込み時に設定されるのでこの作業は不要です。

 ・最新のAVRマイコンの一部では、問題が発生するようです。
  ブート直後の16ms後にウォッチドッグタイマによるリセットがかかる場合があり
   ブート直後に明示的にタイマーを停止させる必要があるようです。

   電子牛乳さん「AVR がウォッチドッグタイマ発動後に再起動を繰り返す問題」
  記事で分かりやすく解説されています。
   使った感じでは、ATtiny13Aでは発生しないみたいです(たぶん)。
   該当デバイスにATtiny13はありますがATtiny13Aは無いですね。
   他のデバイスでは注意が必要です。


   

2014年11月22日 (土)

秋月電子の「お楽しみ袋」を買ってみた

久々に秋月電子 八潮店に行ってみると、「お楽しみ袋」が売っていたの買ってみました。

Dscn3245

早速開けてみると、

まあ、なんてことでしょう! 巨大なキャパシタが一杯です。

Dscn3257

これだけで、袋の2/3を占めていました。高電圧用の電解コンデンサ.. 微妙に欲しくない。

めげずにその他の部品を仕分けて見ると、使えそうなのも入ってました。

5x7 マトリックス、7セグLEDが9個、2色(3本足)LEDが100個くらい?
あと普通のLEDが沢山200個くらい?

圧電スピーカー、タクトスイッチ、これもよし

Dscn3255

小電力用のコンデンサがいっぱい、これはいいかも
その他、トランジスタ、ダイオード、赤外線リモコンセンサー等がありました。

だがゴミも..

Dscn3256

用途不明のROMやAKIPIC18のラベルの付いた古いPICマイコンが多数、
全く判別できない素子も多数ありました。

ゴミも入ってましたが、損はしてなさそうです(たぶん)。
十分、楽しめました。


2014年11月18日 (火)

ATtiny13AでI2C接続キャラクタLCDを利用する(3)

ATtiny13A用のI2C通信部コードをAVRアセンブラの勉強がてら
アセンブラに書き直してました(まだ汚いコードですが..)
動作はこの前のC言語バージョンとほぼ同じです(たぶん)。

前回、ATtiny13Aで作成した時計のスケッチのサイズは1000バイトだったのですが、
I2C接続部をアセンブラすることで884バイト(116バイトのダイエット)になりました。
初めてのAVRアセンブラですが、奇跡的にそれなりに動いているようです。

これなら、時計の時刻設定機能も追加できるかも。取りあえずソースを公開します。

ダウンロード tinyI2C.zip (2.6K)
(関数名は C言語バージョンの各関数名の頭にtinyをつけています)
解凍後、スケッチ保存用のディレクトリの\librariesに入れて利用できます。

Dscn3244

01

アセンブラの学習で参考にしたサイト
えるむ by ChaN - アセンブラ関数の書き方(avr-gcc)
AVR Wiki - avrgccでアセンブラを使う
弘前大学教育学部 AVRマイコンで学ぶ コンピュータの仕組み
AVR.jp  tiny13Aのデータシート、AVR命令セット、AVRGCCでのアセンブリとCの混合など
   (直リンク禁止のためトップページのみリンクを貼ります)

アセンブラの開発環境はarduino IDEを使っています。
ライブラリ登録した(libraries)ソースはアセンブラ(拡張子.S)もコンパイルしてくれるので
テキストエディタでコードを作成すればOKなわけです。

ヘッダーファイル

#ifndef _TINYI2C_H_
#define _TINYI2C_H_

#include <avr/io.h>
#define T100_US		((F_CPU/1000000)*100/10)
#define T200_US		((F_CPU/1000000)*200/10)
#define T1_MS		((F_CPU/1000000)*1000/10)
#define T5_MS		((F_CPU/1000000)*5000/10)
#define T10_MS		((F_CPU/1000000)*10000/10)
#define T15_MS		((F_CPU/1000000)*15000/10)
#define T20_MS		((F_CPU/1000000)*20000/10)

extern "C" {
	int16_t sum(int16_t, int16_t);
	void delay_10cyc(uint16_t);
	void blink(unsigned char);
	void tinyI2C_DATA_HI(void);
	void tinyI2C_DATA_LO(void);
	void tinyI2C_CLOCK_HI(void);
	void tinyI2C_CLOCK_LO(void);
	void tinyI2C_WriteBit(unsigned char);
	void tinyI2C_Stop(void);
	void tinyI2C_Start(void);
	void tinyI2C_Init(void);
	void tinyI2C_Write(unsigned char c);
	unsigned char tinyI2C_ReadBit(void);
	unsigned char tinyI2C_Read(unsigned char ack);
}

#define delay_100us()	delay_10cyc(T100_US)
#define delay_200us()	delay_10cyc(T200_US)
#define delay_1ms()		delay_10cyc(T1_MS)
#define delay_5ms()		delay_10cyc(T5_MS)
#define delay_10ms()	delay_10cyc(T10_MS)
#define delay_15ms()	delay_10cyc(T15_MS)
#define delay_20ms()	delay_10cyc(T20_MS)

#endif

ライブラリソース

#include <avr/io.h>

;delay用設定
#if   F_CPU == 9600000UL
 #define T100_US  96	
 #define T200_US 192
#elif F_CPU == 8000000UL
 #define T100_US  80
 #define T200_US 160
#elif F_CPU ==16000000UL
 #define T100_US 160
 #define T200_US 320
#endif

;-------------------------------------------------------;
;アセンブラ関数 void delay_10cyc(uint16_t t)
; 10サイクル x tの時間待ちを行う
; 引数  t(r25:r24)
; 本関数はr24,r25の変更を行う
; 0でも10サイクル時間待ち
; 実際の呼び出しでは rcall+ret-1 =5サイクル加算される
; 呼び出し側で引数で1引くこと
;--------------------------------------------------------;

.global delay_10cyc
.func delay_10cyc
counter = 24
delay_10cyc:
loop:			; 10サイクルのループ
	nop
	nop
	nop
	nop
	nop
	nop
	sbiw counter,1		; 1づつ減算
	brne loop		; 0でループ抜け
 	ret 
.endfunc

;-------------------------------------------------------;
;アセンブラ関数 void _delay_100us(void)
; 100usの時間待ちを行う
; 本関数はr24,r25の変更を行う
; 呼び出し時のサイクル数の補正済み(20サイクル)
;-------------------------------------------------------;

.global delay_100us
.func delay_100us
delay_100us:
	ldi  r25, 0			; delay_100us
	ldi  r24, T100_US-2
	rcall delay_10cyc
	ret
.endfunc

;-------------------------------------------------------------------;
;I/OポートのON/OFF
;void blink(uint8_t led_val)
;Lチカ 動作確認用
;-------------------------------------------------------------------;
;
#ifdef test_port
#define LED 5
#define DDR_LED 	(DDRB-0x20)
#define PORT_LED	(PORTB-0x20)
led_val = 24
.global blink
.func blink
blink:
	cpi  led_val,0
	brne reset_hi
	sbi  DDR_LED, LED
	cbi  PORT_LED,LED
	ret
reset_hi:
	sbi  DDR_LED, LED
	sbi  PORT_LED,LED
 	ret
.endfunc
#endif

;-------------------------------------------------------------------;
; tinyI2Cライブラリ
;-------------------------------------------------------------------;
;
#define I2C_DDR		(DDRB-0x20)
#define I2C_PIN		(PINB-0x20)
#define I2C_PORT	(PORTB-0x20)
#define I2C_CLK		3
#define I2C_DAT		4

;-------------------------------------------------------------------;
; 関数 void I2C_DATA_HI(void)
;-------------------------------------------------------------------;
;
.global tinyI2C_DATA_HI
.func tinyI2C_DATA_HI

tinyI2C_DATA_HI:
	cbi I2C_DDR	,I2C_DAT
	sbi I2C_PORT,I2C_DAT
	ret
.endfunc
;
;-------------------------------------------------------------------;
; 関数 void I2C_DATA_LO(void)
;-------------------------------------------------------------------;
;
.global tinyI2C_DATA_LO
.func tinyI2C_DATA_LO

tinyI2C_DATA_LO:
	sbi I2C_DDR	,I2C_DAT
	cbi I2C_PORT,I2C_DAT
	ret
.endfunc

;-------------------------------------------------------------------;
; 関数 void I2C_CLOCK_HI(void)
;-------------------------------------------------------------------;
;
.global tinyI2C_CLOCK_HI
.func tinyI2C_CLOCK_HI

tinyI2C_CLOCK_HI:
	cbi I2C_DDR	,I2C_CLK
	sbi I2C_PORT,I2C_CLK
	ret
.endfunc

;-------------------------------------------------------------------;
; 関数 void I2C_CLOCK_LO(void)
;-------------------------------------------------------------------;
;
.global tinyI2C_CLOCK_LO
.func tinyI2C_CLOCK_LO

tinyI2C_CLOCK_LO:
	sbi I2C_DDR	,I2C_CLK
	cbi I2C_PORT,I2C_CLK
	ret
.endfunc


;-------------------------------------------------------------------;
; 関数 void tinyI2C_WriteBit(uint8_t c)
; 引数 r24: 書き込みデータ
; r25:r23 内容破壊される
;-------------------------------------------------------------------;

.global tinyI2C_WriteBit
.func tinyI2C_WriteBit
value_c = 24

tinyI2C_WriteBit:
	cpi value_c, 0
	breq IC2_DATA_LO		; 0なら0出力へ
IC2_DATA_HI:
	rcall tinyI2C_DATA_HI 	; I2C_DATA_HI()
    rjmp STEP2
IC2_DATA_LO:
	rcall tinyI2C_DATA_LO 	; I2C_DATA_LO()
	
STEP2:
	rcall tinyI2C_CLOCK_HI
L1:
	sbis I2C_PIN,I2C_CLK	; I2C_CLK=1待ち
	rjmp L1	
	mov  r23, value_c
	rcall delay_100us		; delay_100us
	
	rcall tinyI2C_CLOCK_LO
	rcall delay_100us		; delay_100us

	cpi r23, 0
	breq STEP3
	rcall tinyI2C_DATA_LO
	
STEP3:	
	rcall delay_100us		; delay_100us
	ret	
.endfunc


;-------------------------------------------------------------------;
; 関数 void tinyI2C_Stop(void)
; r25:r24 内容破壊される
;
;-------------------------------------------------------------------;

.global tinyI2C_Stop
.func tinyI2C_Stop

tinyI2C_Stop:
	rcall tinyI2C_CLOCK_HI
	rcall delay_100us		; delay_100us
	rcall tinyI2C_DATA_HI
	rcall delay_100us		; delay_100us
	ret	
.endfunc

;-------------------------------------------------------------------;
; 関数 void tinyI2C_Start(void)
; r25:r24 内容破壊される
;-------------------------------------------------------------------;

.global tinyI2C_Start
.func tinyI2C_Start

tinyI2C_Start:
	in  r25,I2C_DDR
	andi r25, ~((1 << I2C_DAT) | (1 << I2C_CLK));
	out	I2C_DDR,r25
	rcall delay_100us		; delay_100us
	rcall tinyI2C_DATA_LO
	rcall delay_100us		; delay_100us
	rcall tinyI2C_CLOCK_LO
	ret	
.endfunc

;-------------------------------------------------------------------;
; 関数 void tinyI2C_Init(void)
; r25 内容破壊される
;-------------------------------------------------------------------;

.global tinyI2C_Init
.func tinyI2C_Init

tinyI2C_Init:
	in r25, I2C_PORT
	andi r25,~((1 << I2C_DAT) | (1 << I2C_CLK));
	rcall tinyI2C_CLOCK_HI
	rcall tinyI2C_DATA_HI
	ret
	
.endfunc

;-------------------------------------------------------------------;
; 関数 void tinyI2C_Write(uint8_t data)
; 引数: r24 :data
; r25:r21 内容破壊される
;-------------------------------------------------------------------;
.global tinyI2C_Write
.func tinyI2C_Write
data = 22
count= 21

tinyI2C_Write:
	mov data, r24
	ldi	count, 8
LOOP:				;8ビット書き込みループ
	lsl data
	ldi r24,0
	rol r24
	rcall tinyI2C_WriteBit
	dec count
	brne LOOP
	ret

.endfunc

;-------------------------------------------------------------------;
; 関数 uint8_t tinyI2C_ReadBit(void)
;
; 戻り値 r24: 読み取りビット
; r25,r23:r22 内容破壊される
;-------------------------------------------------------------------;
.global tinyI2C_ReadBit
.func tinyI2C_ReadBit

tinyI2C_ReadBit:
	rcall tinyI2C_DATA_HI
	rcall tinyI2C_CLOCK_HI
LOOP1:
	sbis I2C_PIN,I2C_CLK	; I2C_CLKのHI待ち
	rjmp LOOP1
	rcall delay_100us	; delay_100us
	in r22,I2C_PIN

	rcall tinyI2C_CLOCK_LO
	rcall delay_100us	; delay_100us

	bst r22,I2C_DAT		;r22のI2C_DATビットをr24の0ビットに設定
	ldi r24,0
	bld r24,0
	ret
.endfunc


;------------------------------------------------------------------;
; 関数 unsigned char tinyI2C_Read(unsigned char ack)
;
;  引数    r24: ack
;  戻り値  r24: 取得データ
;  r25:r19 内容破壊される
;------------------------------------------------------------------;

value_ack = 21	;引数用
value_res = 19	;戻り値用
count = 20	;ループ用

.global tinyI2C_Read
.func tinyI2C_Read

tinyI2C_Read:
	mov value_ack, r24	;
	ldi count,8
	ldi value_res,0
LOOP4:				;8ビット分データ取得ループ
	rcall tinyI2C_ReadBit	;r24に読み込みビットを返す
	lsl value_res		;左シフト
	add value_res,r24	;読んだビットを挿入
	dec count
	brne LOOP4
STEP4:				;value_ack が1ならtinyI2C_WriteBit(0)
	cp value_ack,0		;            0ならtinyI2C_WriteBit(1)
	breq STEP5
	ldi r24,0
	rjmp STEP6
STEP5:
	ldi r24,1
STEP6:
	rcall tinyI2C_WriteBit	; ackの送信
	mov r24, value_res
	ret
.endfunc

;--------------------------------------------------------------------;

2014年11月16日 (日)

Arduino IDE 1.0.6 では行番号が表示できりようになった

Arduino IDEは、9月にリリースされたバージョン1.0.6に切り替えて使っています。
リリースノートには、記述されていなかったのですが(たぶん)、
行番号が表示出来るようになりました。

V1006_1

環境設定の「Display line numbers」にチェックを入れると行番号が表示されます。

V1006_2

ちょっと使いやすくなったかも。

2014年11月15日 (土)

ATtiny13Aで赤外線リモコン受信センサーを使う

ATtiny13Aで赤外線リモコン受信センサの利用を試してみました。
利用したセンサーは秋月電子で購入したPL-IRM2161-XD1です。

次のサイトを参考にしてATtiny13A(arduino IDE環境)で使えるコードを書いてみました。
 参考サイト
   ・きむ茶工房ガレージハウス - 赤外線通信の実験パート2 (赤外線リモコンを送信器にして何か動かす) 
   ・garretlab  - Arduinoで遊ぶページ - 赤外線リモコンコード解析(NECフォーマット) 
   ・Renesas Electronics - FAQ No. 1007798 (NECフォーマットの赤外線リモコン・フォーマット [共通])

上記サイトでデータ構造・処理を参考にし、ATtiny13A用に軽量化するため自作しました。

自分もイメージをつかもうと、センサー出力をロジックアナライザで調べてみました。
NECフォーマットの場合、次のフォーマットをしています。

通常のデータ
01_2
ボタン長押し時のリピートデータ
02_2

赤外線リモコン受信センサはリモコンの信号を反転して受信します。
(最初これが分からずハマってしまいました)

リーダーコードの後に2バイトのカスタムコード(リモコンごとの固定値)、1バイトのデータ、
そのデータのエラーチェック用のビット反転データが続きます。
データは、ボタンごとに異なるデータとなります。

パルス幅の短い場合が"0"、長い場合が"1"と判定して"0"、"1"を得ます。
長押しするとリピートデータが送られてきます。
これで、直前のボタンが長押しされていると判断します。

このパルスのON/OFF、長さを判定してビットデータを取り出せばよいわけです。

試験用の回路はこんな感じ。
(前回のシリアル通信用回路に追加しただけですが)

03_2

ソースコード
コンパイル後のスケッチのサイズ(書込み)は884バイトでした。

2015/09/28 追記
動作確認のためのシリアル通信出力は、Nerd Ralphさんのライブラリを利用しています。
詳細については、私の過去の下記の記事を参照して下さい。
  ATtiny13Aでシリアル通信(UART)を行う
  https://nuneno.cocolog-nifty.com/blog/2014/11/attiny13aiuart-.html

#define BAUD_RATE 38400
#include <basicserial3.h>

// for I/O Port
#define IR    4
#define UART  3
#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      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ピンのみ入力設定する
}

void loop() {
  uint32_t rc =  Read_IR();  // IR受信
  if (rc) {
    if (rc != 0xFFFFFFFF) {
      serOut("custom="); serOutHex(rc>>16);serOut(" ");
      serOut("data=");serOutHex(rc>>8&0xff);serOut("\n\r");
    }
  } else {
    //serOut("Repeat\n\r");
  }
}

手持ちの赤外線リモコンを押すと、ちゃんとデータが取れます。

04_2

試した赤外線リモコンの各ボタンのデータコード

05_2

リモコンは中華製品についていたもの。
中華製付属のリモコンはカスタムコードが00FF(未定義?)の場合があるみたいで、
リモコンの識別ができないかもしれません。

色々と応用出来そうです。
とりあえずこれで、パソコンと連携して何か出来そうです。

 

Windows 8.1でPerlを使う

Windows 8.1 でPerlを利用したいと思い ActivePerlをインストールしました。
プログラミング環境として Perlを始めよう! をインストールしました。

Perlはあまり使い込んでいないのですがあると便利。早速動作確認をしてみます。

01

なぜか、日本語が文字化けします。
デフォルトのUTF-8形式ではなくシフトJISで保存し直して試すとちゃんと表示できました。

02

03

うーん、どういうことだろう
直接コマンドプロプト上で実行して確認してみます。

04

やはり同じ現象が発生。

調べてみると、「Perl:日本語対応」に答えがありました。
どうも、Windows上ではシフトJISを使う分には文字化けは発生しないようです。
シフトJISがデフォルト?

UTF-8を使うには明示的にエンコードの指定が必要となるようです。

05

今度はちゃんと動作しました。保存時のコード指定、Linux上で作成したPerlプログラムを
Windowsで動かす際はちょっと注意が必要ですね。

エディタのPerlを始めよう!はシンプルで使いやすいです。開発者に感謝!!

追記 2014/11/16
パッケージを追加しようと、付属のppmコマンド実行すると動きません。
どうも、ユーザーディレクトリにマルチバイト文字を使っているとダメっぽいです。
ppm用のディレクトをDドライブに作成(D:\perl\ppm)して、
cmd画面で、SET ACTIVEPERL_PPM_HOME=D:\Perl\ppm
としてからppmコマンドを実行すると起動出来ました。

参考にしたサイト男たちの群青 ActivePerl の ppm が起動しない

シリアル通信パッケージを入れようとしたけど、Active Perlの64ビット版だと
Win32-SerialPortが利用出来ないと判明。32ビット版に変更した方が良さそうみたい。

 

2014年11月13日 (木)

AVRのアセンブラプログラミングを勉強しています

最近ATtiny13Aが意外と使えそうと思い、本格的に使い込もうとAVRのアセンブラの
調査を始めました。

メインはC言語で、一部の関数は必要に応じてアセンブラで実装しようと思います。

アセンブラ プログラミングはZ80x86などで経験があります。

AVRの命令一覧を見て、「なんて、使いやすいのだろう!」が最初の感想です。

ますレジスタが32個と多く、レジスタで直接演算できるのが素晴らしい。
レジスタが多いと、PUSH、POPでいちいち退避する回数は減るし、
いちいち、演算専用レジスタを介して演算を行うなど不要です。

C言語用の関数を作成する場合、RAMの利用無しにほとんどの変数をレジスタに割り当てて
実装出来るのではないでしょうか。C言語との相性はかなり良さそうです。てかC言語用に
設計されています。

おさえどころは、他のアセンブラと同じで
・レジスタの種類
・レジスタへの値設定
・アドレシング
・演算命令
・演算結果(フラグレジスタ)による分岐
・I/O処理
・割り込み処理
ですかね。

ますは、
1)開発環境
2)C言語から呼び出す手続き(インタフェース)
3)デバック環境
をおさえなければなりませんが、1)、2)はだいたい分かりました。

手始めに、I2CのC言語関数をアセンブラに置き換えて見ようと思います。

2014年11月12日 (水)

ATtiny13Aでシリアル通信(UART)を行う

Attiny13Aでシリアル通信をしてパソコンとの連携をしたい今日この頃、
探しに探してやっと見つけ実現出来ました。

Nerd Ralphさん「AVR half-duplex software UART supporting single pin operation」
ATtinyで利用できるソフトウェアUARTを公開しています。

早速、ATtiny13Aで試してみました。ソースコードは上記HPからダウンロードできます。
かなり良いです。Nerd Ralphさんに感謝!! です。

03_2

概要
これは何?
シリアル通信(UART)をビットバンディング(エミュレーション)で実装したソフトです。
半二重通信でI/O用に1ピンのみ利用、消費フラッシュメモリはわずか62バイトです。
バッファリングは行っていないのでSRAMの消費は無しです。
16Mhzだと460.8kbpsの速度まで対応できるそうです(デフォルトは115.2kbps)。

送信・受信を同時に行うことはないのでこれで半二重通信も問題なしですね。

回路作成
1ピンで入出力に使う場合、ダイオード、トランジスタでTxとRxを分離する回路が必要です。
TxとRxを別ピンに割り当てればこれは不要です(ただし、ソース内のdefine文を修正)。

8ピンATtiny13A的には1ピンだけで済ませたいので、回路も作成しました。
特に部品説明はなかったので、トランジスタとダイオードは手持ちのありふれた
2SC18151N4148を利用しました。

04
実際はこんな感じ。

     Dscn3234


シリアル通信用にはPB3(D3)を割り当てました。

ライブラリのインストール
ダウンロードしたファイルを解凍しBasicSerial3フォルダをlibrariesフォルダに入れます。

ライブラリソースの修正
利用ピンがPB3(D3)なので、BasicSerial3.SのUART_Tx、UART_Rxの定義を修正します。
 #define UART_Tx   3
 #define UART_Rx   3

さらに、通信速度が115200に固定されているので、
  //#define  BAUD_RATE   115200
  #if  !defined(BAUD_RATE)
  #define  BAUD_RATE   115200
  #endif

こんな感じに修正して、スケッチ(ソースコード)作成時にも設定できるようにしました。
動作確認のスケッチを作成して動かしてみます。

ATtiny13Aの9.6MHzだと57600bps,115200bpsではタイミング的に
微妙にエラーが発生します。
通信速度は38400bpsにて利用しました。

#define BAUD_RATE 38400
#include <BasicSerial3.h>

// sketch to test Serial

void setup() {

}

void serOut(const char* str) {
   while (*str) TxByte (*str++);
}

void loop(){
  byte c;
  c = RxByte();
  switch(c) {
    case '1': 
      for (uint8_t i=0;i<10;i++) serOut("埼玉");
      serOut("\n\r");
      break;
    default:
      TxByte(c);
  }
}

プログラムサイズは426バイトでした。標準のSerialと比べると小さいですね。
TeraTermで確認すると、双方向の通信が出来ました。
1を押すと"埼玉"を10個表示します。他はそのまま文字を表示します。

01

十分使えますね。通信速度 38400bps なら十分な速度です。

考察
念のため、ロジックアナライザで通信データを見てみました。
実は57600bps,115200bpsでもそれなりに通信できるのですが、微妙にエラーがでました。
微妙にフレームエラー発生です。パルス幅が規定どおり出てないみたいです。

05

38400bpsの場合はかなり良好です。

06

38400bpsの場合、1ビット当たり26.04マイクロ秒の時間幅なのですが、
生成している波形幅は25.5、26.0マイクロ秒で2%程度のずれでおさまっているようです。

検証時に使った、必要パルス幅とディレイに必要なサイクル数のメモ

検証用データ 通信速度と1ビット幅・必要ディレイサイクル数
※サイクル数換算は ATTiny13A 9.6MHzの場合

07
(57600,115200bpsのタイミングを合わせようとソースのTXDELAYを調整したがだめでした)

実際に、記事のコメント&感想でもATtiny13では38400bpsを使うと良いみないな
投稿がありました。

ということで、 38400bps なら十分利用できます。
このUARTライブラリはかなりの戦力として使えそうです。

ちなみに、2線でで利用する場合は
BasicSerial3.SのUART_Tx、UART_Rxに別ポートを割り当てればよいです。
 #define UART_Tx   3
 #define UART_Rx   4

この場合は、トランジスタ、ダイオード、抵抗は不要でピンに直接接続で利用出来ます。

今回の調査で参考にしたサイト
  ・福福電子工房   「RS-232Cとは?」 - 通信書式
  ・たろの部屋 月刊ソフト作り! 「通信ソフトを作る!(その1)」
  ・秋月電子 スイッチング・ダイオード 1N4148トランジスタ2SC1815GR

2014年11月 9日 (日)

ATtiny13AでI2C接続キャラクタLCDを利用する(2)

前回の続きです。

手持ちのI2C接続リアルタイムクロックモジュールを接続して時計を作成しました。

Dscn3229

接続はこんな感じです。

01

I2C接続リアルタイムクロックモジュール上にI2Cバス用のプルアップ抵抗が
乗っているので抵抗は不要となります。

I2C接続リアルタイムクロックモジュールは、以前Aliexpressで購入したものです。

03

送料無料で1個 120円位で買えます。

プログラムサイズは1000バイトと、容量1024バイトぎりぎりです。
時刻設定機能の実装は無理なので、実用としては使えませんねぇ。

それでもATtiny13Aでここまで出来るとは思いませんでした。
今後も電子工作でATtiny13Aを積極的に使っていきたいです。

02

全ソース(スケッチ)はこちらに置いておきます。
DS1307用のソースは公開されているライブラリを改造して作成しました。
どこで入手したのか不明で、入手先を明記できません。すみませんです。

ATtiny13AのI2Cスレーブとして利用するプログラムも作成中です。
次はArduino UnoとたくさんのATtiny13Aを接続して遊んでみようと思います。

2014年11月 5日 (水)

ATtiny13AでI2C接続キャラクタLCDを利用する

以前から試行錯誤していたのですが、やっとArduino IDE環境下のATtiny13Aで
I2Cが使えるようになりました。

取りあえず、キャラクタLCDに文字が表示できました。

Dscn3222

まあ、自作というよりはRaulさんのHPで公開しているソースをちょっと修正しただけですが..
内容を理解してやっと使えるようになりました。

参考文献

   Coding Laboratory - I2C on an AVR using bit banging

当然、ATtiny13AにはI2Cをサポートしていないのでビットバンディング(エミュレーション)です。
機器によっては動作しない場合もあるでしょう。

開発環境は、以前構築したArduino IDE+ATtiny対応(こちら)です。I
I2C接続LCDモジュールの制御はこちらの成果を利用しています。
ATtiny13Aの書き込みはこちらの成果(USBasp)を利用しています。

01

プログラムのサイズは872バイトです。
プログラマ接続で4ピンを使っているので余っている3番ピン、4番ピンを
I2C接続用に利用してLCDを制御しています。

Dscn3219

通信速度はちょっと遅い感じです。
ロジックアナライザで調べると1.6Kbps程度しかでていません。

これでもdelay時間をいじってオリジナルよりは速くなってます。
その為、他のCPUで利用する場合はタイミングの調整が必要かもしれません。
ちなみに、arduinoのI2C用ライブラリWireを使う場合、転送速度は100kbpsだそうです。

全ソース(スケッチ)はこちらに置いておきます。

以下、主要部を掲載します。

I2C通信部のソース
#include <avr/io.h>
#include <util/delay.h>

// Port for the I2C
#define I2C_DDR 	DDRB
#define I2C_PIN 	PINB
#define I2C_PORT 	PORTB

// Pins to be used in the bit banging
#define I2C_CLK 3
#define I2C_DAT 4

#define I2C_DATA_HI()   I2C_DDR &= ~(1 << I2C_DAT);I2C_PORT |= (1 << I2C_DAT);
#define I2C_DATA_LO()   I2C_DDR |= (1 << I2C_DAT);I2C_PORT &= ~(1 << I2C_DAT);
#define I2C_CLOCK_HI()  I2C_DDR &= ~(1 << I2C_CLK);I2C_PORT |= (1 << I2C_CLK);
#define I2C_CLOCK_LO()  I2C_DDR |= (1 << I2C_CLK);I2C_PORT &= ~(1 << I2C_CLK);

void I2C_WriteBit(unsigned char c) {
    if (c > 0) {
        I2C_DATA_HI();
    } else {
        I2C_DATA_LO();
    }
    I2C_CLOCK_HI();
    while ((I2C_PIN & (1 << I2C_CLK)) == 0);
    _delay_us(200);
    I2C_CLOCK_LO();
    _delay_us(200);        
    if (c > 0) {
        I2C_DATA_LO();
    }
    _delay_us(200);    
}

unsigned char I2C_ReadBit() {
    I2C_DATA_HI();
    I2C_CLOCK_HI();
    while ((I2C_PIN & (1 << I2C_CLK)) == 0);
    _delay_us(200);   
    unsigned char c = I2C_PIN;
    I2C_CLOCK_LO();
    _delay_us(200); 
    return (c >> I2C_DAT) & 1;
}

// Inits bitbanging port, must be called before using the functions below
//
void I2C_Init() {
    I2C_PORT &= ~((1 << I2C_DAT) | (1 << I2C_CLK));
    I2C_CLOCK_HI();
    I2C_DATA_HI();
}

// Send a START Condition
//
void I2C_Start() {
    // set both to high at the same time
    I2C_DDR &= ~((1 << I2C_DAT) | (1 << I2C_CLK));
    _delay_us(100); 
    I2C_DATA_LO();
    _delay_us(100);   
    I2C_CLOCK_LO();
    _delay_us(100);   
}

// Send a STOP Condition
//
void I2C_Stop(){
    I2C_CLOCK_HI();
    _delay_us(100);   
    I2C_DATA_HI();
    _delay_us(100);   
}

// write a byte to the I2C slave device
//
void I2C_Write(unsigned char c) {
    for (char i = 0; i < 8; i++){
        I2C_WriteBit(c & 0x80);
        c <<= 1;
    }
}

// read a byte from the I2C slave device
//
unsigned char I2C_Read(unsigned char ack) {
    unsigned char res = 0;
    for (char i = 0; i < 8; i++) {
        res <<= 1;
        res |= I2C_ReadBit();
    }
    if (ack > 0) {
      I2C_WriteBit(0);
    } else {
      I2C_WriteBit(1);
    }
    return res;
}

LCD制御部のソース

#include "IC2LCD.h"

uint8_t DisplayMode;
uint8_t DisplayControl;

// コマンド送信
void Lcd_writeCmd(uint8_t cmd) {
	I2C_Start();
	I2C_Write(0xa0);
	I2C_ReadBit();
	I2C_Write(0x00);
	I2C_ReadBit();
	I2C_Write(cmd);
	I2C_ReadBit();
	I2C_Stop();
}

// データ送信
void WriteData(uint8_t data) { 
	I2C_Start();
	I2C_Write(0xa0);
	I2C_ReadBit();
	I2C_Write(0x80);
	I2C_ReadBit();
	I2C_Write(data);
	I2C_ReadBit();
	I2C_Stop();
} 

// LCD初期化
void LCD_init() {
	_delay_ms(15);
	Lcd_writeCmd(0x01);
	_delay_ms(5);
	Lcd_writeCmd(0x38);
	_delay_ms(5);
	Lcd_writeCmd(0x0f);
	_delay_ms(5);
	Lcd_writeCmd(0x06);
	_delay_ms(5); 
	
	DisplayControl = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
	DisplayMode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
}

// カーソル移動
void LCD_setCursor(uint8_t col, uint8_t row){
  uint8_t row_offsets[] = { 0x00, 0x40 };
  if ( row >= NUM_LINES ) {
    row = NUM_LINES - 1;
  }
  Lcd_writeCmd(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}

// 非表示設定
void LCD_noDisplay() {
  DisplayControl &= ~LCD_DISPLAYON;
  Lcd_writeCmd(LCD_DISPLAYCONTROL | DisplayControl);
}

// 表示設定
void LCD_display() {
  DisplayControl |= LCD_DISPLAYON;
  Lcd_writeCmd(LCD_DISPLAYCONTROL | DisplayControl);
}

// カーソル非表示
void LCD_noCursor() {
  DisplayControl &= ~LCD_CURSORON;
  Lcd_writeCmd(LCD_DISPLAYCONTROL | DisplayControl);
}

// カーソル表示
void LCD_cursor() {
  DisplayControl |= LCD_CURSORON;
  Lcd_writeCmd(LCD_DISPLAYCONTROL | DisplayControl);
}

// カーソルブリンクなし
void LCD_noBlink() {
  DisplayControl &= ~LCD_BLINKON;
  Lcd_writeCmd(LCD_DISPLAYCONTROL | DisplayControl);
}

// カーソルブリンク
void LCD_blink() {
  DisplayControl |= LCD_BLINKON;
  Lcd_writeCmd(LCD_DISPLAYCONTROL | DisplayControl);
}

// 文字列表示
void LCD_string(char *str) {
  for(uint8_t i = 0; i < 16; i++) {
    if(str[i] == 0x00) {
      break;
    } else {
      WriteData(str[i]);
    }
  }
}

LCDモジュールの制御のほとんどは、コマンド送信とデータ送信を行う関数
void Lcd_writeCmd(uint8_t cmd);
void WriteData(uint8_t data);

で行っています。
LCDモジュールの資料を見ると、I2C Intaface protocolは次のようになってます。

02

このプロトコルに従ってコマンド送信は、
  // コマンド送信
  void Lcd_writeCmd(uint8_t cmd) {
    I2C_Start();
    I2C_Write(0xa0);
    I2C_ReadBit();
    I2C_Write(0x00);
    I2C_ReadBit();
    I2C_Write(cmd);
    I2C_ReadBit();
    I2C_Stop();
  }

こんな感じになっています。図の各部の対応において、先頭かた順番に
    Sが I2C_Start()、
    SLAVE ADDRESS が I2C_Write(0xa0)、
    Acknowledgement from Icmが I2C_ReadBit()、
    RS+CONTROL BYTEが I2C_Write(0x00)、
    Acknowledgement from Icmが I2C_ReadBit()、
    COMMAND OR DATA BYTEが I2C_Write(cmd)、
    Acknowledgement from Icmが I2C_ReadBit()、
    Pが I2C_Stop()
を処理しています。

ATtiny13AでI2Cが使えると、いろいろを応用できそうです。
ただ、LCD接続ではプログラム領域 1024バイトのうち既に872バイトを消費しており、
後は何もできそうにないです。あと1024バイト欲しいところです。

2014年11月 4日 (火)

Windows 8.1 で署名なしドライバーソフトをインストールする

Windows 8.1で署名なしドライバをインストールする手順のまとめです。
個人的に、何回もその都度手順を調べていたのでまとめました。

ここではAVRマイコンプログラマ USBasp用ドライバソフトのインストールを例に記述します。

Windows 8.1では一時的に「ドライバ署名の強制を無効にする」モードがあります。
ここでは、このモードに移行するための手順をまとめます。

操作手順
 1)チャームを表示
     [設定] ->[PC設定の変更] ->[保守と管理]->[回復]->[今すぐ再起動する]ボタンをクリック 01

   (画像をクリックすると拡大表示します)

   これで一旦再起動します。

   2)オプションの選択画面
      再起動すると次の画面が表示されるので「トラベルシューティング」を選択します。 

  02

 3)トラベルシューティング画面
     「詳細オプションを選択」します。

  03

 4)詳細オプション画面
     「スタートアップ設定」を選択します。

    04

  5)スタートアップ設定(確認)画面
    [再起動]ボタンを押して再起動します。

    05 

   6)スタートアップ設定(選択)画面
     再起動するとメニューが表示されます。ここでは7番の
     「ドライバー署名の強制を無効にする」を選択するためにキーボード7を押します。

    06   

    07

    選択すると、デスクトップ環境が立ち上がります。
   これで、署名なしのドライバソフトのインストールが可能な状態になります。
    この状態は再起動するまで有効です。

7)署名なしドライバーソフトのインストール(例)
    USBasp用ドライバソフト(usbasp-windriver.2011-05-28.zip)のインストール例です。
    インストールを試みと、次のような警告が表示されます。

   08
   
  ここでは「このドライバーソフトウェアをインストールします」を選択します。
  これでインストールができます。完了すると次の画面が表示されます。

  09

  稀に次のような画面が表示される場合があるようですが、正常にインストールできました。

  10

  追記 2014/11/05
  どうも、上の画面が出るとダメみたいです。再起動するドライバが使えなくなりました。

  デバイスマネージャーで確認するとちゃんとインストール出来ています。

11

 



 

   
   

2014年11月 3日 (月)

CH341A programmerを試してみました

arduinoで大容量のSPI接続のフラッシュメモリ W25Q64を使っています。

このメモリ、8MバイトのサイズでSPI接続なので以前使っていたI2C接続のEEPROMよりも高速です。
データの書き込みにはLinuxマシン+arduino構成の「Serprog/Arduino flasher」を使って
いました。

頻繁に使うので専用シールドを作ろうと部品をチョイスしていると
CH341A programmerを発見。これを購入した方が安上がりと分かり注文しました。

06

この製品は、I2C、SPIインタフェースのフラッシュメモリ・EEPROMのプログラマーです。
Windows機でUSB接続にて利用できます。
私が使っているwinbond社のW25Q64を含め24/25シリーズのメモリに対応しています。

んで、到着したのがこれです。

Dscn3209

本製品、いつもの中華クオリティで、マニュアルなしです。
ジャンパーにてSPI通信/3線シリアル通信(基板上の3端子)の切り替えが可能なようです。

取りあえずwindows 8.1機に指して見ましたが、要ドライバで認識できませんでした。

色々探して、aitendoで類似の製品があったのでそのドライバ&ソフトを使いました。
(aitendoの製品はSPI端子があるので基板上のICにも書き込みできて良さげです)

< 2016/04/18, 4/21 追記
  現時点でaitendoのHPではドライバ&ソフトを配布を停止しているようです。
 ウィルスが検出されたとのことです。私の手持ちファイルではウィルスは検出されませんでした。
 ツール画面のタイトル文字列もちょっと違うようなので私の入手時と配布ファイルが異なるのかもしれません。

 追記: ソフト開発者のHPによるとウィルス検出は誤検出のようです。
 とりあえず、別のドライバ&ソフトのリンク(動作は保障しません)
   CH341A programmer software+driver
   CH341A 编程器 ツールソフト 開発者のHPと思わる(中国語)

 こちらのサイトも参考になると思います。サポート・調査・動作確認もしっかりとされている
 ようなので(簡易マニュアル付き)、購入もこちらのサイトが無難かと思います。
   
ショップのふうせんUSBプログラマ
 (リンク切れ 2025/01/06 確認)

Windows 8.1対応の表記はありませんが、Windows8.1でも問題なく利用できました。
ドライバのインストールは、手動でINFファイルを使って行うと署名なしインストール
モードにしなくてもインストールできました。

W25Q64を載せて、専用のツールを起動させます。

Dscn3210

ツールのDetectボタンを押すと、W25Q64を自動認識してくれました。

01

以前作成した漢字フォントイメージを読み込んで、書き込んでみます。

02

LanguageをEnglishにしたのになぜか、部分的に中国語(簡体字)です。
イメージファイルを読み込み後、Autoボタンを押すと書き込みが開始されました。

04

8Mバイトの書き込みは(消去→書込→ベリファイ)4分で終了しました。
一応、Readボタンを押して読み込みも行ってみます。

05

だいたい1分で読み込み完了です。
問題なく利用できました。
Serprog/Arduino flasher」よりもお手軽で使いやすいですね。

2018/08/09 追記
下記のサイトにまとめのような情報があります。
  ・Documents and Software Related to the famous CH341a used in I2C/SPI Flash
    Programmers also called as Bios Programmers
    https://github.com/boseji/CH341-Store

上記の内容は、下記のページを元にまとめているようです。
  ・CH341A Mini Programmer Schematic and Drivers
   https://www.onetransistor.eu/2017/08/ch341a-mini-programmer-schematic.html
   - CH341A I2C Programming (Windows API)
      https://www.onetransistor.eu/2017/09/ch341a-usb-i2c-programming.html
   - CH341A SPI Programming (Windows API)
      https://www.onetransistor.eu/2017/12/ch341a-usb-spi-programming.html

関連記事:
  arduinoで利用可能な漢字フォントROMの製作
  arduinoで利用可能な漢字フォントROMの製作(2)
  ArduinoでSPIシリアルフラッシュメモリW25Q64を使ってみる(1)
 CH341A programmer用ツール「AsProgrammer」を試してみました

« 2014年10月 | トップページ | 2014年12月 »