INDI roll-off roof driver using an Arduino to open and close the roof.

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.

The driver

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.


main

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.

main

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.

main

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.

main

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

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.

Arduino Examples

There are three examples of Arduino code that work with the protocol used by the driver.

  1. rolloff.ino.standard. This is a non specific general example as a starting point. It has not been tested. It is close to the AR1450 example. But without the Arduino Due specific code and the pull-down resistor orientation in the specific implementation. If an external controller solution is to be used such as a sliding gate or garage opener controller that provides its own control for stopping the motor when it reaches limits. This might be the Arduino code to use as a starting point.
  2. rolloff.ino.ar1450. This is a specific implementation that uses an Arduino Due. It works with an Aleko AR1450 sliding gate opener controller and motor to activate the roof. A single relay is used with this motor controller to work in place of a a single push button interface. The motor direction alternates with each use. Magnetic sensors provided with the Aleko controller determine when the roof movement stops. If a blockage is detected the contoller will either reverse direction or stop depending upon if it was in the process of opening or closing. A remote FOB can still be used but its movement of the roof is independent of the roof driver.
  3. rolloff.ino.boutons. This user provided example evolved from Arduino Uno code that operated using local buttons and it is able to directly control the motor. The driver communication was added to operate in parallel with the existing code to provide remote capability. It uses a bank of relays to switch polarity to the motor to control direction. The auxiliary function from the driver is used to remotely turn on power for the motor. This Arduino code maintains the state of the roof and monitors local switches to determine when to stop the motor. This approach would be of interest if planning to design that takes direct control of a motor.

Overview of the code used in the rolloffino.standard example.

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
Modify to requirements
If using an AtMega variant Arduino model you can elect to use the built in pull-up resistors on the input pins. To do this use INPUT_PULLUP instead of INPUT definition for the input pins.
For the setting the relay pins use HIGH or LOW depending on which resets your relays to open.
loop
This is the loop that waits for driver input.

Outline of the communication between the roof driver and the Arduino

The communication uses a simple text protocol, lines of text are sent and received
A Command is from the rolloffino driver to the Arduino sketch.
A Response is from the Arduino sketch to the rolloffino driver.
These commands and responses the driver will log to a file when debug logging is enabled.

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
NAKFailure 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.

wiring

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.

Arduino

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.

Aleko Controller

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.

Aleko magnet

Example of a fully closed detection switch feeding to an Arduino pin.

Closed Switch