<commit_before>/*
 * KloC Arduino Controller
 * Copyright (C) 2017  TheSilkMiner
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Contact information:
 * E-mail: thesilkminer <at> outlook <dot> com
 */
bool BeginSerialCommunication();
void CheckButtonForMode();
void DeferModeCall();
void HandleClock();
void HandleTimer();
void HandleSerial();
void CheckForWakeUpCall();

void Setup() {
  Serial.begin(RATE_SPEED);
  ledStrip.begin();
  ledStrip.clear();
  ledStrip.show();
  Display::colors[0] = ledStrip.Color(255, 128, 0);
  Display::colors[1] = ledStrip.Color(255, 0, 128);
  Display::colors[2] = ledStrip.Color(255, 255, 255);
  while (!Serial);
  firstModeLed.TurnOn();
  secondModeLed.TurnOn();
  if (BeginSerialCommunication()) {
    for (auto i = 0; i < 3; ++i ) {
      firstModeLed.TurnOff();
      secondModeLed.TurnOff();
      delay(100);
      firstModeLed.TurnOn();
      secondModeLed.TurnOn();
      delay(100); 
    }
  } else {
    for (auto i = 0; i < 3; ++i) {
      firstModeLed.TurnOff();
      secondModeLed.TurnOff();
      delay(100);
      firstModeLed.TurnOn();
      delay(100);
      secondModeLed.TurnOn();
      delay(150);
      firstModeLed.TurnOff();
      delay(100);
    }
  }
  firstModeLed.TurnOff();
  secondModeLed.TurnOff();
  delay(300);
  Mode::CycleModeAndUpdateLeds(&currentMode, firstModeLed, secondModeLed);
}

bool BeginSerialCommunication() {
  Serial.println(":SYN");
  auto counter = 0;
  auto estabilished = false;
  while (true) {
    if (estabilished || counter >= 30) {
      if (!estabilished) Serial.println(":CONNECTION>FAILED");
      break; // Wait half a minute maximum, then break out and wait for a SYN/ACK request from the Java controller.
    }
    if (Serial.available() > 0) {
      while(true) {
        byte in = '\0';
        while (in != '`') {
          in = Serial.read();
          if (in == 0xFF) continue; 
        }
        String call = Serial.readStringUntil(';');
        if (!String("ACK").equals(call)) continue;
        Serial.println(":CONNECTION>ESTABILISHED");
        estabilished = true;
        break;
      }
    }
    ++counter;
    delay(1000); // Wait one second after every call
  }
  SerialPort::hasSerial = estabilished;
  return estabilished;
}

void Loop() {
  CheckButtonForMode();
  DeferModeCall();
}

void CheckButtonForMode() {
  static long int toggleDelay = 0;
  if (toggleDelay > 0) {
    --toggleDelay;
    return;
  }
  if (modeSwitchButton) {
    Mode::CycleModeAndUpdateLeds(&currentMode, firstModeLed, secondModeLed);
    ledStrip.clear();
    ledStrip.show();
    toggleDelay = 100000L;
  }
}

void DeferModeCall() {
  switch(currentMode) {
    case Mode::CLOCK:
      HandleClock();
      break;
    case Mode::TIMER:
      HandleTimer();
      break;
    case Mode::SERIAL:
      HandleSerial();
      break;
    case Mode::STANDBY:
    default:
      CheckForWakeUpCall();
  }
}

void CheckForWakeUpCall() {
  if (!SerialPort::CanCommunicateWithSerial()) return;
  if (Serial.available() > 0) {
    while(true) {
      byte in = '\0';
      while (in != '`') {
        in = Serial.read();
        if (in == 0xFF) continue; 
      }
      String call = Serial.readStringUntil(';');
      if (!String("WAKEUP").equals(call)) continue;
      Serial.println(":WOKEN");
      Mode::CycleMode(&currentMode);
      Mode::SwitchModeToLed(currentMode, firstModeLed, secondModeLed);
      break;
    }
  }
}
<commit_msg>Allow mode to be changed through serial port<commit_after>/*
 * KloC Arduino Controller
 * Copyright (C) 2017  TheSilkMiner
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Contact information:
 * E-mail: thesilkminer <at> outlook <dot> com
 */
bool BeginSerialCommunication();
void CheckButtonForMode();
void CheckSerialForMode();
void DeferModeCall();
void HandleClock();
void HandleTimer();
void HandleSerial();
void CheckForWakeUpCall();

void Setup() {
  Serial.begin(RATE_SPEED);
  ledStrip.begin();
  ledStrip.clear();
  ledStrip.show();
  Display::colors[0] = ledStrip.Color(255, 128, 0);
  Display::colors[1] = ledStrip.Color(255, 0, 128);
  Display::colors[2] = ledStrip.Color(255, 255, 255);
  while (!Serial);
  firstModeLed.TurnOn();
  secondModeLed.TurnOn();
  if (BeginSerialCommunication()) {
    for (auto i = 0; i < 3; ++i ) {
      firstModeLed.TurnOff();
      secondModeLed.TurnOff();
      delay(100);
      firstModeLed.TurnOn();
      secondModeLed.TurnOn();
      delay(100); 
    }
  } else {
    for (auto i = 0; i < 3; ++i) {
      firstModeLed.TurnOff();
      secondModeLed.TurnOff();
      delay(100);
      firstModeLed.TurnOn();
      delay(100);
      secondModeLed.TurnOn();
      delay(150);
      firstModeLed.TurnOff();
      delay(100);
    }
  }
  firstModeLed.TurnOff();
  secondModeLed.TurnOff();
  delay(300);
  Mode::CycleModeAndUpdateLeds(&currentMode, firstModeLed, secondModeLed);
}

bool BeginSerialCommunication() {
  Serial.println(":SYN");
  auto counter = 0;
  auto estabilished = false;
  while (true) {
    if (estabilished || counter >= 30) {
      if (!estabilished) Serial.println(":CONNECTION>FAILED");
      break; // Wait half a minute maximum, then break out and wait for a SYN/ACK request from the Java controller.
    }
    if (Serial.available() > 0) {
      while(true) {
        byte in = '\0';
        while (in != '`') {
          in = Serial.read();
          if (in == 0xFF) continue; 
        }
        String call = Serial.readStringUntil(';');
        if (!String("ACK").equals(call)) continue;
        Serial.println(":CONNECTION>ESTABILISHED");
        estabilished = true;
        break;
      }
    }
    ++counter;
    delay(1000); // Wait one second after every call
  }
  SerialPort::hasSerial = estabilished;
  return estabilished;
}

void Loop() {
  CheckButtonForMode();
  CheckSerialForMode();
  DeferModeCall();
}

void CheckButtonForMode() {
  static long int toggleDelay = 0;
  if (toggleDelay > 0) {
    --toggleDelay;
    return;
  }
  if (modeSwitchButton) {
    Mode::CycleModeAndUpdateLeds(&currentMode, firstModeLed, secondModeLed);
    ledStrip.clear();
    ledStrip.show();
    toggleDelay = 100000L;
  }
}

void CheckSerialForMode() {
  if (!SerialPort::CanCommunicateWithSerial()) return;
  if (currentMode == Mode::STANDBY) return;
  if (Serial.available() <= 0) return;
  while(true) {
      byte in = '\0';
      while (in != '`') {
        in = Serial.read();
        if (in == 0xFF) continue; 
      }
      String call = Serial.readStringUntil('>');
      if (!String("MODE").equals(call)) continue;
      call = Serial.readStringUntil(';');
      auto newMode = String("CLOCK").equals(call)? Mode::CLOCK : String("TIMER").equals(call)? Mode::TIMER : String("SERIAL").equals(call)? Mode::SERIAL : Mode::STANDBY;
      while (currentMode != newMode) {
        Mode::CycleModeAndUpdateLeds(&currentMode, firstModeLed, secondModeLed);
      }
      break;
    }
}

void DeferModeCall() {
  switch(currentMode) {
    case Mode::CLOCK:
      HandleClock();
      break;
    case Mode::TIMER:
      HandleTimer();
      break;
    case Mode::SERIAL:
      HandleSerial();
      break;
    case Mode::STANDBY:
    default:
      CheckForWakeUpCall();
  }
}

void CheckForWakeUpCall() {
  if (!SerialPort::CanCommunicateWithSerial()) return;
  if (Serial.available() > 0) {
    while(true) {
      byte in = '\0';
      while (in != '`') {
        in = Serial.read();
        if (in == 0xFF) continue; 
      }
      String call = Serial.readStringUntil(';');
      if (!String("WAKEUP").equals(call)) continue;
      Serial.println(":WOKEN");
      Mode::CycleModeAndUpdateLeds(&currentMode, firstModeLed, secondModeLed);
      break;
    }
  }
}

{'fraction_non_alphanumeric': 0.1356558754340764, 'fraction_numerical': 0.017587095328777867, 'mean_word_length': 3.0841720036596523, 'pattern_counts': {'":': 8, '<': 14, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3624556', 'n_tokens_mistral': 2965, 'n_tokens_neox': 2818, 'n_words': 742}