|
@@ -0,0 +1,328 @@
|
|
|
+// FlipFlat based on the Altinak Flip-Flat commands. Makes it possible to use it with ASCOM and INDI drivers
|
|
|
+
|
|
|
+// Enable DEBUG in FlipFlat.h to see logging.
|
|
|
+// Due to driver imitations in de indi driver, when using ESP32 Serial can't be used for FlipFlat communication.
|
|
|
+// Use Serial 2 (pins 16 and 17) instead. Standard Serial is used for debug messages
|
|
|
+
|
|
|
+#include <FlipFlat.h>
|
|
|
+
|
|
|
+int deviceId = FLIP_FLAT; // set this to FLAT_MAN if you want to remove or not use the motor handling
|
|
|
+int motorStatus = STOPPED;
|
|
|
+int lightStatus = OFF;
|
|
|
+int coverStatus = CLOSED;
|
|
|
+int motorDirection = NONE;
|
|
|
+float currentAngle = 0.0;
|
|
|
+
|
|
|
+int brightness = 0;
|
|
|
+
|
|
|
+EasyButton brightness_plus(BRIGHT_PLUS);
|
|
|
+EasyButton brightness_min(BRIGHT_MIN);
|
|
|
+EasyButton cover_control(COVER_FF);
|
|
|
+
|
|
|
+AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
|
|
|
+
|
|
|
+void setup()
|
|
|
+{
|
|
|
+ setupSerial();
|
|
|
+
|
|
|
+ LOG("Debug mode");
|
|
|
+ LOG("Starting FlipFlat");
|
|
|
+ LOG("Setup PWM pin");
|
|
|
+
|
|
|
+ pinMode(PWM, OUTPUT);
|
|
|
+
|
|
|
+ LOG("Setup brightness buttons");
|
|
|
+
|
|
|
+ brightness_plus.begin();
|
|
|
+ brightness_plus.onPressed(increaseBrightness);
|
|
|
+ brightness_min.begin();
|
|
|
+ brightness_min.onPressed(decreaseBrightness);
|
|
|
+
|
|
|
+ LOG("Setup open-close button");
|
|
|
+
|
|
|
+ cover_control.begin();
|
|
|
+ cover_control.onPressed(handleCoverSwitch);
|
|
|
+
|
|
|
+ LOG("Initializing stepper");
|
|
|
+
|
|
|
+ stepper.setMaxSpeed(1000);
|
|
|
+ stepper.setAcceleration(50);
|
|
|
+ stepper.setSpeed(200);
|
|
|
+ stepper.moveTo(STEPS);
|
|
|
+}
|
|
|
+
|
|
|
+void loop()
|
|
|
+{
|
|
|
+ brightness_plus.read();
|
|
|
+ brightness_min.read();
|
|
|
+ cover_control.read();
|
|
|
+
|
|
|
+ if (FF_SERIAL.available() > 0) // all incoming communications are fixed length at 6 bytes including the \r
|
|
|
+ {
|
|
|
+ LOG("Command received");
|
|
|
+ parseCommand();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void increaseBrightness()
|
|
|
+{
|
|
|
+ LOG("Brightness+ is pressed");
|
|
|
+
|
|
|
+ brightness++;
|
|
|
+
|
|
|
+ setBrightness(brightness);
|
|
|
+}
|
|
|
+
|
|
|
+void decreaseBrightness()
|
|
|
+{
|
|
|
+ LOG("Brightness- is pressed");
|
|
|
+
|
|
|
+ brightness--;
|
|
|
+
|
|
|
+ setBrightness(brightness);
|
|
|
+}
|
|
|
+
|
|
|
+void setBrightness(int newBrightness)
|
|
|
+{
|
|
|
+ LOG1("Setting brightness to ", newBrightness);
|
|
|
+
|
|
|
+ analogWrite(PWM, newBrightness);
|
|
|
+}
|
|
|
+
|
|
|
+void parseCommand()
|
|
|
+{
|
|
|
+ LOG("Parse command");
|
|
|
+
|
|
|
+ char *cmd;
|
|
|
+ char *data;
|
|
|
+
|
|
|
+ char str[20];
|
|
|
+ memset(str, 0, 20);
|
|
|
+
|
|
|
+ FF_SERIAL.readBytesUntil('\n', str, 20);
|
|
|
+
|
|
|
+ cmd = str + 1;
|
|
|
+ data = str + 2;
|
|
|
+
|
|
|
+ // useful for debugging to make sure your commands came through and are parsed correctly.
|
|
|
+ LOG1("cmd = ", cmd);
|
|
|
+ LOG1("data = ", data);
|
|
|
+
|
|
|
+ processCommand(cmd, data);
|
|
|
+
|
|
|
+ while (FF_SERIAL.available() > 0)
|
|
|
+ FF_SERIAL.read();
|
|
|
+}
|
|
|
+
|
|
|
+void processCommand(const char *cmd, const char *data)
|
|
|
+{
|
|
|
+ switch (*cmd)
|
|
|
+ {
|
|
|
+ /*
|
|
|
+ Ping device
|
|
|
+ Request: >POOO\r
|
|
|
+ Return : *PiiOOO\n
|
|
|
+ ii = DEVICE_ID
|
|
|
+ */
|
|
|
+ case 'P':
|
|
|
+ LOG("Ping received");
|
|
|
+ FF_SERIAL << F("*P") << deviceId << F("OOO\n");
|
|
|
+ break;
|
|
|
+
|
|
|
+ /*
|
|
|
+ Open shutter
|
|
|
+ Request: >OOOO\r
|
|
|
+ Return : *OiiOOO\n
|
|
|
+ ii = deviceId
|
|
|
+ This command is only supported on the Flip-Flat!
|
|
|
+ */
|
|
|
+ case 'O':
|
|
|
+ LOG("Open received");
|
|
|
+ FF_SERIAL << F("*O") << deviceId << F("OOO\n");
|
|
|
+ openFlipFlat();
|
|
|
+ break;
|
|
|
+
|
|
|
+ /*
|
|
|
+ Close shutter
|
|
|
+ Request: >COOO\r
|
|
|
+ Return : *CiiOOO\n
|
|
|
+ ii = deviceId
|
|
|
+ This command is only supported on the Flip-Flat!
|
|
|
+ */
|
|
|
+ case 'C':
|
|
|
+ LOG("Close received");
|
|
|
+ FF_SERIAL << F("*C") << deviceId << F("OOO\n");
|
|
|
+ closeFlipFlat();
|
|
|
+ break;
|
|
|
+
|
|
|
+ /*
|
|
|
+ Turn light on
|
|
|
+ Request: >LOOO\r
|
|
|
+ Return : *LiiOOO\n
|
|
|
+ ii = deviceId
|
|
|
+ */
|
|
|
+ case 'L':
|
|
|
+ LOG("Turn on received");
|
|
|
+ FF_SERIAL << F("*L") << deviceId << F("OOO\n");
|
|
|
+ lightStatus = ON;
|
|
|
+ setBrightness(brightness);
|
|
|
+ break;
|
|
|
+
|
|
|
+ /*
|
|
|
+ Turn light off
|
|
|
+ Request: >DOOO\r
|
|
|
+ Return : *DiiOOO\n
|
|
|
+ id = deviceId
|
|
|
+ */
|
|
|
+ case 'D':
|
|
|
+ LOG("Turn off received");
|
|
|
+ FF_SERIAL << F("*D") << deviceId << F("OOO\n");
|
|
|
+ lightStatus = OFF;
|
|
|
+ setBrightness(0);
|
|
|
+ break;
|
|
|
+
|
|
|
+ /*
|
|
|
+ Set brightness
|
|
|
+ Request: >Bxxx\r
|
|
|
+ xxx = brightness value from 000-255
|
|
|
+ Return : *Bidyyy\n
|
|
|
+ id = deviceId
|
|
|
+ yyy = value that brightness was set from 000-255
|
|
|
+ */
|
|
|
+ case 'B':
|
|
|
+ LOG("Set brightness received");
|
|
|
+ FF_SERIAL << F("*B") << deviceId << _WIDTHZ(brightness, 3) << F("\n");
|
|
|
+
|
|
|
+ brightness = atoi(data);
|
|
|
+
|
|
|
+ if (lightStatus == ON)
|
|
|
+ setBrightness(brightness);
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ /*
|
|
|
+ Get brightness
|
|
|
+ Request: >J000\r
|
|
|
+ Return : *Jiiyyy\n
|
|
|
+ id = deviceId
|
|
|
+ yyy = current brightness value from 000-255
|
|
|
+ */
|
|
|
+ case 'J':
|
|
|
+ LOG("Get brightness received");
|
|
|
+ FF_SERIAL << F("*J") << deviceId << _WIDTHZ(brightness, 3) << F("\n");
|
|
|
+ break;
|
|
|
+
|
|
|
+ /*
|
|
|
+ Get device status:
|
|
|
+ Request: >S000\r
|
|
|
+ Return : *SiiMLC\n
|
|
|
+ ii = deviceId
|
|
|
+ M = motor status( 0 stopped, 1 running)
|
|
|
+ L = light status( 0 off, 1 on)
|
|
|
+ C = Cover Status( 0 moving, 1 closed, 2 open)
|
|
|
+ */
|
|
|
+ case 'S':
|
|
|
+ LOG("Get status recived");
|
|
|
+ FF_SERIAL << F("*S") << deviceId << motorStatus << lightStatus << coverStatus << F("\n");
|
|
|
+ break;
|
|
|
+
|
|
|
+ /*
|
|
|
+ Get firmware version
|
|
|
+ Request: >V000\r
|
|
|
+ Return : *Vii001\n
|
|
|
+ ii = deviceId
|
|
|
+ */
|
|
|
+ case 'V': // get firmware version
|
|
|
+ LOG("Get firmware version received");
|
|
|
+ FF_SERIAL << F("*V") << deviceId << F("001") << F("\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void openFlipFlat()
|
|
|
+{
|
|
|
+ if (coverStatus != OPEN)
|
|
|
+ {
|
|
|
+ LOG("Turn light off");
|
|
|
+ setBrightness(0);
|
|
|
+
|
|
|
+ motorDirection = OPENING;
|
|
|
+ rotateMotor(270.0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void closeFlipFlat()
|
|
|
+{
|
|
|
+ LOG("Closing FlipFlat");
|
|
|
+ if (coverStatus != CLOSED)
|
|
|
+ {
|
|
|
+ motorDirection = CLOSING;
|
|
|
+ rotateMotor(270.0);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ LOG("FlipFlap already closed");
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void rotateMotor(float newAngle)
|
|
|
+{
|
|
|
+ if (motorDirection == OPENING)
|
|
|
+ {
|
|
|
+ motorStatus = RUNNING;
|
|
|
+ coverStatus = NEITHER_OPEN_NOR_CLOSED;
|
|
|
+
|
|
|
+ stepper.move(STEPS * newAngle / 360.0);
|
|
|
+ stepper.runToPosition();
|
|
|
+
|
|
|
+ coverStatus = OPEN;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (motorDirection == CLOSING)
|
|
|
+ {
|
|
|
+ motorStatus = RUNNING;
|
|
|
+ coverStatus = NEITHER_OPEN_NOR_CLOSED;
|
|
|
+
|
|
|
+ stepper.move(-STEPS * newAngle / 360.0);
|
|
|
+ stepper.runToPosition();
|
|
|
+
|
|
|
+ coverStatus = CLOSED;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ motorStatus = STOPPED;
|
|
|
+ motorDirection = NONE;
|
|
|
+}
|
|
|
+
|
|
|
+void setupSerial()
|
|
|
+{
|
|
|
+
|
|
|
+#ifdef ESP32
|
|
|
+ FF_SERIAL.begin(9600, SERIAL_8N1, 16, 17);
|
|
|
+ LOG_SERIAL.begin(9600);
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef ARDUINO_AVR_LEONARDO
|
|
|
+ FF_SERIAL.begin(9600);
|
|
|
+ LOG_SERIAL.begin(9600);
|
|
|
+#endif
|
|
|
+
|
|
|
+ LOG("Logging serial up and running");
|
|
|
+ LOG("FlipFlat Serial up and running");
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void handleCoverSwitch(){
|
|
|
+ switch (coverStatus){
|
|
|
+ case CLOSED:
|
|
|
+ LOG("Opening cover");
|
|
|
+ openFlipFlat();
|
|
|
+ break;
|
|
|
+ case OPEN:
|
|
|
+ LOG("Closing cover");
|
|
|
+ closeFlipFlat();
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ LOG("Cover not open or closed");
|
|
|
+ }
|
|
|
+}
|