JB23ジムニーの助手席への固定式テーブル設置に失敗して、しばらく時間が経ってしまいました。
助手席の人から「カップホルダーがない!」との悲痛な声が多くなってきたので、そろそろカップホルダー付きのテーブルを、初代よりも進化させて自作します。
初代の固定式テーブル
助手席からの評判も良かったのですが、短期間しか使わなかったテーブルです。
初代のコンセプトは、
- ペットボトルホルダー付き
- 助手席の乗降の邪魔にならない
の2点でした。
固定位置を上下方向で2カ所設定して剛性を出そうとしたので、勢いで2階建てになっています。そのために上側のテーブル面が、エアバックの展開に影響しそうな位置になってしまい、すぐに外しました。
その後は、良いアイデアが思いつくまでペットボトルホルダーはあきらめて、ソーラーパワー腕時計の充電スタンドをつけた板を、テーブルの代わりに置いていました。
今回の自作テーブルのコンセプト
今回は、先回の時に欠点となっていたエアバックへの影響は無くします。
また、蓋で密閉できるペットボトルは対象とせず、コンビニで手軽に買えるカップコーヒーが置ける事を目指します。
- カップホルダー付き
- 助手席の乗降の邪魔にならない
- エアバックの展開を阻害しない
この3点をコンセプトとして、今回のテーブルを自作します。
テーブルの構造を決める
まず、カップホルダーはテーブル面上に市販のものを、最後に固定することにします。後から取り替えもできるので、テーブル自体が完成するまでは、あまりこだわらないことにします。
テーブル面は格納式にして、乗降性とエアバック展開の条件をクリアします。
さらに、高級感をだすために、電動スライド開閉式に挑戦します。
スライドテーブルの奥行き
JB23ジムニーのグローブボックス上にある凹形状の奥行きは、約10cmです。
グローブボックスの扉面から少し出ていても乗降性に影響しないので、テーブルの台座となる板の奥行きは15cmとします。
台座となる奥行き15cmの板を、MDFから切り出しました。
テーブル面はアクリル板にして、その下に配置する機構部やArduinoなどのLED光が見えるようにします。家で何かないか探したところ、もう使わなくなっていたサンバイザーがでてきました。
このサンバイザー、横幅もちょうどいいので、外形は加工せずにそのまま使います。
テーブルのスライドレール
テーブルを滑らかに動かすためのレールを、安価な引き出し用のスライドレールから探してみましたが、汎用品は20cm以上のものばかりでした。
スライド長さ10cm以下では、アルミの押し出し材を使ったものを唯一みつけたので、早速2個注文しました。
取付用の小さなネジを別に入手しないといけませんが、レール自体は滑らかに動き、強度も充分にありそうです。
電動格納部の自作
ステップモーター28BYJ-48を使う
今回の作品のキモとなる電動開閉機構は、ステップモーター(ステッピングモーター)をArduino で制御するものを自作します。
ステップモーター28BYJ-48は、5Vと12V駆動のものがあります。今回は重力の影響を受けない水平方向の動きで、回転速度も遅くていいので、5V駆動のものを使ってみます。
スライド機構
台座の両側に、電動開閉機構部と当たらない高さまで壁をつけて、スライドレールを取り付けます。
テーブルを取り付ける側は、L字断面のプラスチック押し出し材をつけておきます。
台座となる板は、モーターとギヤ用のかさ上げ板を追加して、黒く塗装しておきました。
電動開閉機構
まずは、ステップモーターの出力をギヤで減速します。ギヤは、壊れたプリンターから外したものを、加工して使います
不必要に長い軸や邪魔な出っ張りの部分を切り落として、ヤスリで表面を整えました。
減速したドリブン側のギヤにアームを付けて、開閉方向の動きに変えます。
ArduinoとステップモータードライバULN2003を使う回路
Fritzingで回路図を作りました。
回路図の右半分は、ステップモーター28BYJ-48と、そのULN2003ドライバーモジュールなので、安く購入できる完成品を使っています。
テーブルを電動開閉するアームの位置情報を得るために、全開と全閉時に押される位置にポジションスイッチ(リミットスイッチ)を使います。それぞれスイッチがオンの時はHIGH(5V)、オフの時はプルダウン抵抗でLOW(約0V)の信号をArduinoに送ります。
操作用のモメンタリースイッチも、別に1個使います。
LEDは、モーターを動かす間だけ光るようにスケッチ(プログラム)を書きます。
ブレッドボード上で動作確認してから、汎用基板で回路を作り台座に搭載しました。
ポジションスイッチ動画
制御方法
Arduinoで、テーブルの開閉をコントロールします。
開閉の状態切り替え命令は、モメンタリースイッチ使って、順番に
- 全閉。
- 開く方向に動かす。途中でスイッチが押されることなく全開したら5に移行。
- (開作動中にスイッチが押されたら)止める。
- 閉じる方向に動かす。全閉したら1に移行。
- 全開。
- 閉じる方向に動かす。途中でスイッチが押されることなく全閉したら1に移行。
- (閉作動中にスイッチが押されたら)止める。
- 開く方向に動かす。全開したら5に移行。
の状態に切り替えます。途中状態が多くなっていますが、 何か挟まった時等の非常時に、ボタンを押せば止められて、さらにボタンを押せば反転して動くようにするために、8パターンの状態を推移するようにしました。
電源投入時は、全閉/全開検出スイッチの状態によって、
から始めます。途中で止まっている状態で電源を入れた場合は、テーブル上に飲み物等があるかもしれないので、次に操作スイッチを押したら開く側の動きにします。
スケッチ(プログラム)は最後に紹介します。
完成!(動画あり)
スケッチをArduinoに書き込んだら、車に取り付けて動かしてみます。
定電圧で低回転速度をつくれるステップモーターだからできる、静かで力強い動きです。
Arduino project #4 「車の助手席用の電動格納テーブルをつくる」Making auto-open/close table for passenger seat of car
出力軸の形状が特殊なのでギヤの入手が難しいですが、それをクリアできれば28BYJ-48は、静かにゆっくり動かしたい物を自作する時に重宝するモーターです。
スケッチ(プログラム)の紹介
int operationledPin = 3;
int motorclosePin = 8;
int motoropenPin = 9;
int operationswPin = 10;
int powerOnled = 12;
int motorPin1 = 4;
int motorPin2 = 5;
int motorPin3 = 6;
int motorPin4 = 7;
int motorSpeed;
int count = 0;
int speedcontr = 0;
int countstop = 320;
int conditionNumber = 0;
int lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};
void setup() {
pinMode(operationledPin,OUTPUT) ;
pinMode(motorclosePin,INPUT) ;
pinMode(motoropenPin,INPUT) ;
pinMode(operationswPin,INPUT) ;
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
Serial.begin(9600);
if (digitalRead(motoropenPin) == HIGH){
conditionNumber = 4;
} else if (digitalRead(motorclosePin) == HIGH){
conditionNumber = 0;
} else {
conditionNumber = 6;
}
digitalWrite(powerOnled , HIGH);
}
void loop() {
if (digitalRead(operationswPin) == HIGH) {
if(conditionNumber<7){
conditionNumber++;
}else {
conditionNumber = 0;
}
delay(50);
while(digitalRead(operationswPin)==HIGH){}
}
if(conditionNumber == 0){
if (digitalRead(motorclosePin) == HIGH){
digitalWrite(operationledPin, LOW);
digitalWrite(motorPin1,LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
count = 0;
} else {
digitalWrite(operationledPin, HIGH);
speedcontr = (3*count);
motorSpeed = (2000+speedcontr);
anticlockwise();
count++;
}
}else if(conditionNumber == 1){
if (digitalRead(motoropenPin) == HIGH){
digitalWrite(operationledPin, LOW);
digitalWrite(motorPin1,LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
count = 0;
conditionNumber = 4;
} else {
digitalWrite(operationledPin, HIGH);
speedcontr = (3*count);
motorSpeed = (2000+speedcontr);
clockwise();
count++;
}
}else if(conditionNumber == 2){
digitalWrite(operationledPin, LOW);
digitalWrite(motorPin1,LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
count = 0;
}else if(conditionNumber == 3){
if (digitalRead(motorclosePin) == HIGH){
digitalWrite(operationledPin, LOW);
digitalWrite(motorPin1,LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
count = 0;
conditionNumber = 0;
} else {
digitalWrite(operationledPin, HIGH);
speedcontr = (3*count);
motorSpeed = (2000+speedcontr);
anticlockwise();
count++;
}
} else if(conditionNumber == 4){
if (digitalRead(motoropenPin) == HIGH){
digitalWrite(operationledPin, LOW);
digitalWrite(motorPin1,LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
count = 0;
} else {
digitalWrite(operationledPin, HIGH);
speedcontr = (3*count);
motorSpeed = (2000+speedcontr);
clockwise();
count++;
}
}else if(conditionNumber == 5){
if (digitalRead(motorclosePin) == HIGH){
digitalWrite(operationledPin, LOW);
digitalWrite(motorPin1,LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
count = 0;
conditionNumber = 0;
} else {
digitalWrite(operationledPin, HIGH);
speedcontr = (3*count);
motorSpeed = (2000+speedcontr);
anticlockwise() ;
count++;
}
}else if(conditionNumber == 6){
digitalWrite(operationledPin, LOW);
digitalWrite(motorPin1,LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
count = 0;
}else if(conditionNumber == 7){
if (digitalRead(motoropenPin) == HIGH){
digitalWrite(operationledPin, LOW);
digitalWrite(motorPin1,LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
count = 0;
conditionNumber = 4;
} else {
digitalWrite(operationledPin, HIGH);
speedcontr = (3*count);
motorSpeed = (2000+speedcontr);
clockwise();
count++;
}
}
}
void anticlockwise()
{
for(int i = 0; i < 8; i++)
{
setOutput(i);
delayMicroseconds(motorSpeed);
}
}
void clockwise()
{
for(int i = 7; i >= 0; i--)
{
setOutput(i);
delayMicroseconds(motorSpeed);
}
}
void setOutput(int out)
{
digitalWrite(motorPin1, bitRead(lookup[out], 0));
digitalWrite(motorPin2, bitRead(lookup[out], 1));
digitalWrite(motorPin3, bitRead(lookup[out], 2));
digitalWrite(motorPin4, bitRead(lookup[out], 3));
}