EE161: X10 Receiver Project by Shabsi Walfish and Omar Badoolah under guidance of Professor Stuart Kirtman Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 2/30 02/13/16 1. ABSTRACT The X10 Home Automation System, first patented in 1980, utilizes standard household power outlets to transmit control commands from a central location to appliance units located throughout a home. These control commands are sent as bursts of data riding on top of the standard 120V 60 Hz AC signal available from the power outlets located throughout the house. The advantage of this system is that it does not require the broadcasting of RF signals for communication, or new runs of wire from the master control unit to its slaves (the individual appliance control units). The disadvantage, on the other hand, is interference due to noise on the local power supply, as well transmissions from neighboring control units. The purpose of this project was to construct a working slave unit, capable of receiving transmissions from standard X10 control modules, and interpreting the commands contained in the transmissions in order to control a small lamp. This report describes the complete construction of a working slave unit to control a small lamp, including full schematic diagrams for the circuit as well as source code for the microcontroller that is used to interpret the control codes. Additionally, a PCB layout of the circuit is included. 2. INTRODUCTION The transmissions from the X10 control unit take the form of brief 120 kHz pulses riding on top of the 60 Hz power signal. The pulses are relatively weak compared to the 120V AC signal they are riding on top of, so amplifying them after filtering them from the power signal is critical. Each of the 120 kHz pulses lasts approximately 1 ms, and is repeated 3 times, spaced to coincide with zero crossings of the AC power signal in a 3 phase power system. A bit of data transmitted from the control unit is represented either as the presence of a pulse at the zero crossing of the AC signal for a one, or the absence of a pulse for a zero. All transmissions from the control unit are preceded by a special “start code”, a sequence of three one bits followed by a single zero bit. The start code is followed by 9 bits of data (4 representing the house code, and 5 representing a unit/function code). These data bits are sent as pairs of complementary pulses; that is, a one is transmitted as the presence of a pulse (a 1 bit) immediately followed by the absence of a pulse (a 0 bit), and a zero is transmitted as 0 bit followed by a 1 bit. This scheme allows for simplistic error detection, and sends a bit of data once for every complete 60 Hz cycle of the power signal, since there are two zero crossings per cycle. Every complete code sequence sent is repeated three times in order to improve the probability of detection. A complete table of the house and unit/function codes is contained in Appendix A. In order to receive the 120 kHz pulses from the power lines, a 12V (peak to peak) AC transformer is plugged into a standard wall outlet, and used to power the circuit as well as to provide the input signal from the power lines. See Figure 5.1 below for an example of the signal coming from the transformer. As shown in the block diagram, Figure 3.1, the input signal produced by the transformer is put through a Filtering Stage, which provides some gain and filters out any signals not in the 120 ± 20 kHz range. This eliminates the 60 Hz power signal itself and most of the noise on the line. The Filtering Stage is implemented as an RC high pass filter followed by two identical active bandpass filtering stages, each consisting of one operational amplifier (opamp) with an RC network. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 3/30 02/13/16 The Filtering Stage is immediately followed by a Variable Gain Stage, consisting of a single opamp in a negative feedback configuration with variable gain. This stage amplifies the 120 kHz pulses coming out of the filter in order to pick up transmissions from as far away as possible. The variable gain may be used to tune the sensitivity and improve signal reception. The amplified output is then put through an Integration Stage, which rectifies the signal with a diode and integrates it with a passive RC network in order to produce a roughly square pulse and provide some additional hold time. The height of this pulse will vary with the amplitude of the amplified 120 kHz burst coming out of the previous stage. The roughly square waveforms produced by the Integration Stage are then amplified by the Secondary Amplification Stage, which should boost most of the pulses up to 5V. This stage is made up of an operational amplifier in the standard inverting configuration using negative feedback. Without this secondary amplification stage, weaker signals coming from more distant transmitters would be impossible to detect, as there is not generally enough gain in the previous stages to obtain a discernable pulse height. Increasing the gain in the previous stages poses a difficulty due to line noise, and feedback through the circuit’s power supply. Finally, the output of the Secondary Amplification Stage is put into a Comparator Stage, in order to provide a clean 0 or 5V TTL level signal. This stage consists of a comparator with a resistive biasing network. The signal produced is active low, in the sense that it stays high if no pulse is detected, and goes low if a pulse is received. This signal will then be fed to the final stage, a PIC microcontroller that does the necessary processing to interpret the signal pulses. The PIC microcontroller also requires an input from a Zero Crossing Detector Stage, which provides a signal to the microcontroller indicating when the 60 Hz power line has just gone through a zero crossing (and thus a data burst is expected). The Zero Crossing Detector consists of an RC network and a Schmitt Trigger, and it takes input directly from the 60 Hz power signal. Using a combination of the Zero Crossing Detector signal, and the output of the Comparator Stage indicating when a pulse has occurred, the PIC microcontroller is capable of reading transmitted data bits and interpreting them through software. Finally, in order to keep the entire circuit on a single power supply, the same 12V 60 Hz signal coming from the transformer is put through a Power Regulation Stage, which produces clean +5V and –5V DC power supplies for the circuit. This stage contains large filter capacitors, a pair of diodes, and a pair of voltage regulator ICs. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 4/30 02/13/16 3. ANALOG - BLOCK DIAGRAM Figure 3.1 contains a block diagram of the analog portion of the circuit as described in the introduction. Each stage of the circuit is laid out individually, providing for a modular system. If any individual stage should fail, it is easier to diagnose and repair it as a result of this modularity. A detailed description of the operation of each of these stages follows in the next section. Figure 3.1 - Block Diagram 4. ANALOG - SCHEMATICS AND CALCULATIONS The complete circuit schematic for the analog part of this project is shown in Figure 4.1 (next page), with the signal extractor circuit contained in Figure 4.1a, and the Zero Crossing Detector (ZCD) and Power Supply stages drawn in Figures 4.1b and 4.1c respectively. The ZCD was separated because its operation is completely independent of the signal extractor. The Power Supply was separated because it too operates independently, although it produces the voltage supplies for the rest of the circuit. Wherever +5V and –5V supplies are indicated, they are taken from the Power Supply Stage. The Vin signal is from the transformer, and Vout and ZCDout go to the PIC microcontroller. Individual blocks are indicated, and the block diagram is clearly visible in the schematic itself. Each of the stages in the primary circuit was built and tested in order, using the previous stages to provide the necessary test input. The expected output signals at each stage are discussed in the next section. The signal extractor circuit starts with the Filtering Stage on the left at Vin, and continues up to but not including resistor R7, which is the input resistor for the Variable Gain Stage. The Variable Gain Stage contains only the single opamp U3 and outputs directly to diode D1 which marks the start of the Integration Stage. The Integration Stage outputs into the positive terminal of the non-inverting amplifier U4 that is used as the Secondary Amplification Stage. The Secondary Amplification Stage provides the input for the final stage, which starts with U5. This final Comparator Stage provides the output which the PIC microcontroller will take as its input. It is important to note that the PIC will only sample the input signal coming from the Comparator Stage when there is a zero crossing of the power signal, and thus what the extracted signal coming from the comparator does far away from a zero crossing is irrelevant. A detailed description of each stage follows. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 5/30 02/13/16 Figure 4.1a – Signal Extractor Circuit Schematic Figure 4.1b – Zero Crossing Detector Schematic Figure 4.1c – Power Supply Schematic Figure 4.1 – Schematic Diagrams The first piece of the filtering stage, a simple RC high-pass filter was necessary in order to prevent the 12V peak-to-peak input coming out of the transformer from overloading the opamps in this stage, which are powered by the +5V/-5V rails. The RC filter was designed to pass signals at 100 kHz or above, using the passive filter equation given in Appendix B. The two active bandpass filter circuits were designed to have center frequencies (f0) of approximately 120 kHz, with a Q factor of 3, which implies a pass-band from 100 kHz to 140 kHz. They also provide a gain factor (A) of approximately 5 each. It was necessary to employ two stages in order to provide adequate attenuation of the 60 Hz noise produce by the transformer. The formulas applied in order to obtain the values for C1, C2, R1, R2, and R3 (and their identical counterparts C3, C4, R4, R5, and R6) that would achieve the desired frequency response are as follows: C = C1 = C2 (4.1) R1 = Q / (2 f0 C A) (4.2) R2 = Q / (((2 Q2) – A) 2 f0 C) (4.3) R3 = (2 Q) / (2 f0 C) (4.4) These standardized single opamp bandpass filter design formulas are available in many filter design texts, as well as online1. The frequency response as measured in the lab is provided in the next section. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 6/30 02/13/16 The Variable Gain Stage is an operational amplifier in a negative feedback configuration, with a 100k potentiometer as the feedback resistor. The 5k input resistor was chosen to provide a gain factor of up to 20. The diode immediately following the amplifier rectifies the signal, as part of the Integration Stage. The rectified signal is fed into an RC integrator network. It should be noted that the resistance as seen by the capacitor as it charges is different from that seen by the capacitor during discharge. While charging, the circuit acts as if R9 and R10 in parallel; while discharging, they act as if they were in series. This means the charge time is small, while the hold time is longer. The values were chosen for a discharge time that would flatten the top of the 120 kHz pulse, yet still discharge before another burst of 120 kHz could arrive. Using the following equation: V = V0 exp(-t / ) (4.5) where t is time, V0 is the burst height (approximately 4 volts in this case), and is the time constant RC (in this case (R9 + R10)C5 ), appropriate values for R9 and R10 were found to be 220k each if C5 was chosen to be 1nF. The Secondary Amplification Stage boosts the amplitude of the flattened pulses coming from the Integration Stage using a non-inverting configuration. A gain that was empirically determined to work well was a factor of 6, and this was achieved by setting the ratio of R12 to R11 to be 5, since the configuration of the non-inverting amplifier at U4 in Figure 2a has a gain (A) given by: A = 1 + R12 / R11 (4.6) The Comparator at U5 was set for a threshold voltage of approximately 1.6V using a voltage divider consisting of R13 and R14. This threshold was chosen to be bigger than 6 times the amplitude of the noise entering the Secondary Amplification Stage, which was estimated to be about a quarter of a volt. The output of this comparator is then sent to the PIC microcontroller, as discussed in the digital section (Section 6). This concludes the discussion of the signal extractor circuit. The Zero Crossing Detector, shown in Figure 2b, utilizes a Schmitt Trigger in order to minimize noise. The Schmitt Trigger is essentially a comparator with hysterisis; it has a threshold of approximately .01 volts for a rising input signal, and 0 volts for a falling signal. The rising signal threshold voltage was chosen to be extremely low, in order to react quickly to the zero crossings of the power signal. A low pass RC filter, consisting of Rz1 and Cz1, precedes the trigger. The values of the resistors and capacitor were chosen to give a cutoff frequency around 1 kHz. In addition to removing high frequency noise, this filter helps attenuate the 12V peak to peak input to prevent it from overloading the operational amplifier Uz1. The output of this stage is sent directly to the PIC, as no further analog manipulation needs to be done. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 7/30 02/13/16 Finally, the Power Supply circuit is responsible for providing constant rail voltages to all the other stages in the circuit. The components in the Power Supply circuit were chosen to give clean supplies; the 1N4001 diodes were chosen to deal with the high voltages and act as half wave rectifiers. The large capacitors are necessary in order to maintain the voltage between peaks after the half wave rectification. The regulator chips (7805 and 7905) are designed to produce +5V and –5V DC supplies, and have safety features to prevent the circuit from overloading. 5. MEASUREMENTS In order to ensure that the circuit was functioning properly, the outputs at various stages were monitored during construction of the circuit, using a standard laboratory oscilloscope. The original input waveform was expected to look much like Figure 5.1, although the amplitude of the 120 kHz bursts has been greatly exaggerated. Figure 5.1 – Expected Input Signal The initial group of nine bursts actually represents the transmission of three 1 bits, since each burst is repeated three times. The eleven cycles of the power signal shown here comprise a complete code transmission, and the burst pattern represents a valid code. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 8/30 02/13/16 This input signal is then put into the Filtering Stage, which is expected to produce an output signal much like the one shown in Figure 5.2. All the 60 Hz (or nearly all of it) has been attenuated, and all that remains are the 120 kHz pulses. These pulses appear to be solid because the 120 kHz oscillation is so rapid that it is virtually impossible to see on the time scale of this graph, which remains constant throughout all the figures. Figure 5.2 – Expected Output of Filtering Stage Note that all three pulses sent pass through the filter, even though we are only interested in the one that occurs at the zero crossing, in this case, the first. The positioning of the other pulses relative to the one we are interested in is irrelevant, and the choice to assume that the first pulse occurred at the zero crossing was arbitrary, since the actual input at the receiver depends on its phase lag in a three phase AC system. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 9/30 02/13/16 The output of this filter is then put through the integration stage, which turns the 120 kHz bursts into actual square-wave pulses. It also rectifies the signal, removing the negative portion of the bursts, producing something closer to the digital logic levels required by the PIC. After amplification by the Secondary Amplification Stage, the resulting pulses look something like Figure 5.3, which does not show the effects of the RC discharge curve slightly elongating the pulses Figure 5.3 – Expected Output of Integration Stage These rectified pulses are still not suitable for use by the PIC, however, as they are still noisy, and are not clean 0V or 5V DC signals. The Comparator Stage takes care of this final detail, producing a TTL level signal suitable for input to the PIC. It should be noted that the comparator also inverts these pulses, and the software for the microcontroller was written to take an active low signal as a result. It is important that the pulses be larger than the threshold of the comparator, or there will be no signal at the output. In a properly functioning circuit, the output of the comparator should look like Figure 5.4. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 10/30 02/13/16 Figure 5.4 – Expected Output of Comparator Stage In order for the 120 kHz bursts to pass through the system as has been described, the Filtering Stage must do an adequate job of attenuating the low frequency noise from the power lines. In order to understand how well the Filtering Stage works it is necessary to examine its frequency response. Figure 5.5 contains a plot of frequency versus amplitude, obtained by using a function generator to produce sine waves at different frequencies, and measuring the amplitude of the signals coming from the Filtering Stage. The frequency response of the circuit is clearly not centered where it should have been, most likely due to slight variations in the RC values used in the circuit. However, this does not pose a significant difficulty, since the 120 kHz signals are still passed, and in fact are still amplified sufficiently. Additionally, the roll off is sufficient to attenuate 60 Hz signals to almost unobservable levels. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 11/30 02/13/16 Bandpass Filter Characteristic 4 3.5 3 Gain 2.5 2 1.5 1 0.5 0 0 50 100 150 200 250 300 350 Frequency (kHz) Figure 5.5 – Frequency Response of Filtering Stage Further improvements can be made in the frequency response by increasing the Q factor, and choosing closer matches for the RC values, however there is a compromise involved, as discussed in Section 7. 6. DIGITAL – SCHEMATIC AND DISCUSSION The schematic for the digital part of the system (which includes the PIC microcontroller, its switches, and the lamp to be controlled) is shown in Figure 6.1. The microcontroller is connected to two banks of switches, SU and SH, used to select the unit code and house code, respectively. The purpose of the house code is to prevent X10 control units in neighboring houses from inadvertently triggering the receiver. The unit code allows for control of individual units within the same household. The microcontroller receives additional input from the Zero Crossing Detector Stage, which is used to provide the necessary timing for reading the data bursts from the signal extractor circuit. The software (source code is given in Appendix C) then interprets the received code sequences, and operates a light bulb. Since the light bulb requires more current than the microcontroller is capable of providing through an output pin, it is attached to BJT Q1, which acts like a gate. The base of Q1 is connected to the output from the microcontroller through a series resistance RD1 and a decorative LED, DD1. When the output from the microcontroller goes high, a small current flows through RD1, DD1, and the base of Q1, turning on the LED and the light bulb simultaneously. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 12/30 02/13/16 Figure 6.1 – Schematic Diagram of Digital Stage The PIC16F84 microcontroller operates on a 4 MHz clock, provided by the oscillator OSC1. One instruction is executed for every four cycles of the microcontroller’s clock; thus, instructions are executed at 1 MHz. The software utilizes a delay of approximately .8 ms from the time a zero crossing is detected before checking the output from the signal extractor circuit. This delay was necessary due to overall propagation delay and phase lags in the circuit, and in order to detect the bursts as close to their centers as possible. After the .8 ms delay, the software takes a time average over 5 samples (taken over a 45 microsecond period) from the output of the signal extractor. The time average helps to minimize erroneous pulse detection. In a further effort to improve noise tolerance, the code maintains a full buffer containing the last 22 bits received, and is thus capable of identifying a code sequence that was embedded within a noise pattern containing an erroneous start code. For more information on the timings and PIC settings involved, see the comments in the source code contained in Appendix C. To provide an example, the code sequence illustrated in Figure 5.4 would result in the following chain of events: Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 13/30 02/13/16 - The microcontroller would fill its 22-bit buffer by recording the pulse values at the zero crossings (as determined by the zero crossing detector) with the sequence 11 10 01 10 10 01 01 01 01 10 10. - The microcontroller would then detect a valid start sequence (1110) at the beginning of its buffer, and initiate a code verification which confirms that the remaining pairs of bits are all complimentary pairs. If they are, the first bit in each pair is considered to be the transmitted data bit. If the bit pairs are not valid complements, the sequence is ignored. - Once the code sequence has been proven valid, the microcontroller checks to see if the four bit house code immediately following the start code sequence matches the unit’s house code setting. In this case, the house code is 0110, which matches house code A, as specified in Appendix A. - If the unit is not set to house code A (that is, the house code switch represents the 0th letter of the alphabet in binary), the code transmission is ignored. Otherwise, the microcontroller proceeds to decode the remaining bits. - If the house code matches, the remaining bit sequence is matched against the possible unit and function codes listed in Appendix A. If a unit code is received, it is checked for a match in the same fashion as the house code. A flag is then set in the microcontroller indicating whether or not it last received its own unit code. If a function code is received, the appropriate function is executed. In this case, the code 00011 is received, indicating an All Lights On code. Thus, if the house code was set to A, the microcontroller would turn on the lamp. Additional detail is contained within the source code comments. Finally, it is worthwhile to note that the software is capable of controlling the apparent ‘brightness’ level of the bulb by rapidly turning it on and off, varying the length of the duty cycle. This is achieved via a built in timer interrupt on the microcontroller. Thus the bright and dim function codes are implemented, and as per the X10 specification, the unit will only respond to them after receiving a unit specific instruction with the proper unit code. 7. DIFFICULTIES ENCOUNTERED While constructing this circuit, several difficulties were encountered. The circuit was originally designed using a Filtering Stage with a much higher Q factor and improved gain. However, when more stages were added to the circuit, feedback on the power rails from later stages created a ringing effect in the high Q filters, rendering the circuit useless. In order to prevent the uncontrollable ringing, the circuit was redesigned with lower Q and less gain in the Filtering Stage. The Power Supply produced noise on the rails, which was minimized by the addition of capacitors between the rails. However, there is still an observable noise level, and when the input voltage peaks brief spikes appear on the rails. These spikes are amplified by the Filtering Stage and passed through, appearing at the output of the primary circuit. However, since the spikes appear only at the peaks of the sinusoidal input voltage, and never near the zero crossings, they should not be problematic. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 14/30 02/13/16 Finally, there were some difficulties involving the input signal exceeding the rail voltages used to supply the Zero Crossing Detector Stage. In order to attenuate the signal as well as remove high frequency noise, the input to the Schmitt Trigger in the zero crossing detector was first put through a lowpass filter. The filter was originally set with a cutoff at 60 Hz, but this produced a large phase lag, making it impossible to detect the pulse at the zero crossing. Thus, the filter’s cutoff frequency was increased to 1 kHz which improved the phase response. In the software component, the difficulties were mostly related to the timing issues raised by the interrupts used to control the dimming system. Eventually, it was decided that the interrupts should be timed to occur roughly every 75-80 instructions. This provided great accuracy in controlling the duty cycle of the lamp, without interfering significantly with the delicate timings elsewhere in the program. 8. CONCLUSION The completed prototype, as shown in Appendix D, is functional. Some limitation on the detection range is introduced by the use of a 12V AC step down transformer to provide the power signal to the circuit. Thus, the prototype does not have a detection range comparable to the commercial X10 receiver units. However, it is sufficient to demonstrate the techniques involved in decoding X10 transmissions, and can be easily modified to work with different systems. The modular construction also provides great flexibility for future improvements. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 15/30 02/13/16 APPENDIX A: X10 Codes 2 APPENDIX B: Useful Equations For a passive RC filter, the following equation describes the cutoff frequency, f0, for both high and low pass filters: f0 = 1 / (2 R C) (B.1) The voltage across a voltage divider, is given by: VR1R2 = ((VR1 – VR2)) R2 / (R2 + R1) (B.2) where R1 is the resistor connected to the higher voltage, R2 is the resistor connected to the lower voltage, VR1R2 is the voltage between the two resistors, VR1 is the voltage at the high end of R1 and VR2 is the voltage at the low end of R2. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 16/30 02/13/16 APPENDIX C: PIC Microcontroller Source code (for model PIC16F84) ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; X10.ASM by Shabsi Walfish and Omar Badoolah Sets the PIC16F84 to take the following inputs: RA0: Output from a Zero Crossing Detector for the 60 Hz power line signal. RA1: Output from a Comparator which detects integrated 120 kHz pulses from a bandpass filter. RB0 - RB3: 4-bit Unit Code RB4 - RB7: 4-bit House Code The following outputs are produced: RA4: PWM power control signal for lightbulb __config( _CP_OFF & _PWRTE_ON & _HS_OSC & _WDT_OFF ) include "p16f84.inc" LIST P=16F84, R=DEC ORG 0 ; For case-sensitivity Status EQU STATUS ; Definitions (could have used #define, but this is probably more compatible) GotUnitCode EQU H'01' UnitIsNotLight EQU H'02' UnitIsOn EQU H'03' LightToggle EQU H'04' UTmp1 EQU H'05' ; Flag 0 reserved, start at 1 DimTmr EQU ; Dimmer timer reset value DimLevels EQU DimLevels2 H'1F' ; Number of dimming levels EQU H'5' ; Number of bits used by DimLevels (above line) H'B0' ; Variables DEL EQU AVG EQU UFLAGS DIMMER TMPINT1 TMPINT2 TMP0 EQU TMP1 EQU TMP2 EQU TMP3 EQU TMP4 EQU H'4F' ; Delay count (set before each call to Delay) H'4E' ; Used to store a time average EQU H'4D' ; Unit Status Flags EQU H'4C' ; Dimmer multiplier EQU H'4B' ; Temporary storage for ISR EQU H'4A' ; Temporary storage for ISR H'40' ; Temporary storage H'41' H'42' H'43' H'44' Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II TMP5 TMP6 TMP7 TMP8 TMP9 EQU EQU EQU EQU EQU 17/30 02/13/16 H'45' H'46' H'47' H'48' H'49' ZCD EQU RCVD1 RCVD2 RCVD3 H'1C' ; Zero Crossing Detect Status EQU H'1D' ; Lower 8 bits of recieved code EQU H'1E' ; Middle 8 bits of received code EQU H'1F' ; Upper 6 bits of received code (total 22) DIMCNT EQU H'20' ; Dimmer counter ORG 0 GOTO Start ORG H'04' DimInt MOVWF TMPINT1 ; W -> TMPINT1 SWAPF STATUS, 0 ; STATUS swapped -> W MOVWF TMPINT2 ; TMPINT2 = W BTFSS UFLAGS, UnitIsOn; Check if the light is on GOTO DimRet ; No, so return DECFSZ DIMCNT, 1 ; DIMCNT = DIMCNT - 1 GOTO DimRet ; If DIMCNT > 0, return MOVF DIMMER, 0 ; W = DIMMER MOVWF DIMCNT ; DIMCNT = W MOVLW B'00010000' ; LightToggle bit XORWF UFLAGS, 1 ; Toggle the LightToggle BTFSC UFLAGS, LightToggle ; If we are on now... BSF PORTA, 2 ; Set PORTA's bit 2 high BTFSC UFLAGS, LightToggle GOTO DimRet ; We're done turning on the light, return MOVF DIMMER, 0 ; We need to turn off the light... SUBLW DimLevels ; W = DimLevels - W MOVWF DIMCNT ; DIMCNT = W INCF DIMCNT, 1 ; DIMCNT = DIMCNT + 1 (0 is illegal) BCF PORTA, 2 ; Turn off the light DimRet MOVLW MOVWF MOVLW ANDWF SWAPF MOVWF SWAPF SWAPF RETFIE DimTmr ; Reset TMR0 to DimTmr TMR0 B'11111011' ; Unset the timer interrupt flag INTCON, 1 TMPINT2, 0 ; TMPINT2 unswapped -> STATUS STATUS TMPINT1, 1 ; TMPINT1 (swap then unswap) -> W TMPINT1, 0 ; Return leaving interrupts enabled Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 18/30 02/13/16 Start BSF STATUS, RP0 ; Select bank 1 MOVLW H'03' ; Set lower two bits... MOVWF TRISA ; to make two PORTA pins inputs MOVLW H'FF' ; Make RB0-RB7 inputs MOVWF TRISB ; Turn PORTB inputs/outputs on MOVLW DimLevels ; Initial DIMMER value MOVWF DIMMER ; Initialize DIMMER BCF OPTION_REG, 5 ; Turn RA4 on, T0CK1 off CLRWDT ; Clear WDT & prescaler BSF OPTION_REG, 3 BSF OPTION_REG, 0 ; Setup PS0 MOVLW B'10100000' ; Setup GIE and TOIE IORWF INTCON, 1 ; Enable the bits BCF STATUS, RP0 ; Select bank 0 CLRF UFLAGS ; Clear User Flags CLRF ZCD ; Clear ZCD status BTFSC PORTA, 0 ; Move on if ZCD is set correctly COMF ZCD, 1 ; Complement the ZCD status CALL TurnOn ; Start in the ON state Main MOVF PORTA, 0 ; Load PORTA into W XORWF ZCD, 0 ; W = W XOR ZCD, W(0) = change in RA0 MOVWF TMP1 BTFSC TMP1, 0 ; Skip if RA0 hasn't changed GOTO Crossing ; RA0 changed, crossing occured GOTO Main Crossing ; Delay approximately .8 ms to put us in the middle of the pulse MOVLW 200 MOVWF DEL CALL Delay ; ; ; ; ; ; ; (200 * 4) + 4 cycles + these 2 cycles ; Total 806 cycles The code takes a time average to help minimize the probability of an erroneous pulse being detected... it does create a small possibility of missing an actual pulse, however. Cycles used are tabulated on the right in parenthesis. NOTE: Input from analog circuit is LOW to represent a 1 (active low). CLRF AVG ; BTFSS PORTA, INCF AVG, 1 INCF DEL, 1 CALL Delay BTFSS PORTA, INCF AVG, 1 INCF DEL, 1 CALL Delay BTFSS PORTA, INCF AVG, 1 INCF DEL, 1 CALL Delay BTFSS PORTA, Prepare to take a time average (1) 1 ; Test port RA1 (1) ; Add to AVG if unset (1) ; DEL = 1 (1) ; Wait 8 cycles (approx 20 uS) 1 ; Test port RA1 (1) ; Add to AVG if unset (1) ; DEL = 1 (1) ; Wait 8 cycles (approx 20 uS) 1 ; Test port RA1 (1) ; Add to AVG if unset (1) ; DEL = 1 (1) ; Wait 8 cycles (approx 20 uS) 1 ; Test port RA1 (1) (8) (8) (8) Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 19/30 02/13/16 INCF AVG, 1 ; Add to AVG if unset (1) INCF DEL, 1 ; DEL = 1 (1) CALL Delay ; Wait 8 cycles (approx 20 uS) (8) BTFSS PORTA, 1 ; Test port RA1 (1) INCF AVG, 1 ; Add to AVG if unset ; AVG is now from 0 to 5 inclusive. 3 or more is assumed to be a ; valid 'on' pulse. Total time for this operation was about 45 uS. MOVLW 3 SUBWF AVG, 0 RLF RCVD1,1 RLF RCVD2,1 RLF RCVD3,1 ; Prepare to calculate bit to carry ; W = AVG - 3, C = 1 only if W >= 0 ; Rotate the carry bit into RCVD1 ; Rotate the carry from RCVD1 into RCVD2 ; Rotate the carry from RCVD2 into RCVD3 CALL ProcessBit ; Process the received bit COMF ZCD, 1 ; Complement the ZCD status, and then... GOTO Main ; continue polling. ProcessBit MOVLW XORWF ANDLW BTFSS RETURN ; ; ; ; B'00111000' ; Load W with a Start Code sequence RCVD3, 0 ; W = W XOR RCVD3 B'00111100' ; Mask relevant bits of Start Code only Status, Z ; See if we've matched a Start Code ; Return if we didn't First step is to test for a corrupted since the subsequent code also checks However, it does allow us to remember when appropriate even if some garbage code. Not strictly necessary for valid bit patterns. that we got our unit code code comes down the line. RRF RCVD3, 0 ; W = RCVD3 shifted right once XORWF RCVD3, 0 ; W = W XOR RCVD3 ANDLW B'00000001' ; Mask relevant bits BTFSC STATUS, Z ; If the shifted bits match... RETURN ; It wasn't in standard complement form. RRF RCVD2, 0 ; W = RCVD3 shifted right once XORWF RCVD2, 0 ; W = W XOR RCVD2 ANDLW B'01111111' ; Mask relevant bits BTFSC STATUS, Z ; If the shifted bits match... RETURN ; It wasn't in standard complement form. RRF RCVD1, 0 ; W = RCVD3 shifted right once XORWF RCVD1, 0 ; W = W XOR RCVD1 ANDLW B'01111111' ; Mask relevant bits BTFSC STATUS, Z ; If the shifted bits match... RETURN ; It wasn't in standard complement form. ; We can now proceed under the assumption that the received code is ; in valid form. MOVF RCVD3, 0 ; W = RCVD3 MOVWF TMP3 ; TMP3 = RCVD3 SWAPF TMP3, 1 ; Swap nibbles of TMP3 RLF TMP3, 1 ; Rotate TMP3 left twice RLF TMP3, 1 MOVF PORTB, 0 ; W = PORTB Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II ANDLW MOVWF CALL XORWF ANDLW BTFSS RETURN B'00001111' TMP0 ; CodeTable ; TMP3, 0 B'11000000' STATUS, Z ; ; 20/30 02/13/16 ; W = Lower 4 bits of W TMP0 = Lower 4 bits of W W = House Code ; W = W XOR TMP3 ; Mask relevant bits Check for a match No match, so RETURN MOVF RCVD2, 0 ; W = RCVD2 MOVWF TMP2 ; TMP2 = W = RCVD2 MOVF TMP0, 0 ; W = TMP0 CALL CodeTable ; W = House Code MOVWF TMP0 ; TMP0 = House Code RLF TMP0, 1 ; Rotate TMP0 left twice RLF TMP0, 1 MOVF TMP0, 0 ; W = TMP0 XORWF TMP2, 0 ; W = W XOR TMP2 ANDLW B'11111100' ; Mask relevant bits BTFSS STATUS, Z ; Check for a match RETURN ; No match, so RETURN MOVLW B'00000010' ; 1 in RCVD1's last bit, meaning function XORWF RCVD1, 0 ; W = W XOR RCVD1 ANDLW B'00000011' ; Mask relevant bits BTFSS Status, Z ; Check for a match GOTO CheckUnitCode ; Its a unit code, not a function MOVLW XORWF ANDLW BTFSS RETURN B'00000001' ; Check for a 0 in RCVD2's last bit RCVD2, 0 ; W = W XOR RCVD2 B'00000011' ; Mask relevant bits Status, Z ; Check for a match ; Not something we can handle ; Now only need to check lower 3 bits of function code which are ; in the upper 6 bits of RCVD1. The lower two are 10. MOVLW B'01010110' ; Code for All Units Off XORWF RCVD1, 0 BTFSC Status, Z ; Test match CALL TurnOff ; Match, so Turn Off MOVLW B'01011010' ; Code for All Lights On XORWF RCVD1, 0 BTFSC Status, Z ; Test match CALL TurnOn ; Match, so Turn On MOVLW B'10100110' ; Code for All Lights Off XORWF RCVD1, 0 BTFSC Status, Z ; Test match CALL TurnOff ; Match, so Turn On MOVLW B'01100110' ; Code for On XORWF RCVD1, 0 BTFSC Status, Z ; Test match CALL TurnOnUnit ; Match, so Turn Off Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II MOVLW B'01101010' ; Code for Off XORWF RCVD1, 0 BTFSC Status, Z ; Test match CALL TurnOffUnit ; Match, so Turn Off MOVLW B'10011010' ; Code for Bright XORWF RCVD1, 0 BTFSC Status, Z ; Test match CALL Bright ; Match, so Turn Off MOVLW XORWF BTFSC CALL Dim B'10010110' ; Code for Dim RCVD1, 0 Status, Z ; Test match ; Match, so Turn Off RETURN CheckUnitCode MOVF RCVD2, 0 ; W = RCVD2 MOVWF TMP2 ; TMP2 = W = RCVD2 SWAPF TMP2, 1 ; Swap nibbles of TMP2 RLF TMP2, 1 ; Rotate TMP2 left twice RLF TMP2, 1 SWAPF PORTB, 0 ; W = PORTB swapped ANDLW B'00001111' ; W = Lower 4 bits of W MOVWF TMP0 ; TMP0 = Lower 4 bits of W CALL CodeTable ; W = Unit Code XORWF TMP2, 0 ; W = W XOR TMP2 ANDLW B'11000000' ; Mask relevant bits BTFSS STATUS, Z ; Check for a match GOTO NotMyCode ; No match, so Not My Code MOVF RCVD1, 0 ; W = RCVD1 MOVWF TMP1 ; TMP1 = W = RCVD1 MOVF TMP0, 0 ; W = TMP0 CALL CodeTable ; W = House Code MOVWF TMP0 ; TMP0 = House Code RLF TMP0, 1 ; Rotate TMP0 left twice RLF TMP0, 1 MOVF TMP0, 0 ; W = TMP0 XORWF TMP1, 0 ; W = W XOR TMP1 ANDLW B'11111100' ; Mask relevant bits BTFSS STATUS, Z ; Check for a match GOTO NotMyCode ; No match, so Not My Code BSF UFLAGS, GotUnitCode ; Set the GotUnitCode flag RETURN NotMyCode BCF UFLAGS, GotUnitCode ; Clear the GotUnitCode flag RETURN 21/30 02/13/16 Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 22/30 02/13/16 Bright ; The unit is only supposed to bright or dim if it has just received ; its unit code from an on command, and no other unit code has yet ; come down the line. BTFSS RETURN UFLAGS, GotUnitCode ; Make sure we have our code ; Return if we don't INCF DIMMER, 1 ; DIMMER = DIMMER + 1 BTFSS DIMMER, DimLevels2 ; DIMMER > DimLevels ? RETURN ; No, return DECF DIMMER, 1 ; Yes, DIMMER = DIMMER - 1 RETURN Dim BTFSS RETURN UFLAGS, GotUnitCode ; Make sure we have our code DECFSZ DIMMER, 1 ; DIMMER = DIMMER - 1 RETURN ; DIMMER > 0, return INCF DIMMER, 1 ; DIMMER = 1 (was 0) RETURN TurnOn BSF UFLAGS, UnitIsOn ; Set UnitIsOn flag BSF PORTA, 2 ; Turn RA2 on RETURN TurnOff BCF UFLAGS, UnitIsOn ; Clear UnitIsOn flag BCF PORTA, 2 ; Turn RA2 off RETURN TurnOnUnit BTFSS RETURN UFLAGS, GotUnitCode ; Make sure we have our code ; The flag is NOT cleared intentionally! We still heard our code ; last, and thus subsequent bright/dim commands may be for us. CALL TurnOn RETURN TurnOffUnit BTFSS RETURN UFLAGS, GotUnitCode ; Make sure we have our code CALL TurnOff RETURN Delay ; ; ; ; ; ; The call to this function took 2 cycles on the first run... 2 extra will be added on the last run, for a total of 4 A call to delay thus uses precisely (DEL * 4) + 4 cycles with DEL = 0 being equivalent to DEL = 256. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II ; ; ; ; ; ; ; 23/30 02/13/16 NOTE: Depending on how DEL is loaded, during the initial call, some extra time has to be accounted for. i.e. MOVLW 2 ; adds one cycle... MOVWF DEL ; add another... CALL Delay ; takes a total of 12 cycles (1 * 4 + 4) ; Code block takes a total of 14 cycles Also, note DEL is set to zero on return from this function. NOP DECFSZ GOTO NOP RETURN ; 1 cycle DEL, 1 ; + 1 = 2 cycles Delay ; + 2 = 4 cycles OR ; + 2 = 4 cycles (one is from skipping the GOTO) ; + 2 to return = 6 cycles on last run CodeTable ADDWF PCL,1 DT B'01101001', DT B'01011001', DT B'01010110', DT B'01100110', DT B'01101010', DT B'01011010', DT B'01010101', DT B'01100101', END ; Do a "Computed GOTO"... table entries are RETLWs B'10101001' ; Define the table entries, B'10011001' ; in order. B'10010110' ; NOTE: Bits are duplicated B'10100110' ; but complimented to B'10101010' ; facilitate decoding. B'10011010' B'10010101' B'10100101' Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II APPENDIX D: Photograph 24/30 02/13/16 Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 25/30 02/13/16 APPENDIX E: Additional Work PCB Process Once the analog and digital parts of the circuit were designed and tested on breadboards, the next stage was to fabricate it on a printed circuit board. A series of steps had to be followed, in software, to provide the PCB machine with the required information for fabrication. These steps including creating a schematic, laying out the components on the board and routing the connections. The software used to create the schematic was CircuitMaker® 6 Pro. This schematic differs from Figure 4.1 in that each discrete component must be laid out so that there is a spot for it on the circuit board. From this schematic, a netlist was created for the layout software. The software used to layout and route the components was TraxMaker® 3 Pro. The netlist file (.NET) exported by CircuitMaker was used by TraxMaker to create a .PCB file. A 4.8” X 8.5”, twolayer circuit board was used. The components were manually laid out in TraxMaker to maximize spacing between each component. This allowed the auto routing tool of TraxMaker enough room to route all the networks together. The name of the PCB file is SW_OHB.PCB. The top and bottom layers are shown in Figures E.1 and E.2, respectively. They are also shown with the components overlaid in Figure E.3 and E.4, respectively. Due to time constraints, this is as far as we took this stage of the project. From this stage a Gerber file must be created and the appropriate tools must be defined for the PCB machine. A test run would be done on paper to check that the vias lined up with the grid holes of the circuit board. Once this check is complete, the traces can be printed on a copper sheet. This is followed by a bath in a basic solution to remove all copper not covered by the printed ink. This creates the needed copper traces. This is done for both layers, if necessary. These layers are then pressed on to their respective side of the circuit board. Pins are used to punch holes for the components. Once this is done, the components can then be soldered to the board, and the process is complete. Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II Figure E.1 26/30 02/13/16 Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II Figure E.2 27/30 02/13/16 Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II Figure E.3 28/30 02/13/16 Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II Figure E.4 29/30 02/13/16 Shabsi Walfish and Omar Badoolah Prof. Kirtman – EE161 Engineering Projects II 30/30 02/13/16 LITERATURE CITED 1. An online reference for the active filter equations cited here can be found at: http://ourworld.compuserve.com/homepages/Bill_Bowden/opamp.htm 2. The X10 documentation, used as a source for much of the information contained within this document, notably Appendix A, can be found online at: ftp://ftp.x10.com/pub/manuals/technicalnote.pdf SPECIAL THANKS to Professor Stuart Kirtman for his assistance and guidance (as well as his sardonic comments) throughout this project. We would also like to thank the lab technicians, Roy Belton and Glenn Gross, for their assistance with putting together the final prototype.