Hall Effect Sensor
Because there is a multi-pole magnet attached to the idler wheel, the Hall Effect sensor toggles every time a pulse passes. Because the magnet we used has 6 poles, the Hall Effect outputs 12 transitions per rotation. These transitions are used to track the shade position as well as detect jams.
Jam Detection
The centerpiece of the shade control system is a 16-bit counter running with a 1:256 prescaler. This means, with a 40MHz peripheral clock, that the counter overflows roughly with a period of 420ms. However, an output compare peripheral is configured to fire an interrupt when the Hall Effect sensor output toggles. In this interrupt, the counter is reset and a position counter is incremented (or decremented, depending on the direction of rotation). If the counter overflows, another interrupt is fired to indicate a jam. Behavior when a jam is detected is dependent on the current operating mode.
Motor Control
Because the motors are continuous rotation servos, motion is fairly straightforward. An Output Compare peripheral is used to generate a variable duty cycle waveform with fixed period to tell the servo what speed it should be operating at. The overflow value is chosen such that the period of the waveform is 20ms, as most servos expect. A 1.5ms high wave is considered “stationary”, and 0.3ms added or subtracted from that value to obtain CW or CCW rotation. This value is simply written to the OCxRS register (converted to units of clock cycles) to set the duty cycle.
Handling Multiple Axes
One significant problem that had to be addressed was that each axis required 2 timers (one for the motor control, and one for jam detection). The motor control timer could be used for both motors since the same period was desired, but the jam detection timers could not be combined and independent jam detection still achieved. The OC and IC peripherals can only be configured to use Timer 2 or 3, so only 2 timers were available.
To solve this problem, the decision was made to only ever operate one motor at a time. The PPS system could then be used to direct the OC and IC peripherals to the 2 different sets of pins, one for each motor. As long as both motor outputs, and both Hall Effect inputs, were on pins located in the same PPS group, this output muxing could be achieved simply by use of the PPS. This approach was found to work quite well, though it did force us to manage each axis independently.
Operating Modes
NORMAL: Mode shade defaults to in idle operation. Allows for shades to be moved manually. A detected jam will simply automatically shut that drive motor down.
CALIB_CW: The first calibration mode. Rotate until a jam is detected, then reverse direction.
CALIB_CCW: The second calibration mode. Rotate until a jam is detected.
GOTO_TARGET: Allows the user to specify a specific location, which the shade will automatically move to. If a jam is detected before the target is reached, the shade will automatically stop.
OPEN_1, OPEN_2: Two sets of states used to generally open the shades when commanded. OPEN_1 is used to move the first motor to fully open, and then OPEN_2 opens the other motor the rest of the way.
CLOSE_1, CLOSE_2: The equivalent of OPEN_1 and OPEN_2 but for shade motion in the opposite direction.
Calibration System
Calibration is handled on a per-axis basis. When calibration is triggered, CALIB_CW is called and motor motion is started. The position is updated with ticks from the Hall Effect sensor. When a jam is detected (overflow interrupt is called), the current position (minus a couple ticks) is stored in memory as the endstop location. The motor location is then reversed, the mode changed to CALIB_CCW, and the same procedure repeated. Once another jam is detected, the current location is stored as the second endstop, the motor shuts down, and the system reverts to NORMAL mode.
OPEN_1,2 and CLOSE_1,2 Modes
In each of these modes, a target position for each motor is first set to be one of the endstops (depending on whether it is an open or close command). The target is then compared to the current position, and motor direction is set accordingly. Every time the “tick” Hall Effect interrupt is called, the position is updated compared to the target. Once the target is reached, the second motor is selected and the process is again repeated. The motors are selected in opposite order depending on whether the shades are opening or closing so that closing is effectively opening in reverse order.
ESP Setup
Whenever the system is rebooted, the ESP8266 needs to be reconfigured. This requires communicating AT commands to the ESP via UART. The commands are as follows:
- AT+RST : Reset the ESP module (remove connections, disconnect from wifi, default modes)
- AT+CWMODE=1:Places ESP in station mode
- AT+CIPSTA=”IP”,”Gateway IP”,”Netmask ID”:Changes the IP address of the module. This is necessary for the two ESP modules to know which IP address to communicate with.
- AT+CWJAP=”ssid”,”password”:Connect to the wifi network
- AT+CIPSTART=”TCP”,”SERVER_IP”,<port> :Connects to the server with the specified IP address
- AT+CIPMODE=1:Places ESP in untarnished mode transmission. This allows the ESP module to send and receive data without any other command. It also enables auto reconnect with the server
- AT+CIPSEND: Start transmission
All commands were carried out using UART communication as implemented by the esp866.c library.
Network Connectivity
An ESP8266 module was used for network connectivity. It connects to a WiFi network the same way that the light controller does, and then seeks to establish a connection to the light controller. The light controller sends commands to the shade controller in the form of single ASCII characters. These commands are ‘I’, ‘D’, and ‘S’. A dedicated protothread monitors the UART and yields until a character is received, at which point it is processed. ‘I’ put the controller into the OPEN_1 state, ‘D’ into CLOSE_1, and ‘S’ stopped all motion. Furthermore, if the shade controller stops motion itself, either because of a jam, manual override, or the shade was completely opened or closed, it sends an ‘S!’ back to the light controller to inform it that motion was halted.
Manual Control
A second protothread is used to check the button status every 0.1 sec. If both buttons for a control axis are pressed, then calibration mode is entered. If only a single button is pressed, the last button pressed and the time since it was pressed are tracked. If the same button is pressed again within 5 cycles (0.5sec) it is considered a double press, and GOTO_TARGET is entered, with the target being set to the relevant endpoint. Otherwise, if a button is being held down, that motor is turned on in the relevant direction. If no buttons are down, all motors are shut down.
Command Line Debugging Interface
A system was developed to allow for command line control of the shade controller for debugging purposes. It cannot be used together with the ESP network, since they both use the same UART peripheral, but is useful for development and debugging purposes.
Obstacles Encountered
The most complicated portion of the design involved the PPS output muxing. Once this problem was solved, however, it worked quite well. The actual motor control system worked fairly well when driven over the command line interface, but when integrated with the ESP began to cause problems. Most of these were fixed by having the commands between controllers sent as single chars instead of as words, which drastically simplified the parsing that the receiver and transmitter needed to do.
Finally, there was a fair amount of uncertainty around where exactly bugs were located. It was often hard to tell if there was a hardware/sense failure, a motor control failure, or a networking failure. This confusion was partially mitigated by the development of a dedicated command line interface which could be used to debug just the controller without any of the ESP interface and networking system running.