/*
Forum:https://forum.arduino.cc/t/joystick-and-led/1201691
Wokwi:https://wokwi.com/projects/384628140447292417
*/
constexpr byte joystick_x = A0;
constexpr byte joystick_y = A1;
constexpr byte buttonPin = 12;
constexpr byte noOfLeds {5};
constexpr byte xAxisPins[noOfLeds] = {3, 4, 5, 6, 7};
constexpr byte yAxisPins[noOfLeds] = {8, 9, 5, 10, 11};
;
constexpr unsigned long INTERVAL {200}; // Every 200 ms (1/5 th of a second) update of the led cross
unsigned long lastUpdate = 0;
int valueX;
int valueY;
int ledX;
int ledY;
boolean blinking = false;
enum crossTypes {STANDARD, INTERLEVEL} crossType = STANDARD;
void setup()
{
pinMode(buttonPin, INPUT_PULLUP);
for (int i = 0; i < noOfLeds; i++ ) {
pinMode(xAxisPins[i], OUTPUT);
pinMode(yAxisPins[i], OUTPUT);
}
Serial.begin(9600);
}
void loop() {
if (millis() - lastUpdate > INTERVAL) {
lastUpdate = millis();
switch (crossType) {
case STANDARD: standardCross();
break;
case INTERLEVEL: interLevelCross();
break;
}
}
handleBlinking();
if (buttonPressed()){
switch(crossType){
case STANDARD: crossType = INTERLEVEL;
resetCross();
break;
case INTERLEVEL: crossType = STANDARD;
resetCross();
break;
}
}
}
void readJoystickMappedTo(byte mapTo) {
valueX = analogRead(A0);
valueY = analogRead(A1);
ledX = map(valueX, 0, 1024, 0, mapTo);
ledY = map(valueY, 0, 1024, 0, mapTo);
}
// *********************************************************
// Standard Cross
// *********************************************************
void standardCross() {
readJoystickMappedTo(noOfLeds);
for (int i = 0; i < noOfLeds; i++ ) {
if (i != 2) {
digitalWrite(xAxisPins[i], i == ledX ? HIGH : LOW);
digitalWrite(yAxisPins[i], i == ledY ? HIGH : LOW);
}
}
blinking = false;
byte mode = 0;
if (ledX == 2) {
mode++;
}
if (ledY == 2) {
mode++;
}
switch (mode) {
case 0 :
digitalWrite(xAxisPins[2], LOW);
break;
case 1 :
digitalWrite(xAxisPins[2], HIGH);
break;
case 2 :
blinking = true;
break;
}
}
void handleBlinking() {
static unsigned long lastBlink = 0;
if (!blinking) {
return;
}
if (millis() - lastBlink >= 500) {
lastBlink = millis();
byte state = digitalRead(xAxisPins[2]);
digitalWrite(xAxisPins[2], !state);
}
}
// *********************************************************
// interLevel Cross
// *********************************************************
void interLevelCross() {
constexpr byte noOfLevels {9};
readJoystickMappedTo(noOfLevels);
resetCross();
switchLeds();
}
void switchLeds() {
int8_t x0 = ledX / 2;
int8_t x1 = -1;
if (ledX & 1) {
x1 = x0 + 1;
}
int8_t y0 = ledY / 2;
int8_t y1 = -1;
if (ledY & 1) {
y1 = y0 + 1;
}
blinking = false;
byte mode = 0;
if (x0 == 2 || x1 == 2) {
mode++;
}
if (y0 == 2 || y1 == 2) {
mode++;
}
if (x0 != 2) {
digitalWrite(xAxisPins[x0], HIGH);
}
if (y0 != 2) {
digitalWrite(yAxisPins[y0], HIGH);
}
if (x1 >= 0 && x1 != 2) {
digitalWrite(xAxisPins[x1], HIGH);
}
if (y1 >= 0 && y1 != 2) {
digitalWrite(yAxisPins[y1], HIGH);
}
switch (mode) {
case 0:
break;
case 1 :
digitalWrite(xAxisPins[2], HIGH);
break;
case 2 :
blinking = true;
break;
}
}
void resetCross() {
for (int i = 0; i < noOfLeds; i++ ) {
digitalWrite(xAxisPins[i], LOW);
digitalWrite(yAxisPins[i], LOW);
}
}
boolean buttonPressed() {
static unsigned long lastChange = 0;
static byte state = HIGH;
static byte lastState = HIGH;
byte actState = digitalRead(buttonPin);
if (actState != lastState) {
lastChange = millis();
lastState = actState;
}
if (actState != state && millis() - lastChange > 20) {
state = actState;
return !state;
}
return false;
}
void printData() {
Serial.print("VRx : ");
Serial.print(valueX);
Serial.print(" ");
Serial.print("VRy : ");
Serial.println(valueY);
Serial.print("Led X : ");
Serial.print(ledX);
Serial.print(" ");
Serial.print("Led Y : ");
Serial.println(ledY);
}