E 電子おもちゃ 〜ワイヤレス給電LED
by fjk
給電ユニット(秋月電子#114405、400円)により、電磁誘導方式でワイヤレスLED(秋月電子#117031など、5個入りで240円程度)に無接点で給電を行い、LEDを点灯させることができる。
給電ユニットの仕様は、
- 動作電圧 : DC5〜9V、
- 出力電流 : 500mA(DC9V時)、
- 駆動周波数: 60kHz、
- 誘導距離 : 10mm(9V時)
駆動電源として、スイッチ付きCR2032x2ボタン電池ホルダー(秋月電子#112666、150円)と、給電ユニットのケースとして百均のプラケース(66x62x21mm、2個セット)、PH-2Pコネクタポスト(秋月電子#117259、70円)を揃えた。
なお、給電ユニットは両面テープで1.2mm厚のプラ板(大きさ57mm角)に固定し、プラ板の下に5mm高の樹脂スペーサを両面テープで4隅に取り付けた。
単にLEDを点灯させるだけのオモチャだが、LEDユニットは見た目には見分けにくそうなので、給電ユニットにLEDを置いて、「同じ色のものがあればゲットできる」というルールでゲームができそう。
給電ユニットとワイヤレスLED |
スイッチ付きボタン電池ホルダー |
百均のプラケース |
ワイヤレスLEDの点灯テスト |
P PICミニBBシリーズ(4) 〜I2C接続ロータリーエンコーダー
by fjk
ロータリーエンコーダー(RE)は24クリックタイプ(秋月電子 106357、100円)で、さらにロータリーエンコーダDIP化基板(秋月電子 107241、60円)を用いた。
RE出力をそのままメインPIC(PIC-BASE14)の入力としても良いが、汎用入力ユニットとしたいので、I2C接続スレーブPICでデータを処理後、メインPICにI2CでREデータを送ることにした。I2CマスターPICはPIC16F1825、RE用I2CスレーブPICはPIC12F1840とし、RE用ブレッドボードはabc893で作成(配線)したアナログ入力ユニットを用いた。
さらに、アナログ入力ユニット上の可変抵抗器の電圧(AD)もPIC12F1840で取得し、I2Cマスターからの指示により、AD(mode=0)かRE(mode=1)のどちらのデータをI2C送信するか選択できるようにした。modeの指示はUSB接続パソコン端末から、'0'または'1'を入力。modeを変更(再指定)するとREのカウンタは0にクリアされる。
I2C接続RE/ADボード回路図 |
RE/ADボードの配線 |
RE/AD動作中(REは灰色つまみ) |
また、PIC12F1840へのプログラムの書込みにはabc824で作成した「PIC書込みアダプタ」を使用した。
PIC12F1840(ROM:4Kbyte)の使用メモリは17%(0.7Kbyte)以下なので、代わりにPIC12F1822やPIC16F18313(ROM:2Kbyte)などが使えそう。
PIC12F1840書込み中 |
PIC12F1840の使用メモリ状態 |
パソコン端末(テラターム)画面例 |
なお、slaveI2CのPIC12F1840のMCC設定は以下のとおり。
RE/ADボード(PIC12F1840)のsystem Module
Pin Module |
MSSP
ADC |
プログラムには、abc893で紹介した "i2cLCD_ST7032i.c/h"および"my_stdlib.c/h"が必要。
- 【プログラム】 abc894-1825.c(zip)
(PIC16F1825のMCC設定などはabc893参照) (BFSIZEはeusart.hで宣言、 abc889を参照)
/*********************** (abc894-1825.c)**************
* I2C_RE・ADC入力 (mode=0:ADC、mode=1:RE)
*****************************************************/
#include "mcc_generated_files/mcc.h"
#include "stdio.h"
#include "i2cLCD_ST7032i.h"
#include "my_stdlib.h"
#define SLVADR 0x42
/* ----- Variables ----- */
char sBuf[BFSIZE]; // 文字列作業エリア
char rBuf[BFSIZE]; // シリアル受信バッファ
uint8_t sFlg; // シリアル受信フラグ
/*---- disp mode -----------*/
void dsp_md(uint8_t md){
LCD_cursor(3,0);
if(md){
puts("\n> RE Mode\r");
LCD_str("RE Mode");
IO_RA4_SetLow();
}else{
puts("\n> AD Mode\r");
LCD_str("AD Mode");
IO_RA4_SetHigh();
}
}
/*------ main application ----*/
void main(void)
{
static uint16_t rDat = 0;
static uint8_t mode = 0;
SYSTEM_Initialize();
LCD_init(); // LCD初期化
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
LCD_str("= ready");
dsp_md(mode);
while (1)
{
if(sFlg){ // USB受信データがあれば
LCD_clr();
LCD_str(rBuf);
if(rBuf[0] % 2) // bit0のみで判断
mode = 1;
else
mode = 0;
dsp_md(mode); // モード変更表示
//--- スレーブへ送信
I2C_Write1ByteRegister(SLVADR, 0, mode);
sFlg = 0;
}
//--- スレーブから受信
I2C_ReadNBytes(SLVADR, (uint8_t *)&rDat, 2);
if(mode){ // REモードなら
if(rDat & 0x8000){ // 負数か?
rDat = ~rDat + 1; // 負数処理
sBuf[0] = '-';
my_itoa(sBuf+1,rDat);
}else{
my_itoa(sBuf, rDat);
}
}else{ // ADモード
my_itoa(sBuf, rDat);
}
LCD_cursor(0,1);
LCD_str(" ");
LCD_cursor(0,1);
LCD_str(sBuf);
puts(sBuf);
putch('\r');
__delay_ms(500);
}
}
|
- 【I2Cスレーブ(RE/AD)】 abc894-1840.c(zip)
/*********************(abc894-1840.c)***********
* アナログ&REデータ送信(I2Cスレーブ)
* Slave Address = 0x42 (66)
***********************************************/
#include "mcc_generated_files/mcc.h"
uint8_t wState; // I2C書込みステート番号
uint8_t rState; // I2C読込ステート番号
uint16_t sDat; // I2C送信16ビットデータ
uint8_t reg; // レジスタ番号(未使用)
uint8_t mode = 0; // 1:RE / 0:ADC
int16_t count = 0;
/***** I2C Read Callback ****************/
void I2C_ReadProcess(void) {
switch (rState) { // ステートで進む
case 0:
reg = I2C_Read();
rState++; // 1byte目読込、次へ
break;
case 1:
mode = I2C_Read();
rState = 0; // 2byte目読込、最初に
count = 0; // countデータクリア
break;
default:
break;
}
}
/***** I2C Write Callback *****************/
void I2C_WriteProcess(void) {
switch (wState) {
case 0:
I2C_Write((uint8_t)sDat);
wState++; // sDatの下位送信、次へ
break;
case 1:
I2C_Write((uint8_t)(sDat >> 8));
wState++; // sDatの上位送信、次へ
break;
case 2: // 送信完了
wState = 0; // 最初に戻る
break;
default:
break;
}
}
/*------ main application ----*/
void main(void)
{
uint16_t aDat;
SYSTEM_Initialize();
I2C_Open();
I2C_SlaveSetReadIntHandler(I2C_ReadProcess);
I2C_SlaveSetWriteIntHandler(I2C_WriteProcess);
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
while (1)
{
if(mode){
if(IO_RA4_GetValue() == 0){
__delay_ms(5);
if(IO_RA5_GetValue()) count--;
else count++;
while(IO_RA4_GetValue() == 0);
__delay_ms(5);
}
sDat = (uint16_t)count;
}else{
sDat = ADC_GetConversion(AN0);
__delay_ms(100);
}
}
}
|
※ 本レポートの参考・利用は、あくまでも自己責任でお願いします。