/* * FSRemotePowerSwitch * * Allows to control an Arduino to power up a device. * * A send over cmd from a PC will set a digital pin to high, which * switches relay to close a 230V AC circuit. * * */ #include "Arduino.h" #include #include #include #include #include const char *Version = "V1.3.0"; const String CMD_VER = "Version"; const String CMD_SENDER_PC = "FSRemotePowerSwitch_PC"; const String CMD_SENDER_AN = "FSRemotePowerSwitch_AN"; const String CMD_POWER_RELAY = "Power_Relay"; const String CMD_STATUS_RELAY = "Status_Relay"; const String CMD_POWER_CAM = "Power_Cam"; const String CMD_STATUS_CAM = "Status_Cam"; const String CMD_AZIMUT_CAM = "Azimut_Cam"; const String CMD_ACT_AZIMUT_CAM = "Actual_Azimut_Cam"; const String CMD_ZERO_CAM = "Zero_Cam"; const String CMD_VELOCITY_CAM = "Velocity_Cam"; const String CMD_STATUS_VELOCITY_CAM = "Status_Velocity_Cam"; const String CMD_VELOCITY_SLOW = "Slow"; const String CMD_VELOCITY_FAST = "Fast"; const String CMD_VAL_ON = "On"; const String CMD_VAL_OFF = "Off"; const int PWR_RELAY_PIN = 5; const int PWR_CAM_PIN = 6; const int eepromAddrStatusRelay = 100; const int eepromAddrStatusCam = 200; const int eepromAddrStatusCamVel = 300; const int eepromAddrActAzimut = 400; JsonDocument msg; String stepperVelocity; int actAzimut; // Define motor interface type #define motorInterfaceType AccelStepper::MotorInterfaceType::HALF4WIRE // Creates an instance AccelStepper stepper(motorInterfaceType, 8, 10, 9, 11); // The setup function runs once when you press reset or power the board void setup() { Serial.begin(9600); pinMode(PWR_RELAY_PIN, OUTPUT); pinMode(PWR_CAM_PIN, OUTPUT); int velocity = EEPROM.read(eepromAddrStatusCamVel); if (velocity == 0) { setSlowStepperVelocity(); // Slow: Acc: 200 / Slow: MaxSpeed: 500 } else { setFastStepperVelocity(); // Fast: Acc: 500 / Fast: MaxSpeed: 1000 } int powerRel = EEPROM.read(eepromAddrStatusRelay); if (powerRel == 0) { digitalWrite(PWR_RELAY_PIN, LOW); } else { digitalWrite(PWR_RELAY_PIN, HIGH); } int camRel = EEPROM.read(eepromAddrStatusCam); if (powerRel == 0) { digitalWrite(PWR_CAM_PIN, LOW); } else { digitalWrite(PWR_CAM_PIN, HIGH); } actAzimut = EEPROM.read(eepromAddrActAzimut); if (actAzimut > 180) { actAzimut = 0; } stepper.setCurrentPosition(round((4076.0 / 360.0) * ((double) actAzimut) * -1)); } /* The loop function runs over and and checks the serial port for receiving a Json of following format: * * JSON for FSRemotePowerSwitch * * { * "Sender": "FSRemotePowerSwitch_PC" or "FSRemotePowerSwitch_AN", * "Cmd": "Version" or "Status_Relay" or "Power_Relay" or "Status_Cam" or "Power_Cam" or "Azimut_Cam" or "Zero_Cam", * "Val": "V0.0.1" or "On"/"Off" or "0" * } * */ void loop() { if (Serial.available() > 0) { moveStepper(); String message = readSerialData(); // Deserialize the JSON document DeserializationError error = deserializeJson(msg, message); // Test if parsing succeeds. if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.print(message); Serial.println(error.f_str()); return; } message = ""; String sdr = msg["Sender"]; String cmd = msg["Cmd"]; String val = msg["Val"]; if (sdr == CMD_SENDER_PC && cmd == CMD_VER) { sendVersion(); } else if (sdr == CMD_SENDER_PC && cmd == CMD_POWER_RELAY) { if (val == CMD_VAL_ON) { digitalWrite(PWR_RELAY_PIN, LOW); } else if (val == CMD_VAL_OFF) { digitalWrite(PWR_RELAY_PIN, HIGH); } if (digitalRead(PWR_RELAY_PIN) == LOW) { moveStepper(); sendRelayPowerStatus(CMD_VAL_ON); EEPROM.write(eepromAddrStatusRelay, 0); } else { moveStepper(); sendRelayPowerStatus(CMD_VAL_OFF); EEPROM.write(eepromAddrStatusRelay, 1); } } else if (sdr == CMD_SENDER_PC && cmd == CMD_STATUS_RELAY) { if (digitalRead(PWR_RELAY_PIN) == LOW) { moveStepper(); sendRelayPowerStatus(CMD_VAL_ON); } else { moveStepper(); sendRelayPowerStatus(CMD_VAL_OFF); } } else if (sdr == CMD_SENDER_PC && cmd == CMD_POWER_CAM) { if (val == CMD_VAL_ON) { digitalWrite(PWR_CAM_PIN, LOW); stepper.move(10); moveStepper(); } else if (val == CMD_VAL_OFF) { moveStepper(); digitalWrite(PWR_CAM_PIN, HIGH); } if (digitalRead(PWR_CAM_PIN) == LOW) { moveStepper(); sendCamPowerStatus(CMD_VAL_ON); EEPROM.write(eepromAddrStatusCam, 0); } else { moveStepper(); sendCamPowerStatus(CMD_VAL_OFF); EEPROM.write(eepromAddrStatusCam, 1); } } else if (sdr == CMD_SENDER_PC && cmd == CMD_STATUS_CAM) { if (digitalRead(PWR_CAM_PIN) == LOW) { moveStepper(); sendCamPowerStatus(CMD_VAL_ON); } else { moveStepper(); sendCamPowerStatus(CMD_VAL_OFF); } } else if (sdr == CMD_SENDER_PC && cmd == CMD_VELOCITY_CAM) { if (val.equals(CMD_VELOCITY_FAST)) { setFastStepperVelocity(); } else if (val.equals(CMD_VELOCITY_SLOW)) { setSlowStepperVelocity(); } sendCamVelocityStatus(); } else if (sdr == CMD_SENDER_PC && cmd == CMD_STATUS_VELOCITY_CAM) { sendCamVelocityStatus(); } else if (sdr == CMD_SENDER_PC && cmd == CMD_ZERO_CAM) { stepper.setCurrentPosition(0); sendZeroCamStatus(String(stepper.currentPosition())); EEPROM.write(eepromAddrActAzimut, 0); } else if (sdr == CMD_SENDER_PC && cmd == CMD_ACT_AZIMUT_CAM) { int actAzi = round(stepper.currentPosition() / (4076.0 / 360.0) * -1); sendCamActAzimut(String(actAzi)); } else if (sdr == CMD_SENDER_PC && cmd == CMD_AZIMUT_CAM) { if (digitalRead(PWR_CAM_PIN) == LOW) { long target = round((4076.0 / 360.0) * val.toDouble() * -1); stepper.moveTo(target); stepper.run(); EEPROM.write(eepromAddrActAzimut, val.toInt()); } } } moveStepper(); } void moveStepper() { if (stepper.distanceToGo() != 0) { // Move the motor one step stepper.run(); } } String readSerialData() { String msg = ""; String data = ""; while (Serial.available() > 0) { data = Serial.readString(); msg += data; //delay(50); } return msg; } void setFastStepperVelocity() { stepperVelocity = CMD_VELOCITY_FAST; stepper.setCurrentPosition(stepper.currentPosition()); stepper.setMaxSpeed(1000); // Slow: 500 / Fast: 1000 stepper.setAcceleration(500); // Slow: 200 / Fast: 500 stepper.setSpeed(1000); EEPROM.write(eepromAddrStatusCamVel, 1); } void setSlowStepperVelocity() { stepperVelocity = CMD_VELOCITY_SLOW; stepper.setCurrentPosition(stepper.currentPosition()); stepper.setMaxSpeed(500); // Slow: 500 / Fast: 1000 stepper.setAcceleration(200); // Slow: 200 / Fast: 500 stepper.setSpeed(500); EEPROM.write(eepromAddrStatusCamVel, 0); } void sendVersion() { msg["Sender"] = CMD_SENDER_AN; msg["Cmd"] = CMD_VER; msg["Val"] = Version; serializeJson(msg, Serial); } void sendRelayPowerStatus(String status) { msg["Sender"] = CMD_SENDER_AN; msg["Cmd"] = CMD_STATUS_RELAY; msg["Val"] = status; serializeJson(msg, Serial); } void sendCamPowerStatus(String status) { msg["Sender"] = CMD_SENDER_AN; msg["Cmd"] = CMD_STATUS_CAM; msg["Val"] = status; serializeJson(msg, Serial); } void sendZeroCamStatus(String val) { msg["Sender"] = CMD_SENDER_AN; msg["Cmd"] = CMD_ZERO_CAM; msg["Val"] = val; serializeJson(msg, Serial); } void sendCamActAzimut(String val) { msg["Sender"] = CMD_SENDER_AN; msg["Cmd"] = CMD_ACT_AZIMUT_CAM; msg["Val"] = val; serializeJson(msg, Serial); } void sendCamVelocityStatus() { msg["Sender"] = CMD_SENDER_AN; msg["Cmd"] = CMD_STATUS_VELOCITY_CAM; msg["Val"] = stepperVelocity; serializeJson(msg, Serial); }