I'm creating a sketch to control my projector at home. Unfortunately, my projector requires a (9:th) parity bit for UART communication (see other topic), so I decided to bitbang the protocol. Here's the code:
Code: Select all
// LED pin number
#define LED_PIN 13
#define START_CODE ((char)0xA9)
#define END_CODE ((char)0x9A)
static byte lastValue = 0;
static byte currentValue = 0;
//static const char onCmd[] = { START_CODE, 0x17, 0x2E, 0x00, 0x00, 0x00, 0x3F, END_CODE };
//static const char offCmd[] = { START_CODE, 0x17, 0x2F, 0x00, 0x00, 0x00, 0x3F, END_CODE };
static const char onCmd[] = "UUUUUUUU";
static const char offCmd[] = "UUUUUUUU";
s_pin txPin = 15;
unsigned long timestamp = 0;
#define INTERBIT_26_US_SLEEP delayMicroseconds(41); NOPS(23)
#define SET_TX_PIN(level) digitalWrite(txPin, level); INTERBIT_26_US_SLEEP
static void txByte(char b, bool parity)
{
noInterrupts();
// start bit
SET_TX_PIN(LOW);
// 8 data bits
SET_TX_PIN(b & (1 << 0) ? HIGH : LOW);
SET_TX_PIN(b & (1 << 1) ? HIGH : LOW);
SET_TX_PIN(b & (1 << 2) ? HIGH : LOW);
SET_TX_PIN(b & (1 << 3) ? HIGH : LOW);
SET_TX_PIN(b & (1 << 4) ? HIGH : LOW);
SET_TX_PIN(b & (1 << 5) ? HIGH : LOW);
SET_TX_PIN(b & (1 << 6) ? HIGH : LOW);
SET_TX_PIN(b & (1 << 7) ? HIGH : LOW);
// parity
SET_TX_PIN(parity ? HIGH : LOW);
// stop bit
NOPS(40); // compensate a bit for the lack of comparison
SET_TX_PIN(HIGH);
// for perfect bit timing we should wait some more here,
// but we don't.
interrupts();
}
static bool CalculateParity(byte b)
{
bool parity = false;
while (b) {
parity = !parity;
b = b & (b - 1);
}
return b;
}
static void TurnOnProjector()
{
Serial.print("Turning on projector... ");
for (int i = 0; i < 8; ++i) {
txByte(onCmd[i], CalculateParity(onCmd[i]));
}
digitalWrite (LED_PIN, HIGH);
Serial.println("done.");
}
static void TurnOffProjector()
{
Serial.print("Turning off projector... ");
for (int i = 0; i < 8; ++i) {
txByte(offCmd[i], CalculateParity(offCmd[i]));
}
digitalWrite(LED_PIN, LOW);
Serial.println("done.");
}
// next macro sets up the Z-Uno channels
// in this example we set up 1 switch binary channel
// you can read more on http://z-uno.z-wave.me/Reference/ZUNO_SWITCH_BINARY/
ZUNO_SETUP_CHANNELS(ZUNO_SWITCH_BINARY(getter, setter));
// this function runs only once the controller sends new value
void setter (byte value) {
currentValue = value;
}
// this function runs only once the controller asks
byte getter () {
return currentValue;
}
void setup() {
Serial.begin();
pinMode(LED_PIN, OUTPUT);
pinMode(txPin, OUTPUT);
currentValue = lastValue = 0;
}
void loop() {
if(millis() - timestamp > 3000) {
Serial.print("PING - ");
Serial.println(timestamp);
timestamp = millis();
}
if (lastValue != currentValue) {
lastValue = currentValue;
if (currentValue > 0) {
TurnOnProjector();
}
else {
TurnOffProjector();
}
delay(3000);
}
}
I did not re-program the z-uno between these capture. I only changed the power supply.
What is wrong?