|
- /*
- x10.cpp - X10 transmission library for Arduino version 0.4
-
- Original library (0.1) by Tom Igoe.
- Timing bug fixes (0.2) " " "
- #include bug fixes for 0012 (0.3) " " "
- use pullup, minor tweaks (0.4) Paul Stoffregen <paul@pjrc.com>
-
- Zero crossing algorithms borrowed from David Mellis' shiftOut command
- for Arduino.
-
- The circuits can be found at
- http://www.arduino.cc/en/Tutorial/x10
- */
-
- #include "x10.h"
-
- /*
- Constructor.
-
- Sets the pins and sets their I/O modes.
-
- */
- x10::x10(uint8_t zeroCrossingPin, uint8_t dataPin)
- {
- this->dataPin = dataPin; // the output data pin
- zeroCrossingReg = portInputRegister(digitalPinToPort(zeroCrossingPin));
- zeroCrossingBit = digitalPinToBitMask(zeroCrossingPin);
-
- // Set I/O modes:
- #ifdef INPUT_PULLUP
- pinMode(zeroCrossingPin, INPUT_PULLUP);
- #else
- pinMode(zeroCrossingPin, INPUT);
- digitalWrite(zeroCrossingPin, HIGH);
- #endif
- pinMode(dataPin, OUTPUT);
- }
-
-
-
- /*
- Writes an X10 command out to the X10 modem
- */
- void x10::write(byte houseCode, byte numberCode, byte numRepeats)
- {
- byte startCode = B1110; // every X10 command starts with this
-
- // repeat as many times as requested:
- for (uint8_t i = 0; i < numRepeats; i++) {
- // send the three parts of the command:
- sendBits(startCode, 4, true);
- sendBits(houseCode, 4, false);
- sendBits(numberCode, 5, false);
- }
- // if this isn't a bright or dim command, it should be followed by
- // a delay of 3 power cycles (or 6 zero crossings):
- if ((numberCode != BRIGHT) && (numberCode != DIM)) {
- for (uint8_t i = 0; i < 6; i++) {
- waitForZeroCross();
- }
- }
- }
-
- /*
- Writes a sequence of bits out. If the sequence is not a start code,
- it repeats the bits, inverting them.
- */
- void x10::sendBits(byte cmd, byte numBits, byte isStartCode) {
- byte thisBit; // copy of command so we can shift bits
-
- // iterate the number of bits to be shifted:
- for (uint8_t i=1; i<=numBits; i++) {
- // wait for a zero crossing change:
- waitForZeroCross();
- // shift off the last bit of the command:
- thisBit = !!(cmd & (1 << (numBits - i)));
-
- // repeat once for each phase:
- for (uint8_t phase = 0; phase < 3; phase++) {
- // set the data Pin:
- digitalWrite(this->dataPin, thisBit);
- delayMicroseconds(BIT_LENGTH);
- // clear the data pin:
- digitalWrite(this->dataPin, LOW);
- delayMicroseconds(BIT_DELAY);
- }
-
- // if this command is a start code, don't
- // send its complement. Otherwise do:
- if(!isStartCode) {
- // wait for zero crossing:
- waitForZeroCross();
- for (uint8_t phase = 0; phase < 3; phase++) {
- // set the data pin:
- digitalWrite(this->dataPin, !thisBit);
- delayMicroseconds(BIT_LENGTH);
- // clear the data pin:
- digitalWrite(dataPin, LOW);
- delayMicroseconds(BIT_DELAY);
- }
- }
- }
- }
-
-
- /*
- waits for a the zero crossing pin to cross zero
-
- */
- //void x10::waitForZeroCross(uint8_t howManyTimes)
- void x10::waitForZeroCross(void)
- {
- // wait for pin to change:
- if (*zeroCrossingReg & zeroCrossingBit) {
- while (*zeroCrossingReg & zeroCrossingBit) /* wait */ ;
- } else {
- while (!(*zeroCrossingReg & zeroCrossingBit)) /* wait */ ;
- }
- }
-
-
- /*
- version() returns the version of the library:
- */
- int x10::version(void)
- {
- return 3;
- }
|