This circuit is designed to interface an Arduino Nano with various peripherals including a joystick module, a rotary encoder, an OLED display, and multiple LEDs with corresponding resistors. The circuit allows for user interaction through the joystick and rotary encoder, with visual feedback provided by the LEDs and the OLED display. The Arduino Nano serves as the central processing unit, running embedded code to manage input devices and control outputs based on user actions.
#include <U8g2lib.h>
// Rotary Encoder Pins
#define ENCODER_CLK 6
#define ENCODER_DT 7
#define ENCODER_SW 8
// Joystick Pins
#define JOYSTICK_VRX A0
#define JOYSTICK_VRY A1
#define JOYSTICK_SW 4
// LED Pins
#define RED_LED_PIN 5
#define YELLOW_LED_PIN 11
#define BLUE_LED_PIN 12
#define GREEN_LED_PIN 10
// OLED display settings
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
// Variables for rotary encoder
int lastClk = HIGH;
int lastDt = HIGH;
int currentBrightness = 128; // Initial brightness (0-255)
bool isBlinking = false;
bool isLEDOn = true; // Variable to track LED on/off state
unsigned long lastBlinkTime = 0;
const unsigned long blinkInterval = 500; // 500ms interval for blinking
// Array of LED pins
const int ledPins[] = {RED_LED_PIN, YELLOW_LED_PIN, BLUE_LED_PIN, GREEN_LED_PIN};
const char* colorNames[] = {"Red", "Yellow", "Blue", "Green"};
// Dead zone threshold for joystick
const int deadZone = 100;
// Constants for debounce delay and dead zone
const int debounceDelay = 50;
const int joystickDelay = 200;
const int blinkToggleDelay = 500;
const int joystickCenter = 512;
// Variable to keep track of the current LED color
int currentColor = 0; // Initial color (0: Red, 1: Yellow, 2: Blue, 3: Green)
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Initialize OLED display
u8g2.begin();
// Initialize rotary encoder pins
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_SW, INPUT_PULLUP);
// Initialize joystick pins
pinMode(JOYSTICK_SW, INPUT_PULLUP);
// Initialize LED pins
for (int i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT);
analogWrite(ledPins[i], 0);
}
// Display initial brightness
updateDisplay();
}
void loop() {
// Read the rotary encoder
int clkState = digitalRead(ENCODER_CLK);
int dtState = digitalRead(ENCODER_DT);
if (clkState == LOW && lastClk == HIGH) {
if (dtState == HIGH) {
currentBrightness = min(currentBrightness + 10, 255); // Increase brightness
} else {
currentBrightness = max(currentBrightness - 10, 0); // Decrease brightness
}
Serial.print("Brightness: ");
Serial.println(currentBrightness);
updateDisplay();
}
lastClk = clkState;
// Check if the rotary encoder button is pressed
if (isButtonPressed(ENCODER_SW)) {
isLEDOn = !isLEDOn;
Serial.print("LED: ");
Serial.println(isLEDOn ? "On" : "Off");
updateDisplay();
delay(blinkToggleDelay); // Prevent multiple toggles
}
// Read the joystick
int vrxValue = analogRead(JOYSTICK_VRX);
int vryValue = analogRead(JOYSTICK_VRY);
// Map joystick X-axis to change color with dead zone
if (vrxValue < (joystickCenter - deadZone)) {
currentColor = (currentColor - 1 + 4) % 4;
Serial.print("Color: ");
Serial.println(colorNames[currentColor]);
updateDisplay();
delay(joystickDelay); // Delay to prevent rapid changes
} else if (vrxValue > (joystickCenter + deadZone)) {
currentColor = (currentColor + 1) % 4;
Serial.print("Color: ");
Serial.println(colorNames[currentColor]);
updateDisplay();
delay(joystickDelay); // Delay to prevent rapid changes
}
// Map joystick Y-axis to toggle blinking mode with dead zone
if (vryValue < (joystickCenter - deadZone) || vryValue > (joystickCenter + deadZone)) {
isBlinking = !isBlinking;
Serial.print("Mode: ");
Serial.println(isBlinking ? "Blinking" : "Solid");
updateDisplay();
delay(blinkToggleDelay); // Delay to prevent rapid toggles
}
// Check if the joystick button is pressed
if (isButtonPressed(JOYSTICK_SW)) {
isBlinking = !isBlinking;
Serial.println("Joystick button pressed. Toggling blinking mode.");
Serial.print("isBlinking: ");
Serial.println(isBlinking);
updateDisplay();
delay(blinkToggleDelay); // Prevent multiple toggles
}
// Update LED state
updateLEDs();
}
void updateDisplay() {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_5x8_tr); // Use a smaller font to fit more text
// Column 1
u8g2.setCursor(0, 8);
u8g2.print("Brightness:");
u8g2.setCursor(0, 18);
u8g2.print(currentBrightness);
u8g2.setCursor(0, 28);
u8g2.print("Mode:");
u8g2.setCursor(0, 38);
u8g2.print(isBlinking ? "Blinking" : "Solid");
// Column 2
u8g2.setCursor(64, 8);
u8g2.print("Color:");
u8g2.setCursor(64, 18);
u8g2.print(colorNames[currentColor]);
u8g2.setCursor(64, 28);
u8g2.print("LED:");
u8g2.setCursor(64, 38);
u8g2.print(isLEDOn ? "On" : "Off");
u8g2.sendBuffer();
}
void updateLEDs() {
unsigned long currentTime = millis();
bool ledState = true;
if (isBlinking) {
if (currentTime - lastBlinkTime >= blinkInterval) {
lastBlinkTime = currentTime;
ledState = !digitalRead(ledPins[currentColor]);
} else {
ledState = digitalRead(led