パドルシフト付きの革ハンドルに交換したので活用したいが、シフトレバーをMモードに倒さないとパドルシフトが一切使えない。
Mモードに倒しっぱなしだと発進時のシフトアップもすべて手で行わねばならず面倒くさい。普段はDモードでダラダラ流して、カーブに進入するときだけパドル操作でシフトダウンしたい。
・・・という目的でこういうのがあるらしいが、入手方法もよく分からんし、配線もよく分からん。
パドルを引いたらMモードに入り、5秒たったらMモードから抜けるだけ、の簡単な工作をやってみた。1年ぐらいグダグダとやったので経緯を書くと大変なことになってしまい、結果だけサクッと書いておく。
Arduino Microを中心に、パドルの電圧をA/Dで読み取ってアップ/ダウンを判断、7407でMモードとシフトレバー+/-に介入、という構成を取っている。
回路図はこんな感じ。
左側がArduino周り、中央の囲みがシフトレバー、右の囲みがパドルシフト。
当初電源周りはアクセサリの12Vを直結してArduinoに乗っている5Vレギュレータ任せでやっていたが、レギュレータの発熱でマイコンが暴走?する現象が頻繁に起きたので100円ショップのシガレット-USBアダプタをバラして5V電源として使用している。
工夫したのは3カ所、
- シフトレバー側に介入するのはパドルを引いた最初の操作のみ。
電圧を読んでMモードに切り替えるだけでもよいが、切り替えるタイミングによっては操作がすっぽ抜けてしまう。逆の発想で、Mモードに入れるのを遅らせて最初の操作が完全に無視されるようにしておき、その補償として最初の操作分のみシフトレバー側に介入する動作としている。
2発目以降の操作はArduinoは一切関与せず、パドルシフトから通常の操作が行われるだけとなる。
- Mモードの状態をフィードバックしている。
パドルシフトを引いた最初の操作のみシフトレバー側に介入する動作なので、シフトレバーがMモードに入った状態でパドルシフトを引くと、パドルシフトから+Arduinoが介入したシフトレバー側、の計2回操作が行われてしまう。このため、すでにMモードに入っているならばArduinoは動作を開始しないようにしている。
- A0のアナログ入力の前段にリードリレーを追加してある。
エンジンの回転数によってはパドルシフト側で勝手にシフトアップが入ってしまう現象への対策として急遽取り付けたもの。パドルシフト側の5VプルアップとArduino側の5Vにズレが生じ、Arduino側5Vとシフトアップの電圧が一致したために誤動作したのではないか=A0の線を遮断してしまえばよいのではないか、と考えたが、取り付けた以降は安定しているので理由については深く考えないことにした。
弊害として、以前は最後にパドルシフトを引いた時間から5秒間維持としていたが、最初にパドルシフトを引いた以降はアナログ入力をモニタできなくなるので最初にパドルシフトを引いてから5秒間、という操作に限定されてしまう。
// ピン設定 // PIN_AD : 5V 480Ω pull-upのパドル抵抗入力 // PIN_MANUAL : マニュアルモードリレー出力 0: Dモード 1: Mモード (導通) // PIN_UP/DOWN : シフトリレー出力 0: OFF 1: ON (導通) // up 470±20 2.26V/4.95V 467 // down 610±20 2.92V/4.95V 604 // パドルからの電圧入力 input analog // 5V 440Ω pull-up, UP 360Ω (2.26V), DOWN 620Ω (2.92V) #define PIN_PAD_AD A0 // パドル入力のリレー output digital // arduinoからパドル本線へのノイズ?抑制のため #define PIN_PAD_AD_RELAY 12 // Mモード状態監視 input digital // 1: Dモード 0: Mモード #define PIN_FEEDBACK 2 // Mモード制御 output digital // 1: Mモード (7407 lo出力) #define PIN_PAD_MANUAL 3 // シフトレバー UP制御 output digital // 1: on (7407 lo出力) #define PIN_PAD_UP 5 // シフトレバー DOWN制御 output digital // 1: on (7407 lo出力) #define PIN_PAD_DOWN 7 // マニュアルモードの継続時間[ms] #define MANUAL_TERM 5000 void setup(){ // パドルスイッチ入力 pinMode ( PIN_PAD_AD , INPUT ); // AD入力遮断リレー制御 pinMode ( PIN_PAD_AD_RELAY, OUTPUT ); digitalWrite( PIN_PAD_AD_RELAY, HIGH ); // 0: AD入力遮断 // モード監視 pinMode ( PIN_FEEDBACK , INPUT ); // 車体側 5V pullupのため、内部 pullupは指定しない // 7407制御 pinMode ( PIN_PAD_MANUAL , OUTPUT ); pinMode ( PIN_PAD_UP , OUTPUT ); pinMode ( PIN_PAD_DOWN , OUTPUT ); digitalWrite( PIN_PAD_MANUAL , LOW ); // 0: OFF digitalWrite( PIN_PAD_UP , LOW ); // 0: OFF digitalWrite( PIN_PAD_DOWN , LOW ); // 0: OFF } void loop(){ unsigned int ad_val; boolean is_up_on; boolean is_dw_on; // Dモードになっている (マイコン介入 or レバー操作どちらも) if ( digitalRead(PIN_FEEDBACK) == 1 ){ ad_val = analogRead( PIN_PAD_AD ); is_up_on = ( (ad_val > 400) & (ad_val < 529) ) ? true : false; is_dw_on = ( (ad_val > 530) & (ad_val < 649) ) ? true : false; // パドルが引かれている if ( (is_up_on == true) || (is_dw_on == true) ) { // パドル検出から ウェイトして Mモードへ遷移 → 既存回路側から操作が入り込むのを回避 delay(50); digitalWrite( PIN_PAD_MANUAL , HIGH ); // Mモードへ遷移 digitalWrite( PIN_PAD_AD_RELAY, LOW ); // AD入力遮断 // UP/DOWNを入れる delay(50); if ( is_up_on == true ) digitalWrite( PIN_PAD_UP , HIGH ); if ( is_dw_on == true ) digitalWrite( PIN_PAD_DOWN, HIGH ); delay(200); digitalWrite( PIN_PAD_UP , LOW ); digitalWrite( PIN_PAD_DOWN, LOW ); // 2回目以降のシフト操作は既存回路側から行われるので マイコンからは介入しない // マイコン介入は Mモードの維持のみ // MANUAL_TERM[msec] 後に Mモードを解除 delay(MANUAL_TERM); digitalWrite( PIN_PAD_MANUAL , LOW ); // Mモードを解除 digitalWrite( PIN_PAD_AD_RELAY, HIGH ); // AD入力再開 } } }
現時点では基板と車体との接続に7本(電源2本、パドル入力2本(片方はGND)、Mモード, シフト+/-)必要だが、操作のすっぽ抜けが発生してもOK、と割り切ってしまえば電源2本、パドル1本、Mモード、の計4本まで圧縮できるはず。
あとは、障害時に手早く機能を切り離せるようにしておきたいな、とかそのあたりが今後の課題。