#include <Servo.h> // サーボモータを動かすためのライブラリ
#define RED 3 // Arduino 3番ピン ➔ RGB LEDの赤(R)へ
#define GREEN 5 // Arduino 5番ピン ➔ RGB LEDの緑(G)へ
#define BLUE 6 // Arduino 6番ピン ➔ RGB LEDの青(B)へ
int latchPin = 11; // ラッチ入力
int clockPin = 7; // クロック入力
int dataPin = 12; // データ入力
int switchPin = 2; // タクトスイッチ入力(2番ピン)
// サーボモータの設定
Servo myServo;
int servoPin = 4; // サーボの信号線(4番ピン)
int lightState = 0; // 0なら赤、1なら青
int redValue;
int greenValue;
int blueValue;
void ShiftRegistar(byte value){
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, value);
digitalWrite(latchPin, HIGH);
}
void color(int r, int g, int b){
analogWrite(RED, r);
analogWrite(GREEN, g);
analogWrite(BLUE, b);
delay(10);
}
void turnOffRGB() {
color(0, 0, 0);
}
void setup(){
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(switchPin, INPUT_PULLUP);
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
// サーボモータを4番ピンに割り当てて、初期位置(0度)にする
myServo.attach(servoPin);
myServo.write(0);
Serial.begin(9600);
Serial.println("[信号機システム] 省電力・初期動作モードで起動しました。");
// 歩行者信号を赤(Q0)にする
ShiftRegistar(1 << 0);
lightState = 0;
// ★【ここを追加】電源が入った直後の最初の赤信号でもサーボを1回動かす
Serial.println("➔ 起動時のサーボチェック(90度 ➔ 0度 へ一度切り替え)");
myServo.write(90); delay(1000); // 90度に動かして1秒キープ
myServo.write(0); delay(1000); // 0度に戻して1秒キープ
}
void loop(){
// --- 【赤信号(待機中)のとき】 ---
if (lightState == 0) {
ShiftRegistar(1 << 0);
// ① 赤 ➔ 緑 へのグラデーション
redValue = 255; greenValue = 0; blueValue = 0;
for(int i = 0; i < 255; i += 1){
if (digitalRead(switchPin) == LOW) { lightState = 1; break; }
redValue -= 1;
greenValue += 1;
color(redValue, greenValue, blueValue);
}
// ② 緑 ➔ 青 へのグラデーション
if (lightState == 0) {
redValue = 0; greenValue = 255; blueValue = 0;
for(int i = 0; i < 255; i += 1){
if (digitalRead(switchPin) == LOW) { lightState = 1; break; }
greenValue -= 1;
blueValue += 1;
color(redValue, greenValue, blueValue);
}
}
// ③ 青 ➔ 赤 へのグラデーション
if (lightState == 0) {
redValue = 0; greenValue = 0; blueValue = 255;
for(int i = 0; i < 255; i += 1){
if (digitalRead(switchPin) == LOW) { lightState = 1; break; }
blueValue -= 1;
redValue += 1;
color(redValue, greenValue, blueValue);
}
}
// グラデーション中にボタンが押されていたら実行
if (lightState == 1) {
Serial.println("➔ ボタンが押されました。おまちください...");
// 1. ボタンが押されてから「1秒間」はRGB LEDを光らせたまま待つ
delay(1000);
// 2. 1秒たったら車側の信号を止める(RGB LEDをパッと消灯)
turnOffRGB();
// 3. 車が止まってから、さらに「2秒間」安全のために誰も進めない時間を作る
delay(2000);
}
}
// --- 【青信号のとき】 ---
if (lightState == 1) {
Serial.println("➔ 信号が青になりました。わたってください。");
// 通常の青信号(Q1)をON
ShiftRegistar(1 << 1);
delay(3000);
// 青の点滅(Q1をパチパチさせる)
for(int i = 0; i < 3; i++){
ShiftRegistar(0);
delay(300);
ShiftRegistar(1 << 1);
delay(300);
}
// 歩行者信号の点滅が終わったら、車側の赤信号(Q0)をパッと点灯させる
ShiftRegistar(1 << 0);
Serial.println("➔ 歩行者信号が赤になりました。車側もまだ赤信号です。");
// 赤信号の間に一度だけ90度に切り替えます
Serial.println("➔ サーボモータを作動します(90度 ➔ 0度 へ一度切り替え)");
myServo.write(90); delay(