トップ  »  鉄道模型  »  運転・コントロール機器  »  ArduinoでPWMパワーパックを作ってみた

ArduinoでPWMパワーパックを作ってみた

Pick Up Photo

写真:ArduinoでPWMパワーパックを作ってみた

Author

しろくま
投稿者: しろくま
公開日: 2011年5月 3日
この記事の評価 4.5 stars
星の数の平均 4.5 (16人が評価)
総合ポイント 68.4 Pts.

Tags

Main Article

ArduinoでPWMパワーパックを作ってみましたノッチ式で自動加減速、常点灯機能付きです VVVF音もします

More Info

Detail

これは以前作った加減速付きパワーパック
よくあるコンデンサーを利用したものです
滑らかな加速と減速、惰行で徐々に速度が落ちるという優れたものです
ただ、加速と減速が1段階ずつしかなく、抵抗を利用して多段階のものを作ったりしましたが、停止から走り出すまで時間がかかる等不満が残るものでした。

traintrainのPWMコントローラーコンテストでPWMコントローラーを知り挑戦しようと思ったが、電子工作は全くの素人のため断念。
武蔵野電波のブレッドボーダーズでマイコンで簡単にPWMを出力できることを知る。
ArduinoとパワーMOSFETと数点の部品を組み合わせて、下記のような数行のプログラムでPWMコントローラーの完成

int outPin = 9; // 出力はピン9に接続
int analogPin = 3; // アナログピン3に可変抵抗
int val = 0;

void setup() {
}

void loop() {
val = analogRead(analogPin);
// 得たアナログ値を1/4して、0-1023の値を0-255に変換
analogWrite(outPin, val / 4);

}

プログラムも初心者だがこれならなんとかなりそうと、ブレッドボードで実験を繰り返し、機能を追加していく。
ArduinoのPWMをそのまま使用するとピーとモーターが鳴きます。約490Hzぐらい。
YouTubeで鉄道模型からVVVF音を出している動画を見つけ、これに挑戦。
tone()関数で希望の周波数を設定可能だが、duty比は50%固定。そこからマイコン - AVRの機能を調べていった
そして開発にエクセル(表計算)は必須
当然ArduinoからPCにデータを送信してチェックするが全部送るわけにもいかない
数値を1つずつ動かして、思った通りの値になるか検証するにはエクセルに限る

PWMパワーパックの部品配置図
ArduinoにパワーMOSFET
入力に可変抵抗、ロータリースイッチ
表示用に7セグをつけたもの

配線しケースに組み込んだもの
試作品ではロータリースイッチからの入力をダイオードで4bitに変換していたが、配線がすごいことに・・・(これだけで配線12本とダイオードが22個)
抵抗で電圧に変換する方式に変更したが、ロータリースイッチを中途半端な位置にすると2つの接点に導通し思いもよらない操作に 中途半端な数値を排除することでようやく完成

写真左上が電源スイッチ
左下が加減速の早い遅いを調節するダイヤル
その隣が常点灯調整ダイヤル 走り出すところまで回し少し戻す
右の大きいダイヤルがマスコン
右上が方向切り替えスイッチ
そして真ん中がノッチ表示の7セグ

回路図
ソースは以下 もし容量とかの関係で表示されない場合は参考ページを見てください

/*
WEB上で表示されるように"<"と">"を全角に変換しております。
テキストエディタで半角の括弧に置換するか、リンク先からダウンロードして下さい。

商用利用不可。オークションも含む。必ずご一報下さい。
Arduino用パワーパック ロータリースイッチ抵抗版
*/

#include <avr/io.h>

#define MASCON masconvol( analogRead( 3 ) + 42) // ロータリースイッチ 1~12
#define PWM2A 11 // OCR2A出力はpin11に接続
#define PWM2B 3 // OCR2B出力はpin 3に接続
#define PWM1B 10 // OCR1B出力はpin10に接続
#define PINLIGHT 4 // アナログピン4に常点灯ダイアル
#define PINKASOKU 5 // アナログピン5に加速率ダイアル
#define KASOKU 3 // 加速率 = 加速率入力 × 3
#define GENSOKU 3 // 1ノッチ以上の減速率 = 加速率入力 / GENSOKU

int vvvfpat; // 走行音 0~12
int mascon; // マスコンの位置
int inptmascon; // マスコンの位置入力
int compmascon; // マスコンの位置前回と比較
int light; // 常点灯
int inptkasoku; // 加速率入力
int kasoku; // 加速率
int mode; // 走行状態
// 0 停止
// 1 減速
// 2 惰行
// 3 加速

long notch1; // 各ノッチでの最高速度
long notch2;
long notch3;
long notch4;
long notch5;

long teishisp; // 走行する出力をカットする速度

long sttfrq; // 開始周波数
long endfrq; // 終了周波数
long frq; // 周波数
long sttspd; // 開始スピード
long endspd; // 終了スピード
long spd; // 内部スピード 0~3,000,000(速度×10,000)
long contspd; // 指示スピードl
int i;
int j;
int f;

int mascondata[] = { // 各パターンの各ノッチ位置での最高速度 1ノッチ,2ノッチ,3ノッチ,4ノッチ,5ノッチ
20, 40, 60, 80, 130, // 0 パターン 1
20, 40, 60, 80, 130, // 1 パターン 2
20, 40, 60, 80, 130, // 2 パターン 3
5, 20, 40, 60, 100, // 3 パターン 4
20, 40, 60, 80, 130, // 4 パターン 5
20, 40, 60, 80, 130, // 5 パターン 6
40, 80, 120, 200, 300, // 6 パターン 7 新幹線用
40, 80, 120, 200, 300, // 7 パターン 8 新幹線用
40, 80, 120, 200, 300, // 8 パターン 9 新幹線用
20, 40, 60, 80, 130, // 9 パターン10
20, 40, 60, 80, 130, //10 パターン11
20, 40, 60, 80, 130 //11 パターン12
};

int teishi[] = { //走行用の出力を止める速度 速度×10 ピタッと止めるため
49, // 0 パターン 1
49, // 1 パターン 2
49, // 2 パターン 3
49, // 3 パターン 4
20, // 4 パターン 5
49, // 5 パターン 6
29, // 6 パターン 7 新幹線はギヤ比が高いため大きくするとガクンと止まるため
29, // 7 パターン 8
29, // 8 パターン 9
49, // 9 パターン10
49, //10 パターン11
49, //11 パターン12
};


int data[] = {
// 設定可能周波数 123Hz~8000kHz DUTY比の分解能確保のため30kHzぐらいを上限 整数に限る
// 音を出す場合必ず2段階以上入力すること 減速時1段階目音を止めるため

// パターン1の場合
// 1行目 速度0~ 7 1,800Hzで音程変化なし
// 2行目 速度8~18のあいだで 500Hzから1,800Hzまで変化する
// 例えば1,800Hzから500Hzとかにすれば幽霊インバーターも設定可能

//0 パターン1 223系2000番台
1800, 1800, 7, // 1 開始周波数 終了周波数 切替スピード
500, 1800, 18, // 2 開始周波数 終了周波数 切替スピード
500, 750, 30, // 3 開始周波数 終了周波数 切替スピード
600, 800, 40, // 4 開始周波数 終了周波数 切替スピード
550, 600, 50, // 5 開始周波数 終了周波数 切替スピード
250, 700, 120, // 6 開始周波数 終了周波数 切替スピード
-1, // 7 終了コード

//1 パターン2 京急1000
300, 300, 10, // 1 開始周波数 終了周波数 切替スピード
350, 350, 11, // 2 開始周波数 終了周波数 切替スピード
392, 392, 12, // 3 開始周波数 終了周波数 切替スピード
440, 440, 13, // 4 開始周波数 終了周波数 切替スピード
466, 466, 14, // 5 開始周波数 終了周波数 切替スピード
523, 523, 15, // 6 開始周波数 終了周波数 切替スピード
587, 587, 16, // 7 開始周波数 終了周波数 切替スピード
622, 622, 17, // 8 開始周波数 終了周波数 切替スピード
698, 698, 18, // 9 開始周波数 終了周波数 切替スピード
783, 783, 19, //10 開始周波数 終了周波数 切替スピード
900, 900, 35, //11 開始周波数 終了周波数 切替スピード
900, 1000, 37, //12 開始周波数 終了周波数 切替スピード
900, 1000, 40, //13 開始周波数 終了周波数 切替スピード
300, 500, 100, //14 開始周波数 終了周波数 切替スピード
-1, //15 終了コード

//2 パターン3 207系 223系0番台 281系はるか
800, 800, 10, // 1 開始周波数 終了周波数 切替スピード
380, 900, 30, // 2 開始周波数 終了周波数 切替スピード
500, 750, 40, // 3 開始周波数 終了周波数 切替スピード
500, 800, 80, // 4 開始周波数 終了周波数 切替スピード
800, 800, 100, // 5 開始周波数 終了周波数 切替スピード
-1, // 6 終了コード

//3 パターン4 DL
130, 140, 5, // 1 開始周波数 終了周波数 切替スピード
140, 200, 50, // 2 開始周波数 終了周波数 切替スピード
150, 190, 100, // 3 開始周波数 終了周波数 切替スピード
-1, // 4 終了コード

//4 パターン5 221系
150, 200, 10, // 1 開始周波数 終了周波数 切替スピード
200, 1000, 100, // 2 開始周波数 終了周波数 切替スピード
-1, // 3 終了コード

//5 パターン6 EF210
600, 600, 10, // 1 開始周波数 終了周波数 切替スピード
600, 600, 20, // 2 開始周波数 終了周波数 切替スピード
400, 800, 40, // 3 開始周波数 終了周波数 切替スピード
800, 800, 100, // 4 開始周波数 終了周波数 切替スピード
-1, // 5 終了コード

//6 パターン7 223系2000番台
1800, 1800, 7, // 1 開始周波数 終了周波数 切替スピード
500, 1800, 18, // 2 開始周波数 終了周波数 切替スピード
500, 750, 30, // 3 開始周波数 終了周波数 切替スピード
600, 800, 40, // 4 開始周波数 終了周波数 切替スピード
550, 600, 50, // 5 開始周波数 終了周波数 切替スピード
250, 700, 120, // 6 開始周波数 終了周波数 切替スピード
-1, // 7 終了コード

//7 パターン8 京急1000
300, 300, 10, // 1 開始周波数 終了周波数 切替スピード
350, 350, 11, // 2 開始周波数 終了周波数 切替スピード
392, 392, 12, // 3 開始周波数 終了周波数 切替スピード
440, 440, 13, // 4 開始周波数 終了周波数 切替スピード
466, 466, 14, // 5 開始周波数 終了周波数 切替スピード
523, 523, 15, // 6 開始周波数 終了周波数 切替スピード
587, 587, 16, // 7 開始周波数 終了周波数 切替スピード
622, 622, 17, // 8 開始周波数 終了周波数 切替スピード
698, 698, 18, // 9 開始周波数 終了周波数 切替スピード
783, 783, 19, //10 開始周波数 終了周波数 切替スピード
900, 900, 35, //11 開始周波数 終了周波数 切替スピード
900, 1000, 37, //12 開始周波数 終了周波数 切替スピード
900, 1000, 40, //13 開始周波数 終了周波数 切替スピード
300, 500, 100, //14 開始周波数 終了周波数 切替スピード
-1, //15 終了コード

//8 パターン9 207系 223系0番台 281系はるか
800, 800, 10, // 1 開始周波数 終了周波数 切替スピード
380, 900, 30, // 2 開始周波数 終了周波数 切替スピード
500, 750, 40, // 3 開始周波数 終了周波数 切替スピード
500, 800, 80, // 4 開始周波数 終了周波数 切替スピード
800, 800, 100, // 5 開始周波数 終了周波数 切替スピード
-1, // 6 終了コード

//9 パターン10
-1, // 1 終了コード

//10 パターン11
-1, // 1 終了コード

//11 パターン12
-1 // 1 終了コード
};

int datanum[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

byte font[16] = { // 7segの表示パターン
0b00111111, //0
0b00000110, //1
0b01011011, //2
0b01001111, //3
0b01100110, //4
0b01101101, //5
0b01111101, //6
0b00100111, //7
0b01111111, //8
0b01101111, //9
0b01110111, //A
0b01111100, //b
0b00111001, //C
0b00111110, //d
0b01111001, //E
0b01110001 //F
};

int masconvol(int vol){ // マスコン位置検出

// 0~1023の入力を12段階に分ける さらに3段階に分けて真ん中の時だけ採用
// 中途半端な位置の時にでたらめな入力になるので

int a;
if ( (vol * 10 / 284) % 3 == 1 ){
a = 13 - vol / 85;
} else {
a = 0;
}
return a;
}

// 1 非常
// 2 減速5
// 3 減速4
// 4 減速3
// 5 減速2
// 6 減速1
// 7 惰行
// 8 ノッチ1
// 9 ノッチ2
//10 ノッチ3
//11 ノッチ4
//12 ノッチ5

byte wnum;


//アノードコモン
void swrite(byte num){

byte a;

if( f == 1 ){ //1桁目
f = 0;
digitalWrite( 2, HIGH);
digitalWrite( 4, HIGH);

if( num >= 16){
num = num % 16;
}

a = font[num];

PORTD = (~( a << 5 )) & (PORTD | B11100000); // 7seg表示のポートが連続していないための処理
PORTB = ((((~( a >> 3 )) | B11111100 )) & ((~( a >> 1 )) | B11001111 )) & (PORTB | B00110011);

digitalWrite( 2, LOW);


} else { //2桁目
f = f++;

digitalWrite( 2, HIGH);
digitalWrite( 4, HIGH);

num = num / 16;

if( num == 0){ //ゼロサプレス
a = 0;
} else {
a = font[num];
}

PORTD = (~( a << 5 )) & (PORTD | B11100000);
PORTB = ((((~( a >> 3 )) | B11111100 )) & ((~( a >> 1 )) | B11001111 )) & (PORTB | B00110011);

digitalWrite( 4, LOW);


}


}

void setup(){

// PWM PIN設定
pinMode(PWM2A, OUTPUT);
pinMode(PWM2B, OUTPUT);
pinMode(PWM1B, OUTPUT);

// 7SEG PIN設定
pinMode( 2, OUTPUT);
pinMode( 4, OUTPUT);
pinMode( 5, OUTPUT);
pinMode( 6, OUTPUT);
pinMode( 7, OUTPUT);
pinMode( 8, OUTPUT);
pinMode( 9, OUTPUT);
pinMode( 12, OUTPUT);
pinMode( 13, OUTPUT);

// 走行音パターン各開始位置取得
int n;
int m = 0;

for ( n = 1; n <= 11; n++ ){
while ( data[m] != -1 ){
m++;
}

m++;
datanum[n] = m;
}

// 走行音パターン取得注意喚起
i = 0;
while ( i < 3 ){
i++;

j = 0;
while ( j < 10000){
j++;
swrite( 0x88 );
}

digitalWrite( 2, HIGH);
digitalWrite( 4, HIGH);
delay(100);

}

delay(100);

// 走行音パターン取得 しばらくロータリースイッチを動かさないとその位置で決定
do{
j = 0;
while ( j < 1000){
j++;
inptmascon = MASCON;
if ( mascon != inptmascon ){
j = 0;
mascon = inptmascon;
}
if( mascon > 9){
swrite( mascon + 6 );
} else {
swrite( mascon );
}
delay( 1);
}

} while ( mascon == 0 || mascon > 12);

// 走行音パターンほか選択したパターンに合わせて設定

vvvfpat = mascon - 1;

notch1 = (long)mascondata[vvvfpat * 5] * 10000 - 1;
notch2 = (long)mascondata[vvvfpat * 5 + 1] * 10000 - 1;
notch3 = (long)mascondata[vvvfpat * 5 + 2] * 10000 - 1;
notch4 = (long)mascondata[vvvfpat * 5 + 3] * 10000 - 1;
notch5 = (long)mascondata[vvvfpat * 5 + 4] * 10000 - 1;

teishisp = (long)teishi[vvvfpat] * 1000 - 1;

// 決定したパターンを点滅表示

i = 0;
while ( i < 3 ){
i++;

j = 0;
while ( j < 10000){
j++;
if(mascon > 9){
swrite( mascon + 6 );
} else {
swrite( mascon );
}
}
digitalWrite( 2, HIGH);
digitalWrite( 4, HIGH);
delay(200);

}

// マスコン位置を惰行か減速にしてもらう注意喚起 急に走り出さないようにするため

mascon = MASCON;
while ( mascon == 0 || mascon > 7 ){

j = 0;
while ( j < 10000){
j++;
swrite( 0xBB );
}

digitalWrite( 2, HIGH);
digitalWrite( 4, HIGH);
delay( 100);
mascon = MASCON;

}
}


void loop(){

inptkasoku = analogRead(PINKASOKU)/128+1; // analogRead 0~1023 → 1~8
light = analogRead(PINLIGHT )/8; // analogRead 0~1023 → 0~127

inptmascon = MASCON;

if ( inptmascon > 0 && inptmascon < 13 ){
if ( compmascon == inptmascon ){
mascon = inptmascon;
} else if ( compmascon > inptmascon ){
compmascon--;
} else if ( compmascon < inptmascon ){
compmascon++;
}
}

switch ( mascon ){
case 1:
// 非常
contspd = 0;
spd = 0;
mode = 0;
wnum = 0xe;
break;

case 2:
// 減速5
contspd = 0;
kasoku = inptkasoku * 5;
mode = 1;
wnum = 0xb5;
break;

case 3:
// 減速4
contspd = 0;
kasoku = inptkasoku * 4;
mode = 1;
wnum = 0xb4;
break;

case 4:
// 減速3
contspd = 0;
kasoku = inptkasoku * 3;
mode = 1;
wnum = 0xb3;
break;

case 5:
// 減速2
contspd = 0;
kasoku = inptkasoku * 2;
mode = 1;
wnum = 0xb2;
break;

case 6:
// 減速1
contspd = 0;
kasoku = inptkasoku * 1;
mode = 1;
wnum = 0xb1;
break;

case 7:
// 惰行
kasoku = 0;
contspd = spd;

// kasoku = inptkasoku ; 惰行で速度を落とす場合
// contspd = 0;
mode = 2;
wnum = 0;
break;

case 8:
// ノッチ1
contspd = notch1;
kasoku = inptkasoku * KASOKU;
mode = 3;
wnum = 1;
break;

case 9:
// ノッチ2
contspd = notch2;
kasoku = inptkasoku * KASOKU;
mode = 3;
wnum = 2;
break;

case 10:
// ノッチ3
contspd = notch3;
kasoku = inptkasoku * KASOKU;
mode = 3;
wnum = 3;
break;

case 11:
// ノッチ4
contspd = notch4;
kasoku = inptkasoku * KASOKU;
mode = 3;
wnum = 4;
break;

case 12:
// ノッチ5
contspd = notch5;
kasoku = inptkasoku * KASOKU;
mode = 3;
wnum = 5;
break;
}

for ( j = 0; j < 200; j++ ){ // チャタリング防止ループ

swrite( wnum );

if ( spd < contspd ){
if ( contspd - spd <= kasoku ){
spd = contspd;
} else {
spd = spd + kasoku;
}
}

if ( spd > contspd ){
if ( mascon >= 7 ){
if ( spd - contspd <= kasoku / GENSOKU ){
spd = contspd;
} else {
spd = spd - kasoku / GENSOKU;
}
} else {
if ( spd - contspd <= kasoku ){
spd = contspd;
} else {
spd = spd - kasoku;
}
}
}

if ( spd < teishisp && mascon < 8 ){
spd = 0;
mode = 0;
}

OCR2A = 255 - light; // 走行時の常点灯 PWM DUTY比 周波数は31kHz CPU周波数/2/分周256 Aはこの数値からTOP255がDUTY比
OCR2B = (int)(spd / ( 7680 + spd / 390 )); //走行用出力 SPD / 128 / 4 / 10 / DUTY比 ( 1.5 + speed / 390)

for ( i = 0; ;i = i + 3){

sttfrq = data[datanum[vvvfpat] + i];
endfrq = data[datanum[vvvfpat] + i + 1];

if( i == 0 ){
sttspd = 0;
} else {
sttspd = data[datanum[vvvfpat] + i - 1];
}

endspd = data[datanum[vvvfpat] + i + 2];

if ( i == 0 && sttfrq == -1 ){ //走行音が設定されていない場合の処理
OCR1A = 421; // TOP値 = CPUの動作周波数 / 2 / 分周 / 希望周波数 = 16,000,000 / 2 / 1 / frq 19000 = 421
OCR1B = 421 - 421 * (word)light / 245 ; // 音を出すPWMのDUTY比 
TCCR1B = B00010001;
TCCR1A = B00110001;
TCCR2B = B00000001;
TCCR2A = B00100001;
break;
}

// 停止時 音停止

if ( mode == 0 ) {
OCR1A = 421; // TOP値 = CPUの動作周波数 / 2 / 分周 / 希望周波数 = 16,000,000 / 2 / 1 / frq 19000 = 421
OCR1B = 421 - 421 * (word)light / 255 ; // 音を出すPWMのDUTY比 
TCCR1B = B00010001;
TCCR1A = B00110001;
TCCR2B = B00000001;
TCCR2A = B00000001; //PWM 2A(常点灯部分 代わりに1Bで常点灯出力 19kHzで出力したいから)と2B停止

break;
}

// 減速のとき1段階目の音停止

if ( i == 0 && spd <= endspd * 10000 && mode == 1 ) {
OCR1A = 421; // TOP値 = CPUの動作周波数 / 2 / 分周 / 希望周波数 = 16,000,000 / 2 / 1 / frq 19000 = 421
OCR1B = 421 - 421 * (word)light / 255 ; // 音を出すPWMのDUTY比 
TCCR1B = B00010001;
TCCR1A = B00110001;
TCCR2B = B00000001;
TCCR2A = B00100001; //PWM 2A停止(常点灯部分 代わりに1Bで常点灯出力) 2B出力

break;
}

// 惰行 vvvf音停止

if ( mode == 2 ){
OCR1A = 421; // TOP値 = CPUの動作周波数 / 2 / 分周 / 希望周波数 = 16,000,000 / 2 / 1 / frq 19000 = 421
OCR1B = 421 - 421 * (word)light / 245 ; // 音を出すPWMのDUTY比 
TCCR1B = B00010001;
TCCR1A = B00110001;
TCCR2B = B00000001;
TCCR2A = B00100001; //PWM 2A停止(常点灯部分 代わりに1Bで常点灯出力) 2B出力

break;
}

// 高速時 vvvf音停止

if ( sttfrq == -1 ){
frq = 31500;
OCR1A = (word)(8000000 / frq); // TOP値 = CPUの動作周波数 / 2 / 分周 / 希望周波数 = 16,000,000 / 2 / 1 / frq
OCR1B = (word)(8000000 / frq - 8000000 / frq / 99); // 音を出すPWMのDUTY比 100/99 = 1%
TCCR1B = B00010001;
TCCR1A = B00110001;
TCCR2B = B00000001; //PWM 2A/2B 分周1
TCCR2A = B11100001; //PWM 2A/2B 出力

break;
}

// VVVF音

if ( ( spd >= sttspd * 10000 ) && ( spd < endspd * 10000)){
frq = ( endfrq * 10 - sttfrq * 10 ) / ( endspd - sttspd ) * ( spd - sttspd * 10000 ) / 100000 + sttfrq;

if ( frq < 123 ){
frq = 123;
} else if ( frq > 31500 ) {
frq = 31500;
}

OCR1A = (word)(8000000 / frq); // TOP値 = CPUの動作周波数 / 2 / 分周 / 希望周波数 = 16,000,000 / 2 / 1 / frq
OCR1B = (word)(8000000 / frq - 8000000 / frq / 15); // 音を出すPWMのDUTY比 100/15 = 6.6%
TCCR1B = B00010001;
TCCR1A = B00110001;
TCCR2B = B00000001; //PWM 2A/2B 分周1
TCCR2A = B11100001; //PWM 2A/2B 出力

break;
}
}

}

}

コメント(34)

ソースですが、文字化けしてかなりの部分欠けています
<や>がタグと認識されているようです
参考URLのソースファイルをダウンロードして下さい
本文に書き忘れましたが、もし挑戦していただけるようでしたらモーター音を作って是非、是非、投稿して下さい
よろしくお願いします

PWMコントローラーコンテストのトピ主でございます。
とうとう上陸されましたね。ここではこの手の話は流行らないものかと思っていました。そんな僕はそのうちロジックICで「あまり色々考えていない原始的なデシタル回路のポイント制御器」の作成を検討中です。
ここ数カ月は鉄道模型をそっちのけに電子工作にほとんどの時間を費やしていました。二個PWMのを作りました。555とオペアンプのものです。そのうちの一つはかのコンテストで「出展」されていた方のもので動作が安心してみていられる感じです。555の6,7ピンの抵抗をスイッチで変えられるようにしています。それでインチキ「可変電圧可変周波数」を実現してみたりしてます。あっそれは明日ネタにしましょう。

you-kei様 コメントいただきありがとうございます!
電子工作初心者の私にとって、PWMコントローラーコンテストの内容は非常に興味深いものです
皆様の創意工夫、それに対する意見など貴重なものばかりです
実際、かなりの部分参考にさせていただいています
それで、いくらかでもお返しできたらと思い公表しました
あちらでは最近投稿がないのでネタ投入お願いします
楽しみにしてます


かのコンテストですが、僕があのトピを立てたのは各陣営様からの情報集積で目的で、あとで自分がありがたく頂戴するという至ってヤラティー考え方のもと成り立っておりまして、僕自身電子回路はズブの素人でございますし、555を使った回路、それにオペアンプをつけたもの、オペアンプだけで組むもの、Hブリッジ、PICを使ったもの、シュミットトリガーのとか、専用ドライバーの物といろいろ出尽くした感があるようですね。しかしArduinoのモノはまだ存在していなかったように思われます。

で、ArduinoはunoがCD一枚分の値段だそうですが、ブートローダーというのはArduinoからパソコンでATMEGA328Pに書き込みができるものなんでしょうか?といいますか、ArduinoをATMEGA328Pの書き込み器として使うことは可能なんでしょうか。

Arduinoのブートローダーですが、Arduinoを1個買えば書き込み機として使用可能です
ただし私が確認しているのは、最新のUnoではなく1つ前のDuemilanoveです

ブートローダーはArduinoのチップに入ってます
パワーパックを1台だけ作るならプログラムを書き込んでArduinoからチップを外すのもありです

複数作るとかチップを壊したとかArduinoを他にも使う場合は、プログラムを書き込むのにArduinoが1台は必要ですが、
一番簡単なのはブートローダー書き込み済みチップを買うこと
スイッチサイエンスさんで、商品カテゴリー チップ のところにArduino交換チップ(ブートローダ書き込み済みATMega328P-PU)というのがあります
手間を考えるとかなりリーズナブルだと思います。

本題のDuemilanoveを書き込み機として使用する方法は
Kimio Kosaka氏の
http://www.geocities.jp/arduino_diecimila/

Hack
1.外付けAVRライタ無しでBootloaderを書込む(FTDI-Bitbang Method)
のところを参考にしました

Duemilanoveが入手できない場合は
秋月電子通商さんで売っているFT232RL USBシリアル変換モジュールを使えば可能です。
私はこれを使ってブレッドボードで書き込み機を作っています
兼用でプログラムもこれからブレッドボードISPケーブルというのを使ってパワーパックにつないで書き込みしてます
パワーパックからチップをいちいち引っこ抜く手間がないので修正も非常に楽です
参考にしてみて下さい

今のところの報告ということでお伝えしますが、ArduinoのUnoを購入しまして、ArduinoIDEでまず冒頭の簡単なものをチップに書きこんで使ってみました。なかなか安定した走りでした。これを555とオペアンプで組んだら頭ひねっているところです。
それとArduinoIDEではどうもブートローダーも書き込みができるようですね。

いや〜スゴイっすねコレわ(^^)

電車にはあまり興味無かったのですが、動画のVVVF音聞いてゾクゾクしました。
arduino初心者ですがパーツ揃えたので頑張って作って見ます!

初めまして。
すごいですね。私も作ってみたいです。
質問なんですが、
電子工作に関しては本当の素人ですので、配線図なども読めません。よろしければ、参考になりそうなサイトを紹介していただければ幸いです。

はじめまして。

通販の商品で作れるなんてすごいですね!

質問なんですが・・・・

本ページの冒頭にありました、Arduinoの基板は青色ですが秋月電子の緑の基板でも制作可能ですか?下記のURLです。
http://akizukidenshi.com/catalog/g/gK-04590/
よろしくお願いします。

返信が遅くなってすいません。
私もつい最近始めた素人です。
電子工作のことを何も知らずに、「Bトレインと電子工作のページ」のノッチ付きコントローラーを見よう見まねで作ったところから始まりました。まずハンダの付け方が分からない 検索 と言ったレベルからスタートでした。
実際動くものを作りながら分からないことを調べていく方が夢中になれると思います。
参考になるサイトですが、
traintrainの「拓啓ぽん」さんの「オヤコの遊び場」
同じくtraintrain掲示板のPWMコントローラーコンテスト等々
コントローラー パワーパック で検索すればかなり出てくると思います。
あとArduinoは、武蔵野電波のブレッドボーダーズ/プロトタイパーズで知りました。
参考にしてみて下さい。

返信が遅くなってすいません。
早速ですが、制作可能です。秋月電子さんのキットは、Arduinoの互換品ですから。これに別基板でArduino以外の回路を作って配線すれば動きます。ただマイコンにbootloaderを書き込む必要がありますので、難しいようなら完成品か、bootloader書き込み済みのチップを入手された方が良いと思います。また別基板にすると寸法が大きくなりますので、動くようになったらユニバーサル基板で1つにまとめるとコンパクトになります。是非挑戦してみて下さい。

返信がかなーり遅くなってすいません。
コメントありがとうございます。
是非挑戦してみて下さい。模型を動かすのが本当に楽しくなりますよ。
動いたら、プログラムいじってお好みのコントローラーに仕上げて下さい。

はじめまして。

いろいろ検索していてここにたどり着き、つくってみたのですが...

使ってるうちにパワーMOSが故障してしまう場合があるようです...

初めまして。
ロータリースイッチを15段にしたい場合はプログラムをどのようにすればよいでしょうか?
初歩的な質問ですがお教えください。
お願いします。

コントローラーが完成して電源はついてマイコンにも5vの電気が行くのですが7セグが付きません。送って見てもらうことは可能ですか?

コントローラーが完成して電源はついてマイコンにも5vの電気が行くのですが7セグが付きません。送って見てもらうことは可能ですか?

しろくまさんの回路を応用して電車でGo

ワンハンドルコントローラーで作成してみました。

力行5段惰行ブレーキ8段非常1段計15段です。

今すごい嵌ってます。

これがきっかけで今ではArduinoでいろんなことをしています~

>鉄道太郎さん
横から失礼致します。LEDはアノードコモンですか?トランジスタ2SA1015の足の配置を間違えていませんか?私はここでつまづいていたので参考までにどうぞ^^

素晴しいものを公開していただきありがとうございます。
「鉄道太郎」さんが質問されていた、秋月電子のマイコンボードで製作してみたところ、「鉄道太郎」さんとまったく同じようにLEDが光らないという症状が出ました。
わたしは、5V入力の数か所あるところのつないぐ場所がわからなかったので、基盤の5Voutと書いてあるところに+、Gndと書いてあるところに-をまとめてつなぎました。
このつないでいる場所が間違っているのではないかと思います。
詳しく教えてください。
あとプログラムは参考URLのものをそのまま書き込めばいいんでしょうか。詳しく教えてください。
ちなみに、マイコンは(ブートローダ書き込み済みATMega328P-PU)を使っています。
たいへん厚かましいお願いではありますが(harunirenoki888_0828@yahoo.co.jp)まで基盤の写真などなんでもいいのでおくってくださいませんか。
本当にマイコン初心者ですみません。
よろしくお願いします。

 始めまして
 私はArduino超ビギナーです。私もマイコンでPWMを製作してみたいと思い検索していた所、しろくまさんの投稿を見つけ、拝見させていただき、すばらしいと思い製作させていただきました。
 
 そこで質問させていただきたいのですが、基盤の本製作前にブレットボードにて仮組みし動作させて見ましたが、ロータリースイッチの選択動作が不安定になってしまいます。ちなみに7セグは表示(配線)は間違っていないようです。
どうしたら動作が安定するのかお分かりでしょうか?

私はPICマイコンを少しだけかじったことがあります。マイコンの書き込みはコピペさせて頂いたので失敗していないと思います。
基盤は仮組、本組と2度製作しましたが2度共に動作不安定となってしまいました。配線、部品配置も間違ってはいないようです。
部品配置後の短絡場所等に遠近の違いでもあるのでしょうか?
お分かりの範囲でよろしいですのでお答えいただければ幸いです。 

作者ではないですが私も作成時色々失敗しているのでわかる限りでアドバイスを失礼します。

ロータリースイッチには
ショーティングタイプとノンショーティングタイプ、どちらを使用されていますか?
作者のしろくまさんはアルプスのショーティングタイプのものを使われていると思います。
http://www.marutsu.co.jp/shohin_5471/


ノンショーティングタイプだと、どこの端子にも接続していないタイミング(切り替え途中)に不安定になります。
一度ロータリースイッチの形をご確認ください・・・。
間違ってたらスイマセン笑

どうもはじめまして^^

いやーこのコントローラーすごくいいですね!
自分も作ってみようかと思ったのですがどうしてもDuemilanoveが見つかりません・・・・・これでもいけますかね?
http://www.switch-science.com/catalog/789/

どうもはじめまして^^

いやーこのコントローラーすごくいいですね!
自分も作ってみようかと思ったのですがどうしてもDuemilanoveが見つかりません・・・・・これでもいけますかね?
http://www.switch-science.com/catalog/789/

度々横から失礼します。
DuemilanoveでなくUnoでも全然可能ですよ!

お久しぶりです。というべきでしょうか?

2012年5月22日にコンメントさせていただいた
杉村和人です。
あれから長い年月が経ち、
やっと、制作の準備が整いました。
久しぶりにここへ来てみると、
沢山の方が四苦八苦しているようで、
私自身としては、今後の制作に
参考にさせていただきたいと思っております。
ここで、皆様にご提案があるのですが、
私たち全員がこのコントローラーの制作を成功出来るよう、
皆様の様々な知識を出し合い、
気軽に質問できて、みんなで解決する
コミュニティを立ち上げ、
皆様と今後協力して製作するのを考えています。
もちろん強制ではありませんし、
一体どこでやるのかも決まっておりません。
(Google+など?)
一緒に頑張って見ませんか?
提案など、お待ちしております。

こちらからも横槍申し訳ありません。
ノンショーティングタイプが原因と見て調べましたが、
ロータリースイッチをノンショーティングタイプの方でやっている方がいらっしゃいました。

原因ははっきり突き止められませんでしたが、
私も同じ事象が起きてしまいました。
原因とまで言いませんが、
書き込み時のボード(UNO or 秋月ボードキットなど)
等の違い、(違うと思いますが…)
そして、上の回路図への組み立て時、ベースを一から作っているか、UNOの拡張ピンから作っているか、等の違い。
そして、書き込みソースに問題があるか。
だと思います。
もう少し努力して見ますが…。

度々失礼します。
各回路によって基板内で多少の抵抗がありますがそれが影響しているのではないでしょうか。(マスコン位置検出は5Vをロータリースイッチにつけた抵抗値によって上下させているため)

もしプログラムが解読できるのでしたら以下の

int masconvol(int vol){ // マスコン位置検出

// 0~1023の入力を12段階に分ける さらに3段階に分けて真ん中の時だけ採用
// 中途半端な位置の時にでたらめな入力になるので

int a;
if ( (vol * 10 / 284) % 3 == 1 ){
a = 13 - vol / 85;
} else {
a = 0;
}
return a;
}

この部分を調整していくと上手くいくと思いますよ。
ロータリースイッチの選択が不安定になる理由は、それぞれの接点に接した時、上記の計算が繰り返されているからだと思われます。(あくまで個人的な解釈なので参考までに。)

この場をお借りしてArduinoに目覚めさせてくださったしろくまさんに感謝いたします。

はじめまして
私もこの制御装置の動画を見て驚き、自分もほしいと思いました!
マイコンはやったことがなくほぼ初心者ですが、LMC555を使用した加減速付き制御装置を製作したことがあります。

回路図に関しての質問なんですが・・・
図中のDFR・TXD・RXDは何を指していてどれを接続すればよいのでしょうか?

教えていただければ幸いです。

はじめまして
この投稿を発見して回路を完成させ動作確認したのですが、一桁目のセグメントが点灯しませんでした、、、、、回路の配線ミスかな?と思い確認したのですが配線ミスもなし、、、ということはプログラムのせいなのでしょうか?対処法を教えて頂けると幸いです。よろしくおねがいします!
りんとれ

すばらしいです。
感動しました。

初めまして、私は上記の1桁目のセグメントが光らないの対処は、arduinoのIDEを1.0.5verの古いのに変えたら、よくわからないが光りました
(1.7.Xとブートする回路が違うから変えてみた)
それと、マスコンの取得の部分は、作ったマスコンを調べて、それにプログラムを合わせないと動かないと思いました。
とりあえず、ブレッドボードだけど完成できました、面白い物をありがとうございます。

はじめまして。

私も同じく1桁目の7セグが点灯しませんでした。

プログラムを確認したところ、複合演算子が
適切ではないようです。
古いIDEではokだったのかも知れませんが…。

259行目の

f = f++;

f = 1;

とすれば、点灯するようになります。
IDEは1.6.3で確認済みです。

今回僕も作ったのですが、何回やっても7SEGがつかず、何も走りませんこれでも2作目です。これはプログラムの問題ですか?ver1.6.3に下げてやってます。回路は何も間違えてないはずです。書き込み方法は僕の場合、一度arduino UNOにさして、書き込んでそれをただ基盤にくっつけてるだけです。動いたらすごく嬉しいです!

すいません!返事をし忘れました。初めまして!桃ちゃんです

すいません!返事をし忘れました。初めまして!桃ちゃんです

コメント/評価を送る

 
評価: 星1つ星2つ星3つ星4つ星5つ
記事を星の数で評価できます (´・ω・`)ショボーン★ ・・・ (・∀・)イイ!★★★★★
    
 
 

検索

キーワードで探す


 

タグで探す

最近のコメント

ArduinoでPWMパワーパックを作ってみた
  しろくま 05/03 19:57
  you-kei(ゆーけい) 05/03 21:46
  しろくま 05/07 21:37
  you-kei(ゆーけい) 05/08 12:32
  しろくま 05/08 22:13
  you-kei(ゆーけい) 05/19 20:54
  IKE 05/03 11:01
  杉村和仁 05/22 22:13
  鉄道太郎 08/26 19:30
  しろくま 09/26 23:15
  しろくま 09/26 23:33
  しろくま 09/26 23:43
  chikin 10/25 6:08
  sk0107go 03/23 20:58