hiro yamamoto works

マイコンハード、ソフトを作ったりしています。
お家や現場のお困りごと解決に!
内容利用は自己責任でお願いします。

タコメーターの回路をマイコンで置き換える(壊れる)

2023-09-24 16:26:43 | ナレッジ_knowledge

※残念なお知らせ※ サーキットを1周も出来ずに故障
アナログタコメータと並列接続で、ワーニングLEDのみ使う予定だったそうだが、<br />途中でエンジンストール 置き換え基板を切離したら<br />エンジンかかったそうです。ゴメンね

返品されたら故障箇所調べて投稿します。
このまま取り付けたわけではなく、ちゃんと防振防水対策してます。


タコメーターの回路をマイコンで置き換える(完了かと思う)

2023-09-15 13:49:23 | ナレッジ_knowledge

※日本精機製タコメータが動かない※
電解コンデンサのショート不良可能性あり。基板中央付近の円筒形470μF6.3Vを、
テスタ抵抗レンジで数Ωなら可能性高いので交換してみて。

※残念なお知らせ※ サーキットを1周も出来ずに故障
アナログタコメータと並列接続で、ワーニングLEDのみ使う予定だったそうだが、<br />途中でエンジンストール 置き換え基板を切離したら<br />エンジンかかったそうです。ゴメンね
返品されたら故障箇所調べて投稿します。

ショート不良の電解コンデンサを交換し、振動によるダメージ軽減のため
部品同士をホットボンドで接着してケースに戻す。
※後日追記※
Vz=5.6Vツェナーダイオードとジャンパーピンを追加

下の写真 置き換え基板の仕上げ 3端子レギュレータと電解コンデンサをホットボンドで固定。
配線引き出し

下の写真 実装状態 マイコンの下にもレイアウトしてる。

下の写真 実装状態 マイコンの下にもレイアウトしてる。

下の写真 基板裏の配線 ショートしないように隣接配線間はちゃんと間隔空いてますのでご心配なく。
※ワーニングLEDの配線が回路図と違っていることについて 追記※
回路図では+3.3V共通にして、抵抗を通ってLEDのアノードへ、
カソードからマイコンの端子へ接続するようになっていますが
組み立て品はGND(マイナス)を共通にしてLEDのカソードへ、
アノードから抵抗を通ってマイコンの端子へ接続しています。
これは+3.3V配線がGNDとショートした時、
マイコン搭載のレギュレータを破壊しないようにするためです。
ポリスイッチなどの保護素子は入っていませんので、ショートすれば間違いなく破壊します。

下の写真 緑ワーニングMid LED 12,000rpm以上で点滅

下の写真 13,000rpm以上でワーニングMid 赤LED点滅(緑も一緒に点滅) 

実機搭載テストは未だ
ちゃんと動いてね、頼むよ

気になる方もいるのでは・・・基板サイズの比較は下の図
オリジナル基板より小さく出来ております。

※後日追記※
実機テストにて動かない可能性に備えて
Vz=5.6Vのツェナーダイオードとジャンパーピンを追加しました。
(基板上はVz=12V品を取り付けています。)
ホトカプラの駆動電圧不足で動かない時に、ジャンパーピン挿し替えで並列接続され、
問題解決できる予定です。(たぶん大丈夫かと・・・)


タコメーターの回路をマイコンで置き換える(関係資料スケッチ)終

2023-09-13 16:50:32 | ナレッジ_knowledge

※日本精機製タコメータが動かない※
電解コンデンサのショート不良可能性あり。基板中央付近の円筒形470μF6.3Vを、
テスタ抵抗レンジで数Ωなら可能性高いので交換してみて。<br /><br />私のスキルではこの程度のコードしか書けません。
ワーニングMid,Hi LEDのデジタル入出力接続の説明を書き足しました。

/*202308 アナログタコメーターが動かなくなった相談を受ける。
  マイクロコントローラでメーター基板の置き換えをするべく着手
  イグニッションパルスのたち下がり間隔の時間を計測しエンジン回転数を算出
  アナログタコメータをanalogWrite(PWM)で振らせる
  ①map関数で変換する・・・回転数と目盛りが合わない
  ②回転数ごとにif文でPWM値を割り当てる
  ワーニング(設定回転数を超えたことをLED表示)を表示できるようにする。
  Mid 12,000rpm Hi 13,000rpmを仮に設定
ワーニングLEDの接続
Mid,Hi共に LEDアノードを3V3(3.3V)、カソードをMidは9へ、Hiは10へデジタル入出力に接続
*/

uint32_t warningMidPrevious = 0;
uint32_t warningHiPrevious = 0;

//デバック用
//1回転2パルス 計算上 2142uS->≒14005rpm 2100uS->≒14286rpm
//const long interval = 2142;//pulseWidth/2 uS interval at which to blink (milliseconds)

uint32_t pulseTime, lastTime;

//uint16_t rpm_h = 14000;//map関数使用時
//uint16_t rpm_l = 4500;//800
//const uint8_t PWM_full = 255;
//const uint8_t PWM_emp = 0;

uint32_t pulseWidth = 0;
uint32_t tacho_PWM = 0;
uint32_t rpm = 0;

bool warningMidLedState = HIGH;
bool warningHiLedState = HIGH;
uint16_t warningMid_rpm = 12000;
uint16_t warningHi_rpm = 13000;
uint32_t count = 0;
uint32_t lastCount = 0;
uint32_t reset_pre_t = 0;//previous time

void setup() {
  Serial.begin(115200);
  //while(!Serial);
  //pinMode(ledPin, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(9, OUTPUT); //warning Mid Led
  pinMode(10, OUTPUT); //warning Hi Led

  //interrupt attached to IRQ 1 = pin3(Arduino UNO)
  //0はXIAO SAMD21デジタル入出力D0
  attachInterrupt(0, cycleTimeToRPM, FALLING);//digital input D1 XIAO RP2040

  digitalWrite(9, HIGH);//ワーニングMid表示 LEDを消しておくため
  digitalWrite(10, HIGH);//ワーニングHi表示 LED
}
/*割り込み
  Seeed Studio XIAO SAMD21のすべてのピンは割り込みをサポートしていますが、
  5ピンと7ピンの2つのピンを同時に使用することはできません。*/
  
void loop() {

  //ワーニング表示LED
//ワーニングMid,Hi共に LEDアノードを3V3(3.3V)、カソードをMidは9へ、Hiは10へデジタル入出力に接続
  if (rpm >= warningMid_rpm) {//warningMid_rpm
    uint32_t warningMidCurrent = millis();
    if (warningMidCurrent - warningMidPrevious >= 100) { //点滅用
      warningMidPrevious = warningMidCurrent;
      if (warningMidLedState == LOW) {
        warningMidLedState = HIGH;
      } else {
        warningMidLedState = LOW;
      }
      digitalWrite(9, warningMidLedState);
    }
  } else {
    digitalWrite(9, HIGH);
  }
  if (rpm >= warningHi_rpm) {//warningHi_rpm
    uint32_t current = millis();
    if (current - warningHiPrevious >= 100) { //点滅用
      warningHiPrevious = current;
      if (warningHiLedState == LOW) {
        warningHiLedState = HIGH;
      } else {
        warningHiLedState = LOW;
      }
      digitalWrite(10, warningHiLedState);
    }
  } else {
    digitalWrite(10, HIGH);
  }
  //D0へ入力されるパルスが止まった時tacho_PWM値が止まる直前の値のままになる
  //ワーニングも点滅したままになる
  //Detects rotation stoppage and resets meters and warnings by
  //comparing counter changes in external interrupt functions at regular intervals
  //外部割り込み関数のカウンタ変化を一定間隔で比較することで、
  //回転停止を検出してメーターとワーニングをリセットする

  //uint32_t reset_pre_t = 0;//previous time
  uint32_t reset_cur_t = millis();
  if (reset_cur_t - reset_pre_t >= 100) { //パルス停止をチェックする間隔
    reset_pre_t = reset_cur_t;
    if (count == lastCount) { //外部割り込み発生するたびにインクリメントされるカウンタの、
      //前回値と今回値が同じ時はパルス停止と判断してPWM値を0にしてメータを0へ戻す。
      //rpmを0にしてワーニングLEDを消す。
      tacho_PWM = 0;
      analogWrite(6, tacho_PWM);
      rpm = 0;
    }
    lastCount = count;
  }
}

//Engine RPM from cycle time.イグニッションパルスが入力され、外部割り込み発生で実行される関数
void cycleTimeToRPM() {
  count++;//パルス停止の検出に使うカウンタ
  //used to measure time between pulses.
  lastTime = pulseTime;
  pulseTime = micros();//マイクロ秒

  //uint32_t pulseWidth = 0; //uint32_t tacho_PWM = 0; //uint32_t rpm = 0;
  pulseWidth = pulseTime - lastTime;
  rpm = (60 * 1000000) / pulseWidth;//60秒をマイクロ秒に直して 回転数を算出する
  rpm /= 2; // エンジン種類により1回転2パルスの時使う
  //T(Sec)=60/N(rpm)
  //60/pulseWidth(Sec)=N(rpm)
  
  //map関数を使う場合の説明
  //map関数を使ってパルス幅数値をanalogWrite用数値(PWM)変換する
  //PWM波のデューティ比を変えることで出力電圧を変化させ、メーターの振れ角を変える
  //12V 直列(100Ω,680Ω並列)87.2Ωメーター並列470uFにてanalogWrite値255でフルスケ
  //12,000rpm超え表示域(特に13,000以上)で上下を繰り返すと指示値が500ぐらいばらつく
  //uint16_t rpm_h = 14000;//uint16_t rpm_l = 4500;//800

  /*if ((rpm > rpm_l) && (rpm < rpm_h)) { //map変換前にrpmをrpm_l〜rpm_hの範囲に制限する
    //map関数構文 map(value, fromLow, fromHigh, toLow, toHigh); // すべてlong型
    tacho_PWM = map(rpm, rpm_l, rpm_h, PWM_emp, PWM_full);//回転数(RPM)をPWM値に変換する
    } else if (rpm <= rpm_l) {
    tacho_PWM = 17;
    } else if (rpm >= rpm_h) {
    tacho_PWM = 255;
    }*/
  //2,500〜4,000 500rpm step  4,000〜10,000 200rpm step
  //10,000〜14,000rpm 100rpm step
  if (rpm >= 14000) tacho_PWM = 255;//回転数ごとにメーター指示値をPWM値で調整
  else if (rpm >= 13900 && rpm < 14000) tacho_PWM = 253;//100rpm step
  else if (rpm >= 13800 && rpm < 13900) tacho_PWM = 250; 
  else if (rpm >= 13700 && rpm < 13800) tacho_PWM = 246;
  else if (rpm >= 13600 && rpm < 13700) tacho_PWM = 242;
  else if (rpm >= 13500 && rpm < 13600) tacho_PWM = 238;
  else if (rpm >= 13400 && rpm < 13500) tacho_PWM = 234;
  else if (rpm >= 13300 && rpm < 13400) tacho_PWM = 231;
  else if (rpm >= 13200 && rpm < 13300) tacho_PWM = 225;
  else if (rpm >= 13100 && rpm < 13200) tacho_PWM = 221;
  else if (rpm >= 13000 && rpm < 13100) tacho_PWM = 218;
  else if (rpm >= 12900 && rpm < 13000) tacho_PWM = 215;
  else if (rpm >= 12800 && rpm < 12900) tacho_PWM = 212;
  else if (rpm >= 12700 && rpm < 12800) tacho_PWM = 208;
  else if (rpm >= 12600 && rpm < 12700) tacho_PWM = 206;
  else if (rpm >= 12500 && rpm < 12600) tacho_PWM = 204;
  else if (rpm >= 12400 && rpm < 12500) tacho_PWM = 201;
  else if (rpm >= 12300 && rpm < 12400) tacho_PWM = 199;
  else if (rpm >= 12200 && rpm < 12300) tacho_PWM = 196;
  else if (rpm >= 12100 && rpm < 12200) tacho_PWM = 193;
  else if (rpm >= 12000 && rpm < 12100) tacho_PWM = 191;
  else if (rpm >= 11900 && rpm < 12000) tacho_PWM = 188;
  else if (rpm >= 11800 && rpm < 11900) tacho_PWM = 185;
  else if (rpm >= 11700 && rpm < 11800) tacho_PWM = 183;
  else if (rpm >= 11600 && rpm < 11700) tacho_PWM = 181;
  else if (rpm >= 11500 && rpm < 11600) tacho_PWM = 177;
  else if (rpm >= 11400 && rpm < 11500) tacho_PWM = 175;
  else if (rpm >= 11300 && rpm < 11400) tacho_PWM = 172;
  else if (rpm >= 11200 && rpm < 11300) tacho_PWM = 169;
  else if (rpm >= 11100 && rpm < 11200) tacho_PWM = 167;
  else if (rpm >= 11000 && rpm < 11100) tacho_PWM = 165;
  else if (rpm >= 10900 && rpm < 11000) tacho_PWM = 162;
  else if (rpm >= 10800 && rpm < 10900) tacho_PWM = 160;
  else if (rpm >= 10700 && rpm < 10800) tacho_PWM = 158;
  else if (rpm >= 10600 && rpm < 10700) tacho_PWM = 156;
  else if (rpm >= 10500 && rpm < 10600) tacho_PWM = 153;
  else if (rpm >= 10400 && rpm < 10500) tacho_PWM = 151;
  else if (rpm >= 10300 && rpm < 10400) tacho_PWM = 149;
  else if (rpm >= 10200 && rpm < 10300) tacho_PWM = 147;
  else if (rpm >= 10100 && rpm < 10200) tacho_PWM = 145;
  else if (rpm >= 10000 && rpm < 10100) tacho_PWM = 143; //100rpm step
  else if (rpm >= 9800 && rpm < 10000) tacho_PWM = 137;//200rpm step
  else if (rpm >= 9600 && rpm < 9800) tacho_PWM = 132;
  else if (rpm >= 9400 && rpm < 9600) tacho_PWM = 128;
  else if (rpm >= 9200 && rpm < 9400) tacho_PWM = 124;
  else if (rpm >= 9000 && rpm < 9200) tacho_PWM = 122;
  else if (rpm >= 8800 && rpm < 9000) tacho_PWM = 118;
  else if (rpm >= 8600 && rpm < 8800) tacho_PWM = 114;
  else if (rpm >= 8400 && rpm < 8600) tacho_PWM = 110;
  else if (rpm >= 8200 && rpm < 8400) tacho_PWM = 106;
  else if (rpm >= 8000 && rpm < 8200) tacho_PWM = 102;
  else if (rpm >= 7800 && rpm < 8000) tacho_PWM = 99;
  else if (rpm >= 7600 && rpm < 7800) tacho_PWM = 95;
  else if (rpm >= 7400 && rpm < 7600) tacho_PWM = 92;
  else if (rpm >= 7200 && rpm < 7400) tacho_PWM = 88;
  else if (rpm >= 7000 && rpm < 7200) tacho_PWM = 85;
  else if (rpm >= 6800 && rpm < 7000) tacho_PWM = 82;
  else if (rpm >= 6600 && rpm < 6800) tacho_PWM = 79;
  else if (rpm >= 6400 && rpm < 6600) tacho_PWM = 75;
  else if (rpm >= 6200 && rpm < 6400) tacho_PWM = 72;
  else if (rpm >= 6000 && rpm < 6200) tacho_PWM = 69;
  else if (rpm >= 5800 && rpm < 6000) tacho_PWM = 66;
  else if (rpm >= 5600 && rpm < 5800) tacho_PWM = 63;
  else if (rpm >= 5400 && rpm < 5600) tacho_PWM = 61;
  else if (rpm >= 5200 && rpm < 5400) tacho_PWM = 58;
  else if (rpm >= 5000 && rpm < 5200) tacho_PWM = 55;
  else if (rpm >= 4800 && rpm < 5000) tacho_PWM = 52;
  else if (rpm >= 4600 && rpm < 4800) tacho_PWM = 50;
  else if (rpm >= 4400 && rpm < 4600) tacho_PWM = 47;
  else if (rpm >= 4200 && rpm < 4400) tacho_PWM = 45;
  else if (rpm >= 4000 && rpm < 4200) tacho_PWM = 42;
  else if (rpm >= 3500 && rpm < 4000) tacho_PWM = 37;//500rpm step
  else if (rpm >= 3000 && rpm < 3500) tacho_PWM = 33;
  else if (rpm >= 2500 && rpm < 3000) tacho_PWM = 26;
  else if (rpm < 2500) tacho_PWM = 18;

  analogWrite(6, tacho_PWM);
  Serial.print(pulseWidth); // デバック 計測したパルス幅
  Serial.print(" , "); // デバック
  Serial.print(tacho_PWM); // デバック PWM値
  Serial.print(" , "); // デバック
  Serial.println(rpm); // デバック 回転数
  
}

 


タコメーターの回路をマイコンで置き換える(関係資料その2)

2023-09-13 13:45:14 | ナレッジ_knowledge

※日本精機製タコメータが動かない※
電解コンデンサのショート不良可能性あり。基板中央付近の円筒形470μF6.3Vを、
テスタ抵抗レンジで数Ωなら可能性高いので交換してみて。

ユニバーサル基板上の部品レイアウト
配線は部品面からの透視図です。
マイコンXIAO SAMD21は必要端子だけにピンヘッダを取り付けます。
6箇所 D0,D6,D7,5V0(5V),GND,3V3(3.3V)
5V0から出ている茶色線は、AWG24程度の被覆電線もしくは、φ0.5程度の
メッキ線に絶縁チューブをかぶせて接続して下さい。

ユニバーサル基板上の部品レイアウト(重なって見えにくいところ)


基板 秋月電子 両面スルーホール ユニバーサル基板[AE-E-TH][P-12725]1枚 ¥25(税込)
部品は前に投稿した手書き回路図に書いてあると思いますが・・・
端子説明
DC12V
GND
M+ メータープラス(M+、M−間に470μF16Vの電解コンデンサを接続)
M− メーターマイナス
IGN イグニッションパルス
D9 回転数ワーニングMID(抵抗とLEDを接続すれば設定回転数以上で点滅)
D10 回転数ワーニングHI(抵抗とLEDを接続すれば設定回転数以上で点滅)
※D9、D10のLEDはマイコン端子に接続して下さい。<br />※追記※<br />ワーニングLEDの抵抗取り付けは、マイコン端子D9,D10から<br />ユニバーサル基板の間へ(垂直に)取り付けると良いと思います。<br />抵抗値は220Ωにしてみました。

スケッチは次の投稿で紹介します。


タコメーターの回路をマイコンで置き換える(関係資料その1)

2023-09-13 13:37:20 | ナレッジ_knowledge

※日本精機製タコメータが動かない※
電解コンデンサのショート不良可能性あり。基板中央付近の円筒形470μF6.3Vを、
テスタ抵抗レンジで数Ωなら可能性高いので交換してみて。<br /><br />簡易CDIイグニッションパルス発生&入力回路
ホトカプラ:TLP371
ダイオード:1N4148(何でも使えるかと思う)

パルス発生用Arduinoスケッチ
スケッチ例BlinkWithoutDelayを改変しました。

ざっくり説明
ArduinoUNO用
シリアルターミナルからパルス幅設定数値をマイクロ秒単位で入力してEnterまたは送信をクリックすると
シリアルモニタにパルス幅(μS)と回転数(rpm)を表示して、デジタル9にパルスを出力します。
10000(μS)を入力すると3,000(rpm)4285(μS)で≒14,002(rpm)
もちろん誤差あります。

スケッチ
const int ledPin = 9 ;
int ledState = LOW;
unsigned long previousMillis = 0;
int sensorValue = 0;
int outputValue = 0;
void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);

void loop() {
  if (Serial.available()) {
    String Received_value;
    Received_value = Serial.readStringUntil('\n');//終端文字'\n'検出まで読み文字列全体を変数へ
    outputValue = Received_value.toInt();
    Serial.print(outputValue);
    Serial.print(" , ");
    uint32_t rpm;
    rpm = ((60 * 1000000) / outputValue)/2 ;
    Serial.println(rpm);
  }
  unsigned long currentMillis = micros();
  if (currentMillis - previousMillis >= (outputValue / 2)) {
    previousMillis = currentMillis;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    if (ledState == HIGH) {
      PORTB |= _BV(1);//D9-PB1 D8
    } else {
      PORTB &= ~_BV(1);//D9-PB1 D8
    }
    //digitalWrite(ledPin, ledState);
  }
}