/********* Baseball game output device test using OLED, servo and Neopixels. Servo code based on ESP32Servo Sweep Example by Rui Santos & Sara Santos - Random Nerd Tutorials Complete project details at https://RandomNerdTutorials.com/esp32-servo-motor-web-server-arduino-ide/ *********/ #include #include #include #include #include static const int servoPin = D3; Servo servo1; #define LED_PIN D6 // Which pin is connected to the NeoPixels? #define LED_COUNT 30 // How many NeoPixels are attached to the Arduino? #define LED_COUNT_START 15 // Which is the first Neopixel to light up? // Declare NeoPixel strip object: Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); #define SCREEN_WIDTH 128 // OLED width, in pixels #define SCREEN_HEIGHT 64 // OLED height, in pixels int BASEBALL_SCORE = 0; int NEOPIXEL_BRIGHTNESS = 2; // the first brightness, gets brighter with each shot int SERVO_ANGLE = 40; // "Travel angles: from 40deg to 360deg" // create an OLED display object connected to I2C Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); void setup() { Serial.begin(9600); servo1.attach(servoPin); delay(200); servo1.write(SERVO_ANGLE); strip.setBrightness(0); // Set BRIGHTNESS to about 1/5 (max = 255) strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) strip.clear(); // Clears pixel color buffer (sets all to 0) strip.show(); // Turn OFF all pixels strip.setBrightness(NEOPIXEL_BRIGHTNESS); // initialize OLED display with I2C address 0x3C if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("failed to start SSD1306 OLED")); while (1); } delay(2000); // wait two seconds for initializing oled.clearDisplay(); // clear display oled.setTextSize(3); // set text size, increased to 3 oled.setTextColor(WHITE); // set text color oled.setCursor(0, 2); // set position to display (x,y) oled.println("score: " + String(BASEBALL_SCORE)); oled.display(); // display on OLED while (!Serial); // Wait for Serial to be ready (especially important for XIAO ESP32-C3) Serial.println("Ready! Press Enter."); } void loop() { if (Serial.available()) { char c = Serial.read(); // Detect Enter (newline or carriage return) if (c == '\n' || c == '\r') { BASEBALL_SCORE++; // Only increment angle if it's < 50 if (SERVO_ANGLE < 130) { SERVO_ANGLE = SERVO_ANGLE + 3; } updateScore(BASEBALL_SCORE); // Neopixel lights up white briefly, then fades down to red: colorWipe(strip.Color(255, 255, 255), 0); // White delay(5); colorWipe(strip.Color(255, 255, 0), 0); // Yellow delay(10); colorWipe(strip.Color(255, 128, 0), 0); // Orange delay(10); colorWipe(strip.Color(255, 0, 0), 0); // Red delay(20); colorWipe(strip.Color(50, 0, 0), 0); // Dark red delay(40); strip.clear(); // Clears pixel color buffer (sets all to 0) strip.show(); // Sends the cleared data to the strip (turns off LEDs) SERVO_ANGLE = constrain(SERVO_ANGLE, 40, 130); // "CS939-MG travel angles: from 40deg to 360deg" servo1.write(SERVO_ANGLE); if (NEOPIXEL_BRIGHTNESS < 50) { NEOPIXEL_BRIGHTNESS++; // gets brighter with each shot strip.setBrightness(NEOPIXEL_BRIGHTNESS); } strip.clear(); strip.show(); } } } void colorWipe(uint32_t color, int wait) { for (int i = LED_COUNT_START; i < strip.numPixels(); i++) { // For each pixel in strip... strip.setPixelColor(i, color); // Set pixel's color (in RAM) strip.show(); // Update strip to match delay(wait); // Pause for a moment } } void updateScore(int score) { oled.clearDisplay(); // clear display oled.setTextSize(3); // set text size, increased to 3 oled.setTextColor(WHITE); // set text color oled.setCursor(0, 2); // set position to display (x,y) oled.println("score: " + String(score)); oled.display(); // display on OLED }