Initial commit
This commit is contained in:
commit
f83dd4f105
36 changed files with 3704 additions and 0 deletions
150
lib/inFactory/inFactoryReceive.ino
Normal file
150
lib/inFactory/inFactoryReceive.ino
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
|
||||
Transmissions includes an id. Every 60 seconds the sensor transmits 6 packets:
|
||||
|
||||
0000 1111 | 0011 0000 | 0101 1100 | 1110 0111 | 0110 0001
|
||||
iiii iiii | cccc ub?? | tttt tttt | tttt hhhh | hhhh ??nn
|
||||
|
||||
- i: identification // changes on battery switch
|
||||
- c: CRC-4 // CCITT checksum, see below for computation specifics
|
||||
- u: unknown // (sometimes set at power-on, but not always)
|
||||
- b: battery low // flag to indicate low battery voltage
|
||||
- h: Humidity // BCD-encoded, each nibble is one digit, 'A0' means 100%rH
|
||||
- t: Temperature // in °F as binary number with one decimal place + 90 °F offset
|
||||
- n: Channel // Channel number 1 - 3
|
||||
*/
|
||||
|
||||
int old_duration = 0;
|
||||
int new_duration = 0;
|
||||
|
||||
unsigned long old_time = 0;
|
||||
unsigned long new_time = 0;
|
||||
|
||||
boolean old_status = LOW;
|
||||
boolean new_status = LOW;
|
||||
boolean started = false;
|
||||
byte input = 2;
|
||||
|
||||
uint8_t msg[5];
|
||||
byte indexBit = 0;
|
||||
|
||||
|
||||
|
||||
void setup() {
|
||||
// put your setup code here, to run once:
|
||||
pinMode(input, INPUT_PULLUP);
|
||||
Serial.begin(500000);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// put your main code here, to run repeatedly:
|
||||
receive();
|
||||
|
||||
}
|
||||
|
||||
void receive() {
|
||||
new_status = digitalRead(input);
|
||||
if (new_status != old_status) {
|
||||
new_time = micros();
|
||||
new_duration = new_time - old_time;
|
||||
|
||||
if (!new_status && !started) {
|
||||
if (durationEquals(old_duration, 7850, 100) && (durationEquals(new_duration, 600, 100)) ) {// __________|"| //that's a start
|
||||
started = true;
|
||||
}
|
||||
}
|
||||
else if (new_status && started) {//right after rising edge
|
||||
|
||||
if (durationEquals(old_duration, 600, 100)) {
|
||||
if (new_duration < 2700) {// it's a 0
|
||||
bitWrite(msg[indexBit / 8], 7 - (indexBit % 8), 0);
|
||||
}
|
||||
else {// it's a 1
|
||||
bitWrite(msg[indexBit / 8], 7 - (indexBit % 8), 1);
|
||||
}
|
||||
indexBit++;
|
||||
}
|
||||
else { // abort if high level duration is not correct
|
||||
started = false;
|
||||
indexBit = 0;
|
||||
}
|
||||
if (indexBit >= 40) {// stop when 40 bits are received
|
||||
started = false;
|
||||
indexBit = 0;
|
||||
|
||||
if (infactory_crc_check()) {
|
||||
decode();
|
||||
}
|
||||
else {
|
||||
Serial.println("CRC Error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
old_time = new_time;
|
||||
old_duration = new_duration;
|
||||
}
|
||||
old_status = new_status;
|
||||
}
|
||||
|
||||
void decode() {
|
||||
byte iD = msg[0];
|
||||
bool battery_low = (msg[1] >> 2) & 1;
|
||||
int temp_raw = (msg[2] << 4) | (msg[3] >> 4);
|
||||
byte humidity = (msg[3] & 0x0F) * 10 + (msg[4] >> 4); // BCD, 'A0'=100%rH
|
||||
byte channel = msg[4] & 0x03;
|
||||
float temp_f = ((float)temp_raw * 0.1 - 122) * 5 / 9.;
|
||||
Serial.print("iD=");
|
||||
Serial.print(iD, HEX);
|
||||
Serial.print("; lo_bat=");
|
||||
Serial.print(battery_low);
|
||||
Serial.print("; hum=");
|
||||
Serial.print(humidity);
|
||||
Serial.print("; chn=");
|
||||
Serial.print(channel);
|
||||
Serial.print("; tmp=");
|
||||
Serial.println(temp_f);
|
||||
}
|
||||
|
||||
bool durationEquals(int duration1, int duration2, int tolerance) {
|
||||
if (abs(duration1 - duration2) <= tolerance) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
void printHex(byte b) {
|
||||
if (b < 0x10) Serial.print("0");
|
||||
Serial.print(b, HEX);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t crc4(uint8_t const message[], unsigned nBytes, uint8_t polynomial, uint8_t init)
|
||||
{
|
||||
unsigned remainder = init << 4; // LSBs are unused
|
||||
unsigned poly = polynomial << 4;
|
||||
unsigned bit;
|
||||
|
||||
while (nBytes--) {
|
||||
remainder ^= *message++;
|
||||
for (bit = 0; bit < 8; bit++) {
|
||||
if (remainder & 0x80) {
|
||||
remainder = (remainder << 1) ^ poly;
|
||||
} else {
|
||||
remainder = (remainder << 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return remainder >> 4 & 0x0f; // discard the LSBs
|
||||
}
|
||||
|
||||
|
||||
bool infactory_crc_check() {
|
||||
uint8_t msg_crc, crc;
|
||||
msg_crc = msg[1] >> 4;
|
||||
// for CRC computation, channel bits are at the CRC position(!)
|
||||
msg[1] = (msg[1] & 0x0F) | (msg[4] & 0x0F) << 4;
|
||||
// crc4() only works with full bytes
|
||||
crc = crc4(msg, 4, 0x13, 0); // Koopmann 0x9, CCITT-4; FP-4; ITU-T G.704
|
||||
crc ^= msg[4] >> 4; // last nibble is only XORed
|
||||
return (crc == msg_crc);
|
||||
}
|
||||
116
lib/inFactory/inFactoryTransmit.ino
Normal file
116
lib/inFactory/inFactoryTransmit.ino
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
|
||||
#define PIN_TX 4
|
||||
|
||||
uint8_t msg[5];
|
||||
|
||||
uint8_t id = 0x2C;
|
||||
uint8_t channel = 0x01;
|
||||
bool batteryOK = 0;// 0 means OK
|
||||
uint8_t humidity = 69;
|
||||
float temperature = 1.;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
pinMode(PIN_TX, OUTPUT);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// put your main code here, to run repeatedly:
|
||||
temperature += 1.;
|
||||
if (temperature >= 35.) temperature = 1.;
|
||||
|
||||
|
||||
buildMsg();
|
||||
sendRF();
|
||||
|
||||
delay(10000);
|
||||
|
||||
}
|
||||
|
||||
void buildMsg(){
|
||||
|
||||
// put your setup code here, to run once:
|
||||
msg[0] = id;
|
||||
msg[4] = channel + ((humidity%10) << 4 );
|
||||
msg[3] = humidity/10;
|
||||
|
||||
int binTemp = ((temperature * 9./5) + 32 + 90)*10;
|
||||
msg[3] += (binTemp & 0x0F) << 4;
|
||||
msg[2] = binTemp >> 4;
|
||||
|
||||
msg[1] = batteryOK << 2;
|
||||
|
||||
msg[1] = (msg[1] & 0x0F) | (msg[4] & 0x0F) << 4;
|
||||
// crc4() only works with full bytes
|
||||
uint8_t crc = crc4(msg, 4, 0x13, 0); // Koopmann 0x9, CCITT-4; FP-4; ITU-T G.704
|
||||
crc ^= msg[4] >> 4; // last nibble is only XORed
|
||||
|
||||
msg[1] = (msg[1] & 0x0F) | (crc & 0x0F) << 4;
|
||||
|
||||
for (int i=0; i<=4; i++){
|
||||
|
||||
Serial.print(msg[i],HEX);
|
||||
Serial.print(" ");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t crc4(uint8_t const message[], unsigned nBytes, uint8_t polynomial, uint8_t init)
|
||||
{
|
||||
unsigned remainder = init << 4; // LSBs are unused
|
||||
unsigned poly = polynomial << 4;
|
||||
unsigned bit;
|
||||
|
||||
while (nBytes--) {
|
||||
remainder ^= *message++;
|
||||
for (bit = 0; bit < 8; bit++) {
|
||||
if (remainder & 0x80) {
|
||||
remainder = (remainder << 1) ^ poly;
|
||||
} else {
|
||||
remainder = (remainder << 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return remainder >> 4 & 0x0f; // discard the LSBs
|
||||
}
|
||||
|
||||
void sendRF()
|
||||
{
|
||||
/*low long 4000
|
||||
low short 1800
|
||||
high short 700
|
||||
*/
|
||||
|
||||
for (int n=0; n<6; n++)
|
||||
{
|
||||
for (int i=0; i<10; i++){
|
||||
digitalWrite(PIN_TX, !(i%2));
|
||||
delayMicroseconds(1000);
|
||||
}
|
||||
delayMicroseconds(7000);
|
||||
|
||||
for (int i = 0; i<5; i++) {
|
||||
for (int b = 7; b>=0; b--) {
|
||||
digitalWrite(PIN_TX, HIGH);
|
||||
delayMicroseconds(700);
|
||||
digitalWrite(PIN_TX, LOW);
|
||||
if (bitRead(msg[i], b)){
|
||||
delayMicroseconds(4000);
|
||||
}
|
||||
else{
|
||||
delayMicroseconds(1800);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
digitalWrite(PIN_TX, HIGH);
|
||||
delayMicroseconds(1000);
|
||||
digitalWrite(PIN_TX, LOW);
|
||||
|
||||
delayMicroseconds(16000);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue