• 車種別
  • パーツ
  • 整備手帳
  • ブログ
  • みんカラ+
イイね!
2008年11月29日

アクセル開度もコントロールしちゃう♪

アクセル開度もコントロールしちゃう♪ おはようございます。

ケロタン少佐デありま~す・・・(^_^;)ヾ




こんかいは・・・


TREC



PIVOT



BRITZ

の様なものを

自作にて考えてみまちた。


回路図は・・・







アクセル開度テーブルは・・・







1.ノーマル
2.フラット
3.スポーツ
4.エコ
5.バック

の5種類から・・・





【システム用件】

・運転席足元のアクセルペダル上に設置してある
アクセル開度センサーに割り込み配線

・開度センサーは、ボリューム抵抗によるアナログデータと推測。

・おそらく、0V~5Vのアナログデータである。

・角度検出のデジタルデータであった場合は、再度修正予定
こっちの方がデジタルなので楽かな…(例)舵角センサー



【制御フロー】

・アクセル開度に応じた電圧値のアナログデータを取得

・マイコン内にて、デジタルデータへ変換

・各モードテーブルに沿ったデジタルデータへ変更

・専用IC用にデータをデジタル変換

・専用ICへデータ送信

・デジタルデータをアナログ電圧データに変換

・アクセル開度センサーへ出力

・最初へ戻る(無限ループ)





【プログラム】

/*************************************************************************************************

AVR Studio 4 C言語用 Ver1.1(ATmega88用) 2008.11.28

アクセル開度コントロール プログラム (A・O・C)

Program Name : accel-open-control-ver1.1.c
Version : 1.1
Language : AVR C言語 (WinAVR)
Device : ATmega88
Clock : 1MHz(内蔵RC発振)
Author : ケロタン少佐


**************************************************************************************************

I/O

(PCINT14/RESET) PC6 | 1****28| PC5 (ADC5/SCL/PCINT13)
(PCINT16/RXD) PD0 | 2****27| PC4 (ADC4/SDA/PCINT12)
(PCINT17/TXD) PD1 | 3****26| PC3 (ADC3/PCINT11)
(PCINT18/INT0) PD2 | 4****25| PC2 (ADC2/PCINT10)
(PCINT19/OC2B/INT1) PD3 | 5****24| PC1 (ADC1/PCINT9)
(PCINT20/XCK/T0) PD4 | 6****23| PC0 (ADC0/PCINT8)
VCC | 7****22| GND
GND | 8****21| AREF
(PCINT6/XTAL1/TOSC1) PB6 | 9****20| AVCC
(PCINT7/XTAL2/TOSC2) PB7 |10****19| PB5 (SCK/PCINT5)
(PCINT21/OC0B/T1) PD5 |11****18| PB4 (MISO/PCINT4)
(PCINT22/OC0A/AIN0) PD6 |12****17| PB3 (MOSI/OC2A/PCINT3)
(PCINT23/AIN1) PD7 |13****16| PB2 (SS/OC1B/PCINT2)
(PCINT0/CLKO/ICP1) PB0 |14****15| PB1 (OC1A/PCINT1)


PORTB7 ; 出力 ; H ; def
PORTB6 ; 出力 ; H ; def
PORTB5 ; 出力 ; H ; def
PORTB4 ; 出力 ; H ; def
PORTB3 ; 出力 ; H ; def
PORTB2 ; 出力 ; H ; +信号 ; dat_ch ; データ送信チャンネル
PORTB1 ; 出力 ; H ; +信号 ; cs_ch
PORTB0 ; 出力 ; H ; +信号 ; clk_ch

PORTC6 ; 入力 ; L ; -信号 ; RESET
PORTC5 ; 出力 ; H ; def
PORTC4 ; 出力 ; H ; def
PORTC3 ; 入力 ; L ; -信号 ; menu_sw
PORTC2 ; 入力 ; L ; -信号 ; select_sw
PORTC1 ; 入力 ; L ; -信号 ; back_s
PORTC0 ; 入力 ; ADC0 ; アクセル開度信号入力 ; accel_s

PORTD7 ; 出力 ; H ; seg_a
PORTD6 ; 出力 ; H ; seg_b
PORTD5 ; 出力 ; H ; seg_c
PORTD4 ; 出力 ; H ; seg_d
PORTD3 ; 出力 ; H ; seg_e
PORTD2 ; 出力 ; H ; seg_f
PORTD1 ; 出力 ; H ; seg_g
PORTD0 ; 出力 ; H ; status_LED



**************************************************************************************************

動作仕様
1.アクセル開度データを取得して変換し、モードテーブルを参照して出力する
2.任意変換モードは、ノーマル(N:0)、フラット(F:1)、スポーツ(S:2)、エコ(E:3)の4モードとする
3.後進はバックモードとする
4.設定値は、EEPROMに記憶させる
5.アクセル開度は、7セグにより逐次%表示(10桁のみ)する
6.フローはA/D変換→データ変換→D/A変換とする
7.D/A変換には、専用IC(MCP4822)を使用する


STATUS LEDの動作
点滅1・・・(2Hz)
点滅2・・・(10Hz)

*********************************************************************************************** */

#include (avr/io.h)
#include (avr/eeprom.h)


// PORTB
//#define def 7
//#define def 6
//#define def 5
//#define def 4
//#define def 3
#define dat_ch 2
#define cs_ch 1
#define clk_ch 0

// PORTC
//#define RESET 6
//#define def 5
//#define def 4
//#define menu_sw 3
//#define select_sw 2
//#define back_s 1
//#define accel_s 0

// PORTD
#define seg_a 7
#define seg_b 6
#define seg_c 5
#define seg_d 4
#define seg_e 3
#define seg_f 2
#define seg_g 1
#define status_LED 0




/*************************************************************************************************
******* グローバル宣言 */

uint8_t mode; // 0:Normal,1:Flat,2:Sports,3:Eco,4:Back
uint8_t mode_e __attribute__((section(".eeprom")));

uint8_t menu_stu; // 0:def 1:select 2:EEPROM_write&read
uint8_t adc; // A/D converter


// 7セグ表示用データ

uint8_t seg_dat[] = {
0b11111101, // 0
0b01100001, // 1
0b11011011, // 2
0b11110011, // 3
0b01100111, // 4
0b10110111, // 5
0b10111111, // 6
0b11100101, // 7
0b11111111, // 8
0b11110111, // 9
0b11111101, // 1O:Normal
0b10001111, // 11:Flat
0b10110111, // 12:Sports
0b10011111 // 13:Eco
};

// モード別テーブル
uint8_t kaido_dat[50];

// Normal モード ;0
uint8_t table_n[] __attribute__((section(".eeprom"))) ={
0,2,4,6,8,10,12,14,16,18,
20,22,24,26,28,30,32,34,36,38,
40,42,44,46,48,50,52,54,56,58,
60,62,64,66,68,70,72,74,76,78,
80,82,84,86,88,90,92,94,96,99
};

// Flat モード ;1
uint8_t table_f[] __attribute__((section(".eeprom"))) ={
0,2,4,6,8,10,12,14,16,18,
20,22,24,26,28,30,32,34,36,38,
40,42,44,46,48,50,52,54,56,58,
60,62,64,66,68,70,72,74,76,78,
80,82,84,86,88,90,92,94,96,99
};
// Sports モード;2
uint8_t table_s[] __attribute__((section(".eeprom"))) ={
0,2,4,6,8,10,12,14,16,18,
20,22,24,26,28,30,32,34,36,38,
40,42,44,46,48,50,52,54,56,58,
60,62,64,66,68,70,72,74,76,78,
80,82,84,86,88,90,92,94,96,99
};
// Eco モード;3
uint8_t table_e[] __attribute__((section(".eeprom"))) ={
0,2,4,6,8,10,12,14,16,18,
20,22,24,26,28,30,32,34,36,38,
40,42,44,46,48,50,52,54,56,58,
60,62,64,66,68,70,72,74,76,78,
80,82,84,86,88,90,92,94,96,99
};
// Back モード;4
uint8_t table_b[] ={
0,2,4,6,8,10,12,14,16,18,
20,22,24,26,28,30,32,34,36,38,
40,42,44,46,48,50,52,54,56,58,
60,62,64,66,68,70,72,74,76,78,
80,82,84,86,88,90,92,94,96,99
};


/*************************************************************************************************
******* プロトタイプ宣言 */

void init_io(void);
void init_adc(void);
void init_dat(void);

void wait_100us(uint16_t);

void table_in(void);
void menu(void);
void select(void);
int adc_convert(uint8_t);
void dac_out(uint16_t);
void seg_out(uint8_t);

/*************************************************************************************************
******* メイン */

int main(void){

// 初期化
init_io(); // I/O初期化
init_adc(); // A/Dコンバーター初期化
init_dat(); // データ初期化

PORTD |= _BV(status_LED); // LED点灯


// セッティング記録の読込み
eeprom_busy_wait(); // 読み書き可能になるまで待つ
mode = eeprom_read_byte(&mode_e); // EEPROMよりmodeデータを読出し
eeprom_busy_wait(); // 読み書き可能になるまで待つ
table_in(); // モードテーブルを選択格納
uint8_t i =0;
i = mode +10; // modeに+10の下駄をはかす
seg_out(i); // 選択モード表示
wait_100us(10000); // 1s待ち
wait_100us(10000); // 1s待ち 合計2s待ちオープニング

uint8_t x,x0; // 各SW変化検出用
x0 = PINC & 0b00001110; // 入力信号初期値を代入


// メインループ
while(1) {

// ステータスLED点滅(red)
PORTD ^= _BV(status_LED); // LEDを反転


// セッティング監査
x = PINC & 0b00001110; //
if (x != x0) {
if ((x & 0b00001000) != 0) {
menu();
}
if ((x & 0b00000100) != 0) {
select();
}
if ((x & 0b00000010) != 0) {
for(i=0;i<50;i++)
kaido_dat[i] = table_b[i]; // Back テーブルを格納
} else {
eeprom_busy_wait(); // 読み書き可能になるまで待つ
table_in(); // モードテーブルを選択格納
}
x0 = x; // 前回のスイッチ状況を反映
wait_100us(100); // 10ms待ち チャタリング防止用wait
}


// A/D 変換
adc = adc_convert(10); // ADC10からAD変換 512(例)

// データ変換
uint8_t accel_kaido =0;
accel_kaido = adc / 1023 / 2 * 100; // 50段階へ変換 25

// D/A変換用データ作成
uint8_t dac =0;
dac = kaido_dat[accel_kaido]; // パターン表を参照 50
uint16_t dac_ic_dat =0;
dac_ic_dat = dac * 41; // 2050

// D/A変換器へデータ送信
dac_out(dac_ic_dat); // 2050


// 7セグ表示
if (menu_stu != 0){
i =0;
i = mode + 10; // modeに+10の下駄をはかす
seg_out(i); // 選択モード表示
wait_100us(5000); // 500ms待ち LED点滅変更用wait
} else {
i =0;
i = dac / 10; // 表示用補正
seg_out(i); // アクセル開度表示 50
wait_100us(100); // 10ms待ち LED点滅変更用wait
}
}
}

/*************************************************************************************************
******* init_io I/O 初期化処理  */

void init_io(void){

DDRB = 0b11111111; // 全出力
PORTB = 0b01110000; // 0=all

PORTC = 0b01001110; // 6,3-1プルアップ
DDRC = 0b00110000; // 5-4出力

DDRD = 0b11111111; // 全出力
PORTD = 0b00000000; // 0=all

}

/*************************************************************************************************
******* init_adc A/Dコンバータ 初期化処理 */

void init_adc(void){

ADMUX = (1<<REFS0)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);
// 外部AVCC基準;データレジスタ右そろえ;ADC0;01 0 0 0000;
// 0<REFS1,1<REFS0,0<ADLAR,0<def,0<MUX3,0<MUX2,0<MUX1,0<MUX0

ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADPS1);
// A/D変換許可;1回目変換開始(調整);分周率1/4;1 1 0 0 0 010;
// 1<ADEN,1<ADSC,0<ADATE,0<ADIF,0<ADIE,0<ADPS2,1<ADPS1,0<ADPS0

ADCSRB = 0;
// 連続変換動作;0 0 000 000;
// 0<def,0<ACME,0<def,0<def,0<def,0<ADTS2,0<ADTS1,0<ADTS0
}

/*************************************************************************************************
******* init_dat 各種データ 初期化処理  */

void init_dat(void){

mode = 0; // Normal 初期値0
menu_stu = 0; //
adc = 0; //
}

/*************************************************************************************************
******* wait関数_100us */

void wait_100us(uint16_t time) { // 100us wait ルーチン。 クロック設定のこと。
// 25MHzでも 260ms までとれる。
time*=1; // 8MHzのとき。timeにF_CPU(MHz)をかける。重要!!

uint8_t lpcnt;
__asm__ __volatile__("\n"
"Entry%=: \n\t"
"ldi %0,24\n" // 計算値は25。24の方が実測値は良い。
"Loop%=: \n\t"
"nop\n\t"
"dec %0\n\t"
"brne Loop%=\n\t"
"sbiw %1,1\n\t"
"brne Entry%=\n\t"
:"=&a"(lpcnt)
:"w"(time)
);
return;
}

/*************************************************************************************************
******* テーブル格納 */

void table_in(void){
uint8_t i;

switch(mode){
case 0:for(i=0;i<50;i++){
eeprom_busy_wait();
kaido_dat[i] = eeprom_read_byte(&table_n[i]); // Normalテーブル格納
};
break;
case 1:for(i=0;i<50;i++){
eeprom_busy_wait();
kaido_dat[i] = eeprom_read_byte(&table_f[i]); // Flatテーブル格納
};
break;
case 2:for(i=0;i<50;i++){
eeprom_busy_wait();
kaido_dat[i] = eeprom_read_byte(&table_s[i]); // Sportsテーブル格納
}
break;
case 3:for(i=0;i<50;i++){
eeprom_busy_wait();
kaido_dat[i] = eeprom_read_byte(&table_e[i]); // Ecoテーブル格納
}
break;
default:mode = 0;
}
}

/*************************************************************************************************
******* menu */

void menu(void){
menu_stu++;
if (2 < menu_stu) {
menu_stu = 0;
}
if (menu_stu == 2){
eeprom_busy_wait(); // 読み書き可能になるまで待つ
eeprom_write_byte (&mode_e, mode); // EEPROMへmodeデータを書込み
menu_stu = 0;
eeprom_busy_wait(); // 読み書き可能になるまで待つ
table_in(); // モードテーブルを選択格納
}
}

/*************************************************************************************************
******* select */

void select(void){

if (menu_stu == 1){
mode++;
if (3 < mode) {
mode = 0;
}
}
}

/*************************************************************************************************
******* ピンを指定してAD変換 戻り値(return) 0-1023 */

int adc_convert(uint8_t pin){

ADMUX = pin; // AD変換入力ピン
ADCSRA &= ~_BV(ADIF); //
ADCSRA |= _BV(ADSC); // 変換開始
loop_until_bit_is_set(ADCSRA,ADIF); // 変換完了まで待つ
adc = ADCL; // 下位8bit取得
return adc += (ADCH<<8); // 上位2bit取得
}

/*************************************************************************************************
******* dac_out D/A変換器へデータ送信 */

void dac_out(uint16_t out) // D/A_out
{
uint8_t i = 0;

// 開始処理
PORTB = _BV(0 << clk_ch); // clock low
PORTB = _BV(0 << cs_ch); // CS on

// 以下4ビットがステータス設定ビット
// bit-1 // チャンネル設定ビット 0:chanel A 1:chanel B
// VoutA に出力
// PORTB = _BV(1 << dat_ch); // data high
PORTB = _BV(0 << dat_ch); // data low
PORTB = _BV(1 << clk_ch); // clock high
PORTB = _BV(0 << clk_ch); // clock low

// bit-2 // dummy;常時 1
PORTB = _BV(1 << dat_ch); // data high
// PORTB = _BV(0 << dat_ch); // data low
PORTB = _BV(1 << clk_ch); // clock high
PORTB = _BV(0 << clk_ch); // clock low

// bit-3 // ゲイン設定ビット 1:G=1, 0:G=2
// G = 2; V = Data/4096 * 2.048*2 [V]
// PORTB = _BV(1 << dat_ch); // data high
PORTB = _BV(0 << dat_ch); // data low
PORTB = _BV(1 << clk_ch); // clock high
PORTB = _BV(0 << clk_ch); // clock low

// bit-4 // シャットダウン設定ビット 1:出力イネイブル, 0:シャットダウン
// output enable
PORTB = _BV(1 << dat_ch); // data high
// PORTB = _BV(0 << dat_ch); // data low
PORTB = _BV(1 << clk_ch); // clock high
PORTB = _BV(0 << clk_ch); // clock low

// ここから、データビット

for(i=0; i<12; i++){ // 送信データをMSBから順次1ビットづつ合計12bit分を出力する
// outの第12bitをチェック 0なら0を1なら1を出力する
if ((out & 0b0000100000000000) != 0){ // 0000 1000 0000 0000;
PORTB = _BV(1 << dat_ch); // 12bit目が1ならdata highを出力
} else {
PORTB = _BV(0 << dat_ch); // 12bit目が0ならdata lowを出力
}
out = (out << 1); // 送信後1bitだけ左にビットシフト
PORTB = _BV(1 << clk_ch); // clock high
PORTB = _BV(0 << clk_ch); // clock low
}

// 終了処理
PORTB = _BV(1 << cs_ch); // CS off
}

/**************************************************************************************************
******* 7セグメント表示 */

void seg_out(uint8_t data) {
uint8_t j,x,y;

x = PORTD; // ポート状態データ取得
PORTD = (x & 0b00000001); // 7seg 表示クリア

x = PORTD; // ポート状態データ再取得
x = (x ^ 0b11111110); // bit0以外を反転マスク

j = data; // データ取得
y = seg_dat[j]; // 7segデータを展開

PORTD = (x & y); // 7segデータをポートへ出力

}

/*************************************************************************************************
******* END */

ブログ一覧 | MPV | 日記
Posted at 2008/11/29 12:51:23

イイね!0件



タグ

今、あなたにおすすめ

ブログ人気記事

美味しい季節の頂き物🍑
剣 舞さん

明日、手術決定しました😂
なつこの旦那さん

ある日のブランチ
パパンダさん

【美ヶ原と】雲と仲良し?な8月【八 ...
hinosさん

夏季休暇の締めくくり…夏のこの時期 ...
やっぴー7さん

みん友さんとお泊りデート🥰
ボッチninja400さん

この記事へのコメント

2008年11月29日 12:56
わっけわからんwww
出来そうですか?アクセル開度センサーから出力される電圧を弄ってやるんですよね
いまいちわかってませんが
コメントへの返答
2008年12月1日 11:18
そうです♪
アクセル開度センサーから出力されている電圧に下駄を履かせてやる制御になります♪

他にも応用できるかも・・・(^_^)ヾ
2008年11月29日 12:57
少佐・・・ボクの頭の回転速度を制御する回路はいつ完成するんですか?(笑)

いつまでたっても低速回転なんですけどっ!(爆)

あっ!たまに逆回転してるし(*▼ω▼)ぶっ
コメントへの返答
2008年12月1日 11:19
私も、風邪を引いて、頭がオーバーヒートぎみデあります・・・(^_^;)ヾ

くろぐろさんは、モニター全開仕様にて・・・(汗
2008年11月29日 13:04
凄い。
私もわかるようになったらいいな(^-^;)

押忍
コメントへの返答
2008年12月1日 11:20
ちょっとずつ勉強すれば、意外と簡単かも・・・♪

どうですか?
ご一緒に・・・(^_^;)ヾ
2008年11月29日 13:13
凄すぎです!!
メーカーを超える日が近そうな気が・・・。

今、ポチガーでお世話になってます。m(__)m
コメントへの返答
2008年12月1日 11:21
メーカーの真似は出来るのですが、アイデア創出は、難しいですねぇ~・・・(^_^;)ヾ

ポチガー見守っています♪
頑張ってくださ~い♪♪♪
2008年11月29日 15:06
はじめまして。
ずっとロムってました。

初期状態で開度データに書き込む値が各モードでどのように変化するのか楽しみにしています。

コメントへの返答
2008年12月1日 11:24
スイけんさん

どうもデあります・・・(^_^;)ヾ

開度データはテーブルにして、別データーとして保存する仕様にしてあります。このほうが後々色々弄れるので・・・(汗

エクセルのグラフも作成しましたので、こちらを見ていただくと、各モードの動きがわかると思います。

ところで、スイフトも電子スロットでしたら・・・いけるかも・・・(笑
2008年11月29日 15:46
呪文のような文章が沢山(?_?)☆

僕には未知の世界・・・(汗

完成したら製品化ですか???
コメントへの返答
2008年12月1日 11:25
とりあえず、既製品が数社から出回っていますので、今のところは、製品化する予定はありません。

知的探究心から、考えてみただけデあります・・・(^_^;)ヾ
2008年11月29日 18:23
 え・・・と。 外国のサイトに飛んじゃったかと思いました。

 少佐殿は一体どこまで逝ってしまうのでしょう・・・・
コメントへの返答
2008年12月1日 11:26
え~~~とですね。

最近は車弄りよりも・・・

ロボットでも作ってみようかと・・・(^_^;)ヾ
2008年11月30日 13:03
なるほど・・・
要するに・・・

あっ!!
寝てしまったであります!!
NAでも装着かのうでしょうか???
コメントへの返答
2008年12月1日 22:47
もちろんNAでも装着可能となります♪

ただし、魔法をかけたりして、ECUを書き換えていると難しいです。

むしろ、ノーマルの方が体感できる機能だと思うデあります…(^_^;)ヾ
2008年11月30日 18:03
はは~そうゆう制御なのですね~
ウンウン・・・・・・>―<〇バタッ
私の頭の中が制御不能(^^;
コメントへの返答
2008年12月1日 22:51
今回の、プログラム勉強の目標は、外部テーブルを参照するものにチャレンジしてみたデあります♪

だいたい感じがつかめましたので、今後はデーターの伝送や多連ユニットの開発をやってみようと思っています。

要約すると、自作のBCMユニットでしょうか。CAN通信と同等のことをして、各電子ユニット間にて、電子データを共有したいということです。
2008年12月1日 18:53
おぉっ、エクセルのテーブルが出来ていますね。
勉強させていただきます。どうも有難う御座いました。

スイスポは電スロですが、素イフトはワイヤースロットルなので残念ながら…。(^^;
コメントへの返答
2008年12月1日 22:45
そうだったんですか。
スイスポが電子スロットで、素イフトはワイヤーなんですね。

ならば、純正スイスポの電子スロットとアクセルセンサーを移植することが可能ですね♪

【フロー】
①アクセルセンサーが開度を電圧変化量として伝送

②電圧変化量に応じて電子スロットがスロットルバルブを制御

③電子スロットルに装備されているバルブ角度センサーがバルブ開度量を電圧としてECUに伝送

④ECUがフィードバック制御にて、燃料噴射量を適時制御

ワイヤー制御の場合でも、スロットルバルブ開度のフィードバック制御はしていますので、上記③ー④だけとなりますね。



プロフィール

「お仕事ちうデあります・・・(^_^)ヾ」
何シテル?   09/04 11:33
めぐりめぐって初マツダです。 皆さんよろしくお願いします。 お約束ですが、当ブログの内容を見て整備、修理して不具合が生じても、当プログ主は責任を負えませ...
みんカラ新規会員登録

ユーザー内検索

<< 2025/8 >>

     12
3456789
10111213141516
17181920212223
24252627282930
31      

愛車一覧

マツダ MPV マツダ MPV
家族の為にミニバンにしました。 新型MPVのあまりの出来に家族で 大満足です。 これ ...
ホンダ シビック ホンダ シビック
私に操る楽しさを教えてくれた車です。 VTECのハイカムに入ったときの 加速がたまりま ...
日産 スカイライン 日産 スカイライン
私に整備の楽しさを教えてくれた車です。 かなり高齢でしたが、まだまだ元気でした。 一 ...
その他 その他 その他 その他
ブログ用画像倉庫

過去のブログ

2009年
01月02月03月04月05月06月
07月08月09月10月11月12月
2008年
01月02月03月04月05月06月
07月08月09月10月11月12月
2007年
01月02月03月04月05月06月
07月08月09月10月11月12月
2006年
01月02月03月04月05月06月
07月08月09月10月11月12月
ヘルプ利用規約サイトマップ

あなたの愛車、今いくら?

複数社の査定額を比較して愛車の最高額を調べよう!

あなたの愛車、今いくら?
メーカー
モデル
年式
走行距離(km)
© LY Corporation