PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

130 lines
3.2KB

  1. /*
  2. x10.cpp - X10 transmission library for Arduino version 0.4
  3. Original library (0.1) by Tom Igoe.
  4. Timing bug fixes (0.2) " " "
  5. #include bug fixes for 0012 (0.3) " " "
  6. use pullup, minor tweaks (0.4) Paul Stoffregen <paul@pjrc.com>
  7. Zero crossing algorithms borrowed from David Mellis' shiftOut command
  8. for Arduino.
  9. The circuits can be found at
  10. http://www.arduino.cc/en/Tutorial/x10
  11. */
  12. #include "x10.h"
  13. /*
  14. Constructor.
  15. Sets the pins and sets their I/O modes.
  16. */
  17. x10::x10(uint8_t zeroCrossingPin, uint8_t dataPin)
  18. {
  19. this->dataPin = dataPin; // the output data pin
  20. zeroCrossingReg = portInputRegister(digitalPinToPort(zeroCrossingPin));
  21. zeroCrossingBit = digitalPinToBitMask(zeroCrossingPin);
  22. // Set I/O modes:
  23. #ifdef INPUT_PULLUP
  24. pinMode(zeroCrossingPin, INPUT_PULLUP);
  25. #else
  26. pinMode(zeroCrossingPin, INPUT);
  27. digitalWrite(zeroCrossingPin, HIGH);
  28. #endif
  29. pinMode(dataPin, OUTPUT);
  30. }
  31. /*
  32. Writes an X10 command out to the X10 modem
  33. */
  34. void x10::write(byte houseCode, byte numberCode, byte numRepeats)
  35. {
  36. byte startCode = B1110; // every X10 command starts with this
  37. // repeat as many times as requested:
  38. for (uint8_t i = 0; i < numRepeats; i++) {
  39. // send the three parts of the command:
  40. sendBits(startCode, 4, true);
  41. sendBits(houseCode, 4, false);
  42. sendBits(numberCode, 5, false);
  43. }
  44. // if this isn't a bright or dim command, it should be followed by
  45. // a delay of 3 power cycles (or 6 zero crossings):
  46. if ((numberCode != BRIGHT) && (numberCode != DIM)) {
  47. for (uint8_t i = 0; i < 6; i++) {
  48. waitForZeroCross();
  49. }
  50. }
  51. }
  52. /*
  53. Writes a sequence of bits out. If the sequence is not a start code,
  54. it repeats the bits, inverting them.
  55. */
  56. void x10::sendBits(byte cmd, byte numBits, byte isStartCode) {
  57. byte thisBit; // copy of command so we can shift bits
  58. // iterate the number of bits to be shifted:
  59. for (uint8_t i=1; i<=numBits; i++) {
  60. // wait for a zero crossing change:
  61. waitForZeroCross();
  62. // shift off the last bit of the command:
  63. thisBit = !!(cmd & (1 << (numBits - i)));
  64. // repeat once for each phase:
  65. for (uint8_t phase = 0; phase < 3; phase++) {
  66. // set the data Pin:
  67. digitalWrite(this->dataPin, thisBit);
  68. delayMicroseconds(BIT_LENGTH);
  69. // clear the data pin:
  70. digitalWrite(this->dataPin, LOW);
  71. delayMicroseconds(BIT_DELAY);
  72. }
  73. // if this command is a start code, don't
  74. // send its complement. Otherwise do:
  75. if(!isStartCode) {
  76. // wait for zero crossing:
  77. waitForZeroCross();
  78. for (uint8_t phase = 0; phase < 3; phase++) {
  79. // set the data pin:
  80. digitalWrite(this->dataPin, !thisBit);
  81. delayMicroseconds(BIT_LENGTH);
  82. // clear the data pin:
  83. digitalWrite(dataPin, LOW);
  84. delayMicroseconds(BIT_DELAY);
  85. }
  86. }
  87. }
  88. }
  89. /*
  90. waits for a the zero crossing pin to cross zero
  91. */
  92. //void x10::waitForZeroCross(uint8_t howManyTimes)
  93. void x10::waitForZeroCross(void)
  94. {
  95. // wait for pin to change:
  96. if (*zeroCrossingReg & zeroCrossingBit) {
  97. while (*zeroCrossingReg & zeroCrossingBit) /* wait */ ;
  98. } else {
  99. while (!(*zeroCrossingReg & zeroCrossingBit)) /* wait */ ;
  100. }
  101. }
  102. /*
  103. version() returns the version of the library:
  104. */
  105. int x10::version(void)
  106. {
  107. return 3;
  108. }