ウィンカー信号 → Arduino → LEDテープ
目的 |
修理・故障・メンテナンス |
作業 |
DIY |
難易度 |
  中級 |
作業時間 |
3時間以内 |
1
今までサイドマーカーからドアミラーLEDテープに電源を供給しているだけでしたが、
2
マイコンボードで完全制御させるためサイドマーカー → マイコンボード → ドアミラーLEDテープに変更します。
3
サイドマーカーからマイコンボードの入力はツェナーダイオードを使おうとしましたが、車内の信号には以下のような問題があります
・ノイズ(点火系、モーター、CANなど)
・電圧変動(コールドクランキングで9Vまで落ちる)
・リレーなどによる逆起電力(スパイク)
オプトカプラを使うと下記のようなメリットがあるのでオプトカプラを使う手法にしました。
・電気的に信号を絶縁
・Arduino 側は5Vロジックで安全に信号を読み取れる
・トランジスタによるスイッチ動作でノイズ耐性UP
12V → 5V 4チャンネル オプトカプラ
https://amzn.asia/d/j3vdVY9 4
車載バッテリー12V → Arduino 5Vには
DC-DC 降圧コンバータ(8-32V → 5V 3A)を使いました。
Arduino UNOやNanoの消費電流はせいぜい50~150mA程度ですが、5V/3A の容量があるので、センサー・LED・通信モジュールなども一緒に動かせます
https://amzn.asia/d/42AM3NH 5
全体の配線
6
12V側の配線
7
5V側の配線
8
左右ボタンを押すと点滅するプログラム
9
#include <Adafruit_NeoPixel.h>
#define NUM_LEDS 36
// ウィンカー入力(オプトカプラ出力)
#define LEFT_SIGNAL_PIN 2
#define RIGHT_SIGNAL_PIN 3
// LEDデータピン(Arduino → WS2812B)
#define LEFT_LED_PIN 6
#define RIGHT_LED_PIN 7
// NeoPixelオブジェクト(LEDテープ用)
Adafruit_NeoPixel stripLeft = Adafruit_NeoPixel(NUM_LEDS, LEFT_LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripRight = Adafruit_NeoPixel(NUM_LEDS, RIGHT_LED_PIN, NEO_GRB + NEO_KHZ800);
// 点滅制御
bool blinkState = false;
unsigned long lastBlinkTime = 0;
const unsigned long blinkInterval = 300; // 点滅間隔(ms)
void setup() {
pinMode(LEFT_SIGNAL_PIN, INPUT);
pinMode(RIGHT_SIGNAL_PIN, INPUT);
stripLeft.begin();
stripRight.begin();
stripLeft.show(); // 初期化(すべてOFF)
stripRight.show();
}
void loop() {
bool leftOn = digitalRead(LEFT_SIGNAL_PIN) == LOW;
bool rightOn = digitalRead(RIGHT_SIGNAL_PIN) == LOW;
unsigned long currentTime = millis();
if (currentTime - lastBlinkTime >= blinkInterval) {
blinkState = !blinkState;
lastBlinkTime = currentTime;
}
if (leftOn) {
showBlink(stripLeft, blinkState, stripLeft.Color(255, 80, 0)); // オレンジ色
} else {
clearStrip(stripLeft);
}
if (rightOn) {
showBlink(stripRight, blinkState, stripRight.Color(255, 80, 0));
} else {
clearStrip(stripRight);
}
}
// 指定色で点滅表示
void showBlink(Adafruit_NeoPixel &strip, bool on, uint32_t color) {
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, on ? color : 0);
}
strip.show();
}
// OFF
void clearStrip(Adafruit_NeoPixel &strip) {
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, 0);
}
strip.show();
}
10
左右ボタンを押すとシーケンシャルするプログラム
11
#include <Adafruit_NeoPixel.h>
#define NUM_LEDS 36
#define LEFT_SIGNAL_PIN 2
#define RIGHT_SIGNAL_PIN 3
#define LEFT_LED_PIN 6
#define RIGHT_LED_PIN 7
Adafruit_NeoPixel stripLeft(NUM_LEDS, LEFT_LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripRight(NUM_LEDS, RIGHT_LED_PIN, NEO_GRB + NEO_KHZ800);
unsigned long lastUpdateLeft = 0;
unsigned long lastUpdateRight = 0;
int currentIndexLeft = -1;
int currentIndexRight = -1;
const unsigned long stepDelay = 30; // 30msごとに1個ずつ進む
const unsigned long offDelay = 100; // 全点灯後に消灯するまでの待ち時間
const uint32_t blinkerColor = stripLeft.Color(255, 80, 0); // オレンジ
void setup() {
pinMode(LEFT_SIGNAL_PIN, INPUT);
pinMode(RIGHT_SIGNAL_PIN, INPUT);
stripLeft.begin();
stripRight.begin();
stripLeft.show();
stripRight.show();
}
void loop() {
bool leftActive = digitalRead(LEFT_SIGNAL_PIN) == LOW;
bool rightActive = digitalRead(RIGHT_SIGNAL_PIN) == LOW;
if (leftActive) {
sequentialBlink(stripLeft, currentIndexLeft, lastUpdateLeft);
} else {
resetStrip(stripLeft, currentIndexLeft);
}
if (rightActive) {
sequentialBlink(stripRight, currentIndexRight, lastUpdateRight);
} else {
resetStrip(stripRight, currentIndexRight);
}
}
void sequentialBlink(Adafruit_NeoPixel &strip, int &index, unsigned long &lastUpdate) {
unsigned long now = millis();
if (index < NUM_LEDS) {
if (now - lastUpdate >= stepDelay) {
strip.setPixelColor(index, blinkerColor);
strip.show();
index++;
lastUpdate = now;
}
} else {
// 全点灯したあとの消灯待ち
if (now - lastUpdate >= offDelay) {
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, 0);
}
strip.show();
index = 0;
lastUpdate = now;
}
}
}
void resetStrip(Adafruit_NeoPixel &strip, int &index) {
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, 0);
}
strip.show();
index = 0;
}
[PR]Yahoo!ショッピング
タグ
関連コンテンツ( シーケンシャルウインカー の関連コンテンツ )
関連整備ピックアップ
関連リンク