// Forum: https://forum.arduino.cc/t/sevsegshift-issues-with-other-functions/1247100
// This Wokwi project: https://wokwi.com/projects/395093421051239425
//
// 13 April 2024
// Changed the pins for the Uno.
// The two delay(100) should be removed.
// Somehow the usage of the JSON library crashes the sketch.
//
// 14 April 2024
// Changed the baudrate from 9600 to 115200.
// The real project uses a Pro Micro (which ignores the baudrate).
//


#include <ArduinoJson.h>
#include <SevSegShift.h>

// Clock pins
#define SHIFT_PIN_DS   13 // 10
#define SHIFT_PIN_STCP 12 // 16
#define SHIFT_PIN_SHCP 11 // 14

SevSegShift sevseg(SHIFT_PIN_DS, SHIFT_PIN_SHCP, SHIFT_PIN_STCP);  // Instantiate a seven segment controller object

// Joystick pins
#define JOYSTICK_PIN_VRX 18
#define JOYSTICK_PIN_VRY 19
#define JOYSTICK_PIN_SW 20

// Buzzer pin
#define BUZZER_PIN 6

// JSON document size
#define JSON_DOCUMENT_SIZE 256

void setup() {
  // Initialization logic
  Serial.begin(115200); // 9600
  while (!Serial) continue;

  // Clock setup logic
  byte numDigits = 4;
  byte digitPins[] = { 8 + 2, 8 + 5, 8 + 6, 2 };                // of ShiftRegister(s) | 8+x (2nd Register)
  byte segmentPins[] = { 8 + 3, 8 + 7, 4, 6, 7, 8 + 4, 3, 5 };  // of Shiftregister(s) | 8+x (2nd Register)
  bool resistorsOnSegments = false;                             // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_CATHODE;                         // See README.md for options
  bool updateWithDelays = false;                                // Default 'false' is Recommended
  bool leadingZeros = false;                                    // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = false;                                 // Use 'true' if your decimal point doesn't exist or isn't connected

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
               updateWithDelays, leadingZeros, disableDecPoint);
  sevseg.setBrightness(90);
}

void loop() {
  sendingJsonData(); // Send joystick data
  updateClock();      // Update clock display
  receiveJsonData(); // Receive JSON data if available
}



void updateClock() {
  static unsigned long timer = millis();
  static int deciSeconds = 10000;

  if (millis() - timer >= 100) {
    timer += 100;
    deciSeconds--;  // 100 milliseconds is equal to 1 deciSecond

    if (deciSeconds == 0) {  // Reset to 0 after counting for 1000 seconds.
      deciSeconds = 10000;
    }
    sevseg.setNumber(deciSeconds, 1);
  }

  sevseg.refreshDisplay();  // Must run repeatedly
}

void sendingJsonData() {
  delay(100);
  int sensorValueX = map(analogRead(JOYSTICK_PIN_VRX), 0, 1022, 0, 100);
  int sensorValueY = 100 - map(analogRead(JOYSTICK_PIN_VRY), 0, 1022, 0, 100);
  int sensorValueSwitch = analogRead(JOYSTICK_PIN_SW);

  // JSON sending logic
  DynamicJsonDocument doc(JSON_DOCUMENT_SIZE);
  doc["sensor"] = "joystick";
  doc["data"][0] = sensorValueX;
  doc["data"][1] = sensorValueY;
  doc["data"][2] = sensorValueSwitch != 0 ? 0 : 1;
  serializeJson(doc, Serial);
  Serial.println();
}

void receiveJsonData() {
  delay(100);
  if (Serial.available() > 0) {
    String s = Serial.readStringUntil('\n');
    StaticJsonDocument<JSON_DOCUMENT_SIZE> doc;
    DeserializationError error = deserializeJson(doc, s);
    if (error) {
      logSerial("JSON parse failed");
      return;
    }
    // Handle parsed JSON data here according to your requirements
  }
}

void logSerial(const char* message) {
  StaticJsonDocument<JSON_DOCUMENT_SIZE> doc;
  doc["sensor"] = "message";
  doc["data"] = message;
  serializeJson(doc, Serial);
  Serial.println();
}
74HC595
74HC595