A roll-off roof driver for a DIY automation project that uses an Arduino to provide the interface with a roof motor or roof controller. The driver is intended to be installed and used without the need for coding in the INDI environment. It is the Arduino code that works from a standard interface with the driver that requires adaptation to control the selected motor. There is project, hardware and coding help available online for the Arduino. The driver provides an interface is sufficient to open, close and determine if the roof is fully opened or fully closed for a roll-off or similar roof.
Driver: | RollOff ino |
Executable: | indi_rolloffino |
INDI: | 1.8.1 |
Provided in a form similar to a INDI third party driver. It does require building and installing, see the INSTALL file for directions. The driver is derived from the Ekos roll-off roof simulator driver. USB is the connection mechanism, and it uses a default transmission rate of 38400 baud which can be changed in the Arduino code. The driver responds to Park and Unpark requests, these are sent to the Arduino in the form of open and close requests. The Arduino uses these requests to open or close relays in order to activate roof movement. The driver will generate requests to obtain the state of the fully open and fully closed sensors to determine when the park or unpark request have been completed. The Arduino responds to to those request be reading the assigned switches. There is also an Abort request which should stop any movement in progress. A lock status intended to indicate some form of external mechanical roof lock has been applied. If the lock switch is closed it will block the driver from issuing movement requests. There is an Auxiliary function and status. It use is undefined in the driver. If and how that might be used is up to the Arduino code.
Observatory interface.
The observatory interface will be the normal way to park and unpark the roof.
INDI control panels.
The INDI Control panels provide the detail and setup interfaces.
The main panel's periodic monitoring of the roof status as provided by the Arduino code is reflected in the status lights. The Park/Unpark provides local replication of the Observatory functions. The Open/Close buttons might be of use, if for some reason there is a discrepancy between the drivers notion of where the roof is versus the actual position.
The connection panel is where the USB connection baud rate can be set to match the Arduino code. It is where the USB used for the connection is established.
The options panel is for the setting of the standard driver INDI options and for specifying roof's view of interactions with the telescope mount.
Weather protection.
The driver will interact with the Ekos weather monitoring applications or DIY local sensors and the watchdog timer along with the other dome related drivers.
The Arduino code examples include the communication with the driver, the parsing and decoding of the commands and responses. There is communication error checking, any error messages will be sent back to the driver for logging. The mapping of commands to relay activation is provided. Also the mapping of status switch to command status response. The actual hardware pin to relay, and switch to pin assignments are to be specified. The Arduino's communication with the driver is passive, when there is no roof activity it waits for input. The set of built in commands and responses that the driver can handle along with the communication syntax is outlined below in the communication protocol summary.
It is the Arduino code along with hardware build that is responsible for controlling the safe operation of the roof. How that is done is unknown to the driver. The Arduino receives Open and Close commands from the INDI driver. The Arduino will acknowledge receiving the command. The driver will request the status of the fully open and fully closed switches to which the Arduino will respond. The roof must be brought to a stop when it reaches its limits. It must be able to handle obstructions safely. It should be able to respond to Abort requests from the user via the driver. Consideration should be given to what will happen if a switch fails to open or close and how to protect against over running the roof limits.
Using a commercial controller of some kind can simplify the design of the Arduino project. A controller can provide proper sizing of the motor for the size and weight of the roof. Provide obstruction protection, enforce range limits, variable force adjustments, slow start and slow stop to lessen the impact of sudden activation to get the roof moving. Some models will run off solar power and the choice of chain or track. With a controller that can be activated by a single or a pair of on/off button it is a simple job to wire a relay in parallel to emulate the pushing of a button. There is built in support in the example relay code to temporarily close a relay for a particular length of time.
There are three examples of Arduino code that work with the protocol used by the driver.
Definitions section
Modify to requirements
The terms HIGH, LOW, ON, OFF are defined by the Arduino environment and explained in the Arduino SDK documentation.
For the relays and switches in use define the pin numbers that match the wiring.
The commands from the driver OPEN, CLOSE, ABORT, AUXSET are associated with a relay RELAY_1, RELAY_2, RELAY_3, RELAY_4.
And those relay names are in turn defined to be a particular pin number on the Arduino.
Define similar associations for the driver requests to read the fully open, fully closed and other switches.
Then you define for each of the relays if they are to be set and left in the requested state or if just a momentary set is to
be used. If for the relay associated with the command the HOLD is set to 0, it will be closed and released.
The timing of this is defined below by the DELAY settings. The idea is to emulate a push and release of a button.
If for particular a relay HOLD is defined as 1, then the relay will be set and left closed or opened depending upon the request.
Following the definitions for the switches and relays the internal buffer definitions and limits should be left alone,
they are matched in the driver.
Then any additional error messages can added next for logging by the driver.
Utility routines
sendAck and sendNak
Used to respond to each driver input and used as is. Each input must receive a positive or negative
response. A positive response will return the result. A negative response will be accompanied by an error message.
The next two routines might require modification depending upon how you connect your switches and relays.
setRelay
Modify to requirements
Requires modification depending upon how you connect your relays.
The comments in the routine header might relate if you use a module that provides a bank of relays and associated circuitry.
It describes how to connect an Arduino and have it isolated and protected from back surges from the relay. There is help on
this wiring available on-line. Use the comments in the body as a guide for when the relay should be opening or closing.
Determine given your relay module and wiring how it should be controlled and if needed change around the use of
HIGH and LOW in the routine.
getSwitch
Modify to requirements
Requires modification depending upon how you connect your switches. Similar to the setRelay is the question of how the switches are setup and if they have pull-up or pull-down resistors. If
unsure read about it in the SDK documentation. In summary if external pull down resistors are used an open switch will
return LOW. If external or the Arduino's internal pull-up resistors are used an open switch will return HIGH. So whether
open switch is HIGH or LOW match that to the OFF in the routine.
Communication routines
parseCommand
Used by the readUSB routines to break down the strings from the driver into their parts.
readUSB
Determines type of input. Resolves the named action or state into an associated relay or switch and its associated pin number.
If it is an initial connection request it willl acknowledge that with the local codes version number.
Returns a negative acknowledgement with message for any errors found. When valid command or request is decoded it
calls commandReceived or requestReceived routines. These routines are meant to provide for additional action
if something other or in addition to the default behavior is wanted. It also calls out to isAbortAllowed routine in case
non default decision making is wanted.
If using a commercial opener of some kind where needed action can be related to the use of a relay the default actions may
well suffice. If you need to locally track the motor movement then these breakout points might be of interest.
Intervention routines
These routines are when the final action for a command or request is about to take place. They are brought out from readUSB to be more obvious.
isAbortAllowed
Change if default conditionals are not what you need.
The readUSB routine has received an Abort command. The default implementation is working with just the one button
to control the roof. The decision whether or not to proceed is taken in this routine. Returning false will send
negative acknowledgement to the driver. Returning true will result in the abort command being allowed through to
the commandReceived routine which will activate the the associated relay.
commandReceived
Change if default action of setting a relay is not what you need.
requestReceived
Change if default action of reading the pin and sending result to the driver a relay is not what you need.
Standard routines
setup
Command Format: (command:target|state:value)
Command: | CON | (CON:0:0) | Establish initial connection with Arduino |
GET | (GET:state:value) | Get status of a switch | |
SET | (SET:target:value) | Set relay closed or open |
state: | OPENED | CLOSED | LOCKED | AUXSTATE |
target: | OPEN | CLOSE | ABORT | AUXSET |
value: | ON | OFF | 0 | text-message |
Response Format: (response:target|state:value)
Response: | ACK | Success returned from Arduino |
NAK | Failure returned from Arduino |
Examples:
From the Driver | From the Arduino | ||
Initial connect | (CON:0:0) | > | |
< | (ACK:0:0) | (ACK:0:version) | (NAK:ERROR:message) | ||
Read a switch | (GET:OPENED:0) | > | |
< | ACK:OPENED:ON|OFF) | (NAK:ERROR:message) | ||
Set a relay | (SET:CLOSE:ON|OFF) | > | |
< | (ACK:CLOSE:ON|OFF) | (NAK:ERROR:message) |
A project build example.
The images match with the rolloffino.ino.ar1450 install.
The pin connections. The baloon looking things next to the pull-down resistors are meant to be the fully open/closed switches. With the pull-down resistors an open switch would return LOW when the pin is read. The connection to the Aleko controller to act in place of the single push button comes off of the Normally Open relay NO connection.
The Arduino Due with a relay board. The additional DC supply is to provide the higher voltage required for the relays. The relay bank is opto-isolated from the protected 3.3V Arduino Due which has its own supply. Here only one of the two USB connections is in use. The other can be connected if debug logging is required. Just the single relay on the right is in use with the red and black wires routed to the Aleko controller. When the relay closes, then opens it will replace the action of a manual push button closing a connection.
The Aleko controller board. The AC power supply comes in at the top. To the lower left is the red and black wires feeding back to the Arduino relay. An adjustable potentiometer is visible around the midlle to control how much power is applied to overcome resistance before a blockage is declared.
Just an image showing the Aleko positioning magnet that the controller detects when the roof has reached the fully opened or fully closed position. It shows the track used to drive the roof. The roof will roll a little past where the detector is placed.
Example of a fully closed detection switch feeding to an Arduino pin.