Here is the Arduino side of the code
/*******************************************************************************
* DESCRIPTION:
This sketch is written to control a DC Gearmotor that swings a Flat panel into position against the dew shield of the telescope(Closed) and back against the wall (Open).
The DC Gearmotor is Controlled by a Cytron DC motor Controller which requires speed input via a pulse Width Modulated signal
on the PWM terminal and Direction via a binary input on the DIR terminal. These inputs to the motor controller will
originate from the Seeed Studio XIAO SAMD21 Board. Note the I/O pins are only rated for 3.3V
Final speed of the motor will be determined during commisionaing and controled by this sketch using the MaxSpeed varible.(0-255)
The commands required for the motor controller were derived from the Example scipt and library created by:
AUTHOR : Kong Wai Weng
COMPANY : Cytron Technologies Sdn Bhd
WEBSITE : www.cytron.io
EMAIL : [email protected]
the library needed for this board is at
but should be able to be installed diectly from the library manager.
Control inputs will be recieved by serial control via a Windows Form App
information on the Arduino Seeed XIAM Samd21 board can be found here.
To install the Samd board in the Arduino IDE Click on File > Preference, and fill Additional Boards Manager URLs with the url below:
https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json
The commands from PC to Arduino will be OpenCover, Closecover. This Arduino sketch will report Status using the following Enumerators;
1= Closed, 2= Moving, 3=Open,4=Unknown, 5=Error.
This Version adds local manual pushbutton switches to also control the mechanism.
* CONNECTIONS:
Arduino D1 - Grd thru a N/O limit switch to input for stopping in the COVER_ON direction
Arduino D2 - Grd thru a N/O limit switch to input for stopping in the COVER_OFF direction
Arduino D3 - Motor Driver PWM Input
Arduino D4 - Motor Driver DIR Input
Arduino D9 - Open Pushbutton
Arduino D10 - Close Pushbutton
Arduino GND - Motor Driver GND
5V pwr and Grd and serial communication via USB
24VDC power to the Cytron motor controller and output wiring from the controller to the motor
************************************************************************************************************************************************/
#include "CytronMotorDriver.h" //this loads the required library for the cytrom motor control
// Configure the motor driver.
CytronMD motor(PWM_DIR, 3, 4); // PWM = Pin 3, DIR = Pin 4.
//This section sets up the varibles needed for serial communication
String serialin; //declares a string type variable called "serialin" to store incoming serial data from the serial line
//This section sets up other global varibles
int Speed = 0; //creates a integer varible "Speed" and assigns the initial value of 0
int MaxSpeed = 128; //creates an integer varible "MaxSpeed" and assigns a value (0-255), adjust to get desired travel speed
unsigned long end_time;// declares an unsigned, long type varible named 'end_time' a unsigned long varible is 32 bits (0 to 4,294,967,295) (intial Value to be assigned in a few lines)
unsigned long ActuatorTravelTime = 5000; //change to suit your rquirments , set it to just longer than expected open or close time (in milliseconds) to determine if Actuator is lost depending on Actuator travel time.
int TravelRemaining ; //create a varible to store remaining run time to Error
int Switch_Input = 0 ; //Declares a integer varible called "Switch_Input" to store the state of the switch and assigns the initial value of 0
// The setup routine runs once when you press reset.
void setup() {
// this section defines the input pins
pinMode(1, INPUT_PULLUP); // assigns pin 1 as INPUT with an internal pullup resistor
pinMode(2, INPUT_PULLUP); // assigns pin 2 as INPUT with an internal pullup resistor
pinMode(9, INPUT_PULLUP); // assigns pin 9 as INPUT with an internal pullup resistor
pinMode(10, INPUT_PULLUP); // assigns pin 10 as INPUT with an internal pullup resistor
end_time=millis()+ActuatorTravelTime; //Actuator lost reset timer 'end_time' = current time +ActuatorTravelTime seconds
Serial.begin(9600); //Begin Serial Comunication(configured for 9600 baud) using default values of 8Bit, no parity, 1 stop bit
while (!Serial) { ;// Wait for serial port to connect. Required for native USB!
}
serialin = ""; //clears the serialin
// Make sure the RX, TX, and built-in LEDs don't turn on, they are very bright!
// Even though the board is inside an enclosure. Unfortunately, it is not possible to turn off the power LED (green) in code...
// pinMode(PIN_LED_TXL, INPUT);
//pinMode(PIN_LED_RXL, INPUT);
// pinMode(LED_BUILTIN, OUTPUT);
//digitalWrite(LED_BUILTIN, HIGH);
}
// The loop routine runs over and over again forever.
void loop() {
Switch_Input = 0; //Clears the varible Switch_Input
int Open_Limit =digitalRead(1); //creates an integer varible "Open_Limit" and reads pin 1 status into that varible (HIGH if limit switch is open(off), LOW if limit switch is closed(on))
int Close_Limit =digitalRead(2); //creates an integer varible "Close_Limit" and reads pin 2 status into that varible (HIGH if limit switch is open(off), LOW if limit switch is closed(on))
int Open_PB =digitalRead(9); //creates an integer varible "Open_PB" and reads pin 9 status into that varible (HIGH if pushbutton switch is open(off), LOW if pushbutton switch is closed(on))
int Close_PB =digitalRead(10); //creates an integer varible "Close_PB" and reads pin 10 status into that varible (HIGH if pushbutton switch is open(off), LOW if pushbutton switch is closed(on))
if ((Open_Limit ==LOW) && (Close_Limit == LOW)){ //both switches should never be closed unless one is stuck or there is a short in the wiring
Serial.println(5); //notify the PC app of ERROR via serial interface
while((Open_Limit == LOW && Close_Limit == LOW)){}//get stuck in this while loop that can only be reset by fixing the broken limit circuit or by restarting/resetting
}
if (Open_PB == LOW) { //if the open pushbutton has been pressed
Switch_Input = 1; //Assigns the value "1" to the Switch_Input varible
}
if (Close_PB == LOW) {//if the Close pushbutton has been pressed
Switch_Input = 2; //Assigns the value "2" to the Switch_Input varible
}
//=======================================================================================================
//look for and act on commands on the serial interface
while ((Serial.available()>0) || (Switch_Input > 0)) { //will loop through these commands until there is no data remaining in the serial recieve buffer
serialin = Serial.readStringUntil('#'); //Read Serial data and store the results in the 'serialin' string variable until it recieves an '#'
if ((serialin == "CloseCover") || (serialin == "CLOSE") || (Switch_Input == 2)) { //if the command 'CloseCover' or 'CLOSE' is recieved, or the close switch has been pressed
//Actuator status check, checks to see if the position is known and resets end_time
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
if ((Close_Limit == LOW) || (Open_Limit == LOW)){ // if either switch reads as a CLOSED contact
end_time=millis()+ActuatorTravelTime; //reset the timer 'end_time'
}// end of if Actuator status known
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
// this section puts the COVER ON(Close) if the Close command has been recieved and the associated Limit Switch is open
while (Close_Limit == HIGH) {
Open_Limit =digitalRead(1); //reads pin 1 status into that varible (HIGH if limit switch is open(off), LOW if limit switch is closed(on))
Close_Limit =digitalRead(2); //reads pin 2 status into that varible (HIGH if limit switch is open(off), LOW if limit switch is closed(on)
Speed = MaxSpeed; //set speed varible to max speed
motor.setSpeed(Speed); // Run forward at Maxspeed
//**********************
//This section evaluates if the motor has been running longer than expected(end_time)
//and if so, shuts the motor off , prints Error on serial monitor and locks out the sketch until reset
TravelRemaining= end_time-millis(); //calculates the remaining time before Error
Serial.println(2); //Report the moving status to the PC App
if(millis()>=end_time) { //I.E. >2 s have passed since program started or since 'end_time' was last reset!!
motor.setSpeed(0); // Stop the motor (it may be stalled)
Serial.println(5); //let the PC know of the ERROR because the actuator is lost
while(millis()> end_time){}//get stuck in this while loop that can only be reset by restarting/resetting
} //end of if Actuator is lost
//***********************
} //end of while loop
Speed = 0; // sets speed varible back to 0
motor.setSpeed(Speed); // Stop motor now that limit switch has closed
} //end of if 'CloseCover'
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if ((serialin == "OpenCover") || (serialin == "OPEN") || (Switch_Input == 1)){ //if the command 'OpenCover' or 'OPEN' is recieved, or the open switch has been pressed
//Actuator status check, checks to see if the position is known and resets end_time
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
if ((Close_Limit == LOW) || (Open_Limit == LOW)){ // if either switch reads as a CLOSED contact
end_time=millis()+ActuatorTravelTime; //reset the timer 'end_time'
}// end of if Actuator status known
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
// this section takes the COVER Off(Open) if the OPEN command is recieved and the associated Limit Switch is open
while (Open_Limit == HIGH) {
Open_Limit =digitalRead(1); //reads pin 1 status into that varible (HIGH if limit switch is open(off), LOW if limit switch is closed(on))
Close_Limit =digitalRead(2); //reads pin 2 status into that varible (HIGH if limit switch is open(off), LOW if limit switch is closed(on))
Speed = 0 - MaxSpeed; //set speed varible to negative maxspeed
motor.setSpeed(Speed); // Run reverse at Maxspeed
//***********************
//This section evaluates if the motor has been running longer than expected(end_time)
//and if so, shuts the motor off , prints Error on serial monitor and locks out the sketch till reset
TravelRemaining= end_time-millis(); //calculates the remaining time before lost
Serial.println(2); //Report the moving status to the PC App
if(millis()>=end_time) { //I.E. >2 s have passed since program started or since 'end_time' was last reset!!
motor.setSpeed(0); // Stop the motor (it may be stalled)
Serial.println(5); //let PC app know that the actuator is lost
while(millis()> end_time){}//get stuck in this while loop that can only be reset by restarting/resetting
} //end of if Actuator is lost
//***********************
} //end of while loop
Speed = 0; // sets speed varible back to 0
motor.setSpeed(Speed); // Stop motor now that the limit switch has closed
} //end of if 'OpenCover'
serialin = ""; //clears the serialin
} //end of while serial loop
//==============================================================================================================
// The next three sections determine the status of the Cover
if ((Close_Limit == 1) && (Open_Limit == 0)){ //if 'closed' switch is OPEN and 'open' switch is CLOSED
Serial.println(3); //updates the status as OPEN
} //end of if 'closed'
if ((Close_Limit == 0) && (Open_Limit == 1)){ //if 'closed' switch is CLOSED and 'open' switch is OPEN
Serial.println(1); //updates the status as CLOSED
} //end of if 'closed'
if ((Close_Limit == 1) && (Open_Limit == 1)) { //if both switches are OPEN
Serial.println(4); //updates the status as unknown
} //end of if 'closed'
delay(250 );
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//This section is commented out if using ASCOM, but can be turned on for troubleshooting or when using Arduino serial control
Serial.println(); //print several lines to clear the serial monitor
Serial.println(); //print several lines to clear the serial monitor
Serial.println(); //print several lines to clear the serial monitor
Serial.println(); //print several lines to clear the serial monitor
Serial.println(); //print several lines to clear the serial monitor
//Serial.print("Close Limit is "); //prints text listed on Serial monitor
//Serial.println(Close_Limit); //prints the varible
//Serial.print("Open Limit is "); //prints text listed on Serial monitor
//Serial.println(Open_Limit); //prints the varible
delay (100);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
} //end of void loop
/*
commands from the Cytron Example sketch
motor.setSpeed(128); // Run forward at 50% speed.
delay(1000);
motor.setSpeed(255); // Run forward at full speed.
delay(1000);
motor.setSpeed(0); // Stop.
delay(1000);
motor.setSpeed(-128); // Run backward at 50% speed.
delay(1000);
motor.setSpeed(-255); // Run backward at full speed.
delay(1000);
motor.setSpeed(0); // Stop.
delay(1000);
*/