#include <Servo.h>
#include <Adafruit_NeoPixel.h>
#define SERVO_PIN_1 3
#define SERVO_PIN_2 5
#define ULTRASONIC_TRIGGER_PIN 12
#define ULTRASONIC_ECHO_PIN 11
#define NEOPIXEL_PIN 9
#define NUM_PIXELS 20
bool isReturning = false;
Servo servo1;
Servo servo2;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
enum UltrasonicState1 {
IDLE_1,
MOVE_SERVO1
};
enum UltrasonicState2 {
IDLE_2,
MOVE_SERVO2
};
UltrasonicState1 currentState1 = IDLE_1;
UltrasonicState2 currentState2 = IDLE_2;
int servo1Angle = 0;
unsigned long lastServoMoveMillis = 0;
unsigned long rainbowStartTime = 0;
bool rainbowTriggered = false;
// 函数原型声明
int measureDistance();
void setup() {
Serial.begin(9600);
pinMode(ULTRASONIC_TRIGGER_PIN, OUTPUT);
pinMode(ULTRASONIC_ECHO_PIN, INPUT);
strip.begin();
strip.show();
servo1.attach(SERVO_PIN_1);
servo1.write(0);
servo2.attach(SERVO_PIN_2);
servo2.write(0);
}
void loop() {
ultrasonicLoop();
}
void ultrasonicLoop() {
int distance = measureDistance();
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
// 控制第一个舵机
switch (currentState1) {
case IDLE_1:
if (distance < 20) {
currentState1 = MOVE_SERVO1;
servo1Angle = 0;
lightUpStrip();
} else {
turnOffStrip();
servo1.write(0);
currentState1 = IDLE_1;
}
break;
case MOVE_SERVO1:
if (millis() - lastServoMoveMillis > 1000) { // 减少时间间隔
if (servo1Angle < 180 && !isReturning) {
servo1.write(servo1Angle);
servo1Angle += 10; // 增加角度变化量
if (servo1Angle > 180) {
servo1Angle = 180; // 防止超过180度
}
} else {
isReturning = true;
servo1.write(servo1Angle);
servo1Angle -= 10; // 减少角度变化量
if (servo1Angle < 0) {
servo1Angle = 0; // 防止小于0度
isReturning = false;
}
}
lastServoMoveMillis = millis();
}
break;
}
if (distance >= 20) {
servo1.write(0);
currentState1 = IDLE_1;
}
// 控制第二个舵机
switch (currentState2) {
case IDLE_2:
if (distance < 5) {
currentState2 = MOVE_SERVO2;
servo2.write(90);
} else {
servo2.write(0);
currentState2 = IDLE_2;
}
break;
case MOVE_SERVO2:
if (distance > 9) {
servo2.write(0);
currentState2 = IDLE_2;
}
break;
}
// 当距离在20cm到25cm之间触发彩虹效果
if (distance >= 20 && distance <= 45) {
if (!rainbowTriggered) {
rainbowStartTime = millis();
rainbowTriggered = true;
}
rainbowEffect();
} else {
rainbowTriggered = false;
if (distance > 46) {
digitalWrite(5, LOW);
digitalWrite(3, LOW);
digitalWrite(9, LOW);
//servo1.write(0);
//servo2.write(0);
//turnOffStrip();
return; // 直接返回,不执行其他动作
}
}
}
void lightUpStrip() {
for (int i = 0; i < NUM_PIXELS; i++) {
strip.setPixelColor(i, strip.Color(255, 165, 0)); // 橙色
}
strip.show();
}
void turnOffStrip() {
for (int i = 0; i < NUM_PIXELS; i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
}
void rainbowEffect() {
if (millis() - rainbowStartTime < 5000) {
for (int j = 0; j < 256; j++) {
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i + j) & 255));
}
strip.show();
delay(20);
}
} else {
turnOffStrip();
}
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
int measureDistance() {
const int sampleSize = 5; // Number of samples to take
int readings[sampleSize]; // Array to store the readings
int sum = 0; // Sum of all valid readings
int validReadings = 0; // Number of valid readings
for (int i = 0; i < sampleSize; ++i) {
digitalWrite(ULTRASONIC_TRIGGER_PIN, LOW);
delayMicroseconds(2);
digitalWrite(ULTRASONIC_TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(ULTRASONIC_TRIGGER_PIN, LOW);
readings[i] = pulseIn(ULTRASONIC_ECHO_PIN, HIGH) * 0.034 / 2;
// Simple filter: only accept readings that are not 0
if (readings[i] != 0) {
sum += readings[i];
validReadings++;
}
delay(10); // Small delay to prevent echo interference
}
if (validReadings > 0) {
return sum / validReadings; // Return the average of valid readings
} else {
return -1; // Return an error value if no valid readings
}
}
Comments