/* * RemoteSensor library v1.0.2 (20130601) for Arduino 1.0 * * This library encodes, encrypts en transmits data to * remote weather stations made by Hideki Electronics.. * * Copyright 2011-2013 by Randy Simons http://randysimons.nl/ * * Parts of this code based on Oopsje's CrestaProtocol.pdf, for which * I thank him very much! * * License: GPLv3. See license.txt */ #include /******************* * Sensor base class ******************/ SensorTransmitter::SensorTransmitter(byte transmitterPin, byte randomId) { _transmitterPin = transmitterPin; _randomId = randomId; pinMode(_transmitterPin, OUTPUT); } /* Encrypt data byte to send to station */ byte SensorTransmitter::encryptByte(byte b) { byte a; for(a=0; b; b<<=1) { a^=b; } return a; } /* The second checksum. Input is OldChecksum^NewByte */ byte SensorTransmitter::secondCheck(byte b) { byte c; if (b&0x80) { b^=0x95; } c = b^(b>>1); if (b&1) { c^=0x5f; } if (c&1) { b^=0x5f; } return b^(c>>1); } /* Example to encrypt a package for sending, Input: Buffer holds the unencrypted data. Returns the number of bytes to send, Buffer now holds data ready for sending. */ byte SensorTransmitter::encryptAndAddCheck(byte *buffer) { byte cs1,cs2,count,i; count=(buffer[2]>>1) & 0x1f; cs1=0; cs2=0; for(i=1; i>=1; } } } /* Send bytes (prepared by “encryptAndAddCheck”) and pause at the end. */ void SensorTransmitter::sendManchesterPackage(byte transmitterPin, byte *data, byte cnt) { byte i; for (i=0; i=0x40; temp+=0x40) { /* Sends 3 packages */ memcpy(buffer, data, ((data[2] >> 1) & 0x1f) + 1); buffer[3] = (buffer[3] & 0x1f) + temp; count = encryptAndAddCheck(buffer); /* Encrypt, add checksum bytes */ sendManchesterPackage(transmitterPin, buffer,count); /* Send the package */ delay(30); } } /************************************ * Thermo / Hygro sensor transmitter ***********************************/ ThermoHygroTransmitter::ThermoHygroTransmitter(byte transmitterPin, byte randomId, byte channel) : SensorTransmitter(transmitterPin, randomId) { _channel = channel; } void ThermoHygroTransmitter::sendTempHumi(int temperature, byte humidity) { byte buffer[10]; // Note: temperature is 10x the actual temperature! So, 23.5 degrees is passed as 235. buffer[0] = 0x75; /* Header byte */ buffer[1] = (_channel << 5) | _randomId ; /* Thermo-hygro at channel 1 (see table1)*/ buffer[2] = 0xce; /* Package size byte for th-sensor */ buffer[3] = 0x1e; /* Themo/Hygro */ if ( temperature < 0 ) { buffer[5] = 0x4 << 4; // High nibble is 0x4 for sub zero temperatures... temperature = -temperature; // Make temperature positive } else { buffer[5] = 0xc << 4; // ...0xc for positive } // Note: temperature is now always positive! buffer[4] = (((temperature % 100) / 10 ) << 4) | // the "3" from 23.5 (temperature % 10); // the "5" from 23.5 buffer[5] |= (temperature / 100); // the "2" from 23.5 buffer[6] = ((humidity / 10) << 4) | (humidity % 10); // BCD encoded buffer[7]=0xff; /* Comfort flag */ sendPackage(_transmitterPin, buffer); } void ThermoHygroTransmitter::sendRainlevel(unsigned int level){ // in 0.7mm byte buffer[10]; // Note: temperature is 10x the actual temperature! So, 23.5 degrees is passed as 235. buffer[0] = 0x75; /* Header byte */ buffer[1] = (_channel << 5) | _randomId ; /* Thermo-hygro at channel 1 (see table1)*/ buffer[2] = 0xcc; /* Package size byte for rain-sensor */ buffer[3] = 0x0e; /* Rain level */ // Note: temperature is now always positive! buffer[4] = level & 0xff; // Low byte buffer[5] = (level >>8) & 0xff; // High byte sendPackage(_transmitterPin, buffer); }