Go Down

Topic: Wireless doorbell (Read 4447 times) previous topic - next topic

Lectere

Hey Guys,

Need some help with my project. My goal is to make a wireless doorbell.

This is the hardware I have:
-Arduino with Ethernet shield
-RX868SH-C3
-FS20 TK  (wireless doorbell on the FS20 protocol)

I've connected everything like this;



I've took this source code (http://www.jansipke.nl/res/arduino/TempHumid.pde) and uploaded to the Arduino. Modified it to report every package it recieves.

When I run the code, it does recieve the package, but only when I have the wireless doorbell within 20 centimeters of the reciever (RX868SH-C3).

I've tried some other FS20 devices, but no luck. Questions are:
-Anyone has simelair setup?
-Do I need to connect the RX868SH-C3 on the 5v or 3v?, they both seem to work...

Thanks for the help!


Zack_Johnston

#1
Nov 12, 2012, 12:29 am Last Edit: Nov 12, 2012, 12:32 am by Zack_Johnston Reason: 1
Well, at least it works  XD...For a start, you might want to increase the antenna length by a lot....looks very short. Maybe you could have the antenna very close to the door, and very long. You might want to wrap the wire around the door frame.If I am mistaken, and you don't have one, then you might want to figure out a way to add one in. It always helps increase the distance of the reception for any wireless devices.

Lectere

I've tried a longer antenna, no luck... Also, normal FS20 should do 100 meters in the open.

So there must be something else going on here,

Zack_Johnston

Hmmm...Can you post the code? Maybe that will help...:)

Zack_Johnston

Ive done a similar project a while back, and I had to take the doorbell apart and make an antenna....You might want to try that. If its too delicate, then don't bother... :D

Lectere

// The basic idea is to measure pulse widths between 0/1 and 1/0 transitions,
// and to keep track of pulse width sequences in a state machine.

// can't just change these pin definitions, PIN_868 uses interrupts
#define PIN_868 14  // the 868 MHz receiver is connected to AIO1

enum { UNKNOWN, T0, T1, T2, T3, OK, DONE };

// track bit-by-bit reception using multiple independent state machines
struct { char bits; byte state; uint32_t prev; uint64_t data; } FS20;
struct { char bits; byte state, pos, data[16]; } S300;
struct { char bits; byte state, pos, seq; word data[10]; } EM10;
struct { byte state; char bits; uint32_t prev; word data; } KAKU;

static byte FS20_bit (char value) {
   FS20.data = (FS20.data << 1) | value;
   if (FS20.bits < 0 && (byte) FS20.data != 0x01)
       return OK;
   if (++FS20.bits == 45 && ((FS20.data >> 15) & 1) == 0 ||
         FS20.bits == 54 && ((FS20.data >> 24) & 1))
       return DONE;
   return OK;
}

static byte S300_bit (char value) {
   byte *ptr = S300.data + S300.pos;
   *ptr = (*ptr >> 1) | (value << 4);
   
   if (S300.bits < 0 && *ptr != 0x10)
       return OK; // not yet synchronized

   if (++S300.bits == 4) {
       if (S300.pos >= 9 && S300.data[0] == 0x11 || S300.pos >= 15) {
           *ptr >>= 1;
           return DONE;
       }
   } else if (S300.bits >= 5) {
       ++S300.pos;
       S300.bits = 0;
   }

   return OK;
}

static byte EM10_bit (char value) {
   word *ptr = EM10.data + EM10.pos;
   *ptr = (*ptr >> 1) | (value << 8);
   
   if (EM10.bits < 0 && *ptr != 0x100)
       return OK; // not yet synchronized

   if (++EM10.bits == 8) {
       if (EM10.pos >= 9) {
           *ptr >>= 1;
           return DONE;
       }
   } else if (EM10.bits >= 9) {
       ++EM10.pos;
       EM10.bits = 0;
   }

   return OK;
}

static void ook868interrupt () {
   // count is the pulse length in units of 4 usecs
   byte count = TCNT2;
   TCNT2 = 0;

   // FS20 pulse widths are 400 and 600 usec (split on 300, 500, and 700)
   // see http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol
   if (FS20.state != DONE)
       switch ((count - 25) / 50) {
           case 1:  FS20.state = FS20.state == T0 ? FS20_bit(0) : T0; break;
           case 2:  FS20.state = FS20.state == T1 ? FS20_bit(1) : T1; break;
           default: FS20.state = UNKNOWN;
       }

   // (K)S300 pulse widths are 400 and 800 usec (split on 200, 600, and 1000)
   // see http://www.dc3yc.homepage.t-online.de/protocol.htm
   if (S300.state != DONE)
       switch ((count + 50) / 100) {
           case 1:  S300.state = S300.state == T1 ? S300_bit(0) : T0; break;
           case 2:  S300.state = S300.state == T0 ? S300_bit(1) : T1; break;
           default: S300.state = UNKNOWN;
       }

   // EM10 pulse widths are 400 and 800 usec (split on 200, 600, and 1000)
   // see http://fhz4linux.info/tiki-index.php?page=EM+Protocol
   if (EM10.state != DONE) {
       switch ((count + 50) / 100) {
           case 1:  EM10.state = EM10.state == T0 ? EM10_bit(0) : T0; break;
           case 2:  if (EM10.state == T0) {
                       EM10.state = EM10_bit(1);
                       break;
                    } // else fall through
           default: EM10.state = UNKNOWN;
       }
   }
}

static void reset_FS20 () {
   FS20.bits = -1;
   FS20.data = 0xFF;
   FS20.state = UNKNOWN;
}

static void reset_S300 () {
   S300.bits = -1;
   S300.pos = 0;
   S300.data[0] = 0x1F;
   S300.state = UNKNOWN;
}

static void reset_EM10 () {
   EM10.bits = -1;
   EM10.pos = 0;
   EM10.data[0] = 0x1FF;
   EM10.state = UNKNOWN;
}

static void ook868timeout () {
   if (FS20.state != DONE)
       reset_FS20();
   if (S300.state != DONE)
       reset_S300();
   if (EM10.state != DONE)
       reset_EM10();
}

static void ook868setup () {
   pinMode(PIN_868, INPUT);
   digitalWrite(PIN_868, 1); // pull-up

   // enable pin change interrupts on PC0
   PCMSK1 = bit(0);
   PCICR |= bit(PCIE1);

   /* prescaler 64 -> 250 KHz = 4 usec/count, max 1.024 msec (16 MHz clock) */
   TCNT2 = 0;
   TCCR2A = 0;
   TCCR2B = _BV(CS22);
   TIMSK2 = _BV(TOIE2);
   
   reset_FS20();
   reset_S300();
   reset_EM10();
}

// Poll and return a count > 0 when a valid packet has been received:
//  4 = S300
//  5 = FS20
//  6 = FS20 extended
//  7 = KS300
//  9 = EM10*

static byte ook868poll (byte* buf) {
   if (FS20.state == DONE) {  
       byte len = FS20.bits / 9;
       byte sum = 6;
       for (byte i = 0; i < len; ++i) {
           byte b = FS20.data >> (1 + 9 * i);
           buf[len-i-1] = b;
           if (i > 0)
               sum += b;
       }
       if (sum == buf[len-1]) {
           uint32_t since = millis() - FS20.prev;
           FS20.prev = millis();
           reset_FS20();
           if (since > 150)
               return len;
       }
       
       reset_FS20();
   }
 
   if (S300.state == DONE) {    
       byte n = S300.pos, ones = 0, sum = 37 - S300.data[n], chk = 0;
       for (byte i = 0; i < n; ++i) {
           byte b = S300.data;
           ones += b >> 4;
           sum += b;
           chk ^= b;
           
           if (i & 1)
               buf[i>>1] |= b << 4;
           else
               buf[i>>1] = b & 0x0F;
       }
       
       reset_S300();
       
       if (ones == n && (chk & 0x0F) == 0 && (sum & 0x0F) == 0)
           return n >> 1;
   }
 
   if (EM10.state == DONE) {    
       if ((byte) EM10.data[2] != EM10.seq) {
           byte ones = 0, chk = 0;
           for (byte i = 0; i < 10; ++i) {
               word v = EM10.data;
               ones += v >> 8;
               chk ^= v;
               buf = v;
           }
           
           if (ones == 9 && chk == 0) {
               EM10.seq = EM10.data[2];
               reset_EM10();
               return 9;
           }
       }
       
       reset_EM10();
   }
   
   return 0;
}

ISR(TIMER2_OVF_vect)    { ook868timeout(); }
ISR(PCINT1_vect)        { ook868interrupt(); }

void setup () {
   Serial.begin(57600);
   Serial.println("[TempHumid]\n");
   ook868setup();
}

void loop () {
   byte buf[10];
   byte len = ook868poll(buf);
       
       Serial.print("Packet:");
       for (byte i = 0; i < len; ++i) {
           Serial.print(' ');
           Serial.print(buf, DEC);
       }
       Serial.println();

   }
}

Lectere


Ive done a similar project a while back, and I had to take the doorbell apart and make an antenna....You might want to try that. If its too delicate, then don't bother... :D


You also had the FS20 TK?

Zack_Johnston

#7
Nov 12, 2012, 12:39 am Last Edit: Nov 12, 2012, 12:41 am by Zack_Johnston Reason: 1
I can't find anything wrong with the code. :(

You might want to secure all of your connections. You have probably already done this...

Try looking into the doorbell to see if anything is wrong with it.

No I haven't had the FS20 TK but I tried making a wireless doorbell.

Lectere


I can't find anything wrong with the code. :(

You might want to secure all of your connections. You have probably already done this...

Try looking into the doorbell to see if anything is wrong with it.


Secure connections? what do you mean?

I'm going for new batteries tomorrow...

But still, for a protocol which should be able to do 400 meters, strange that it won't do more than 30 cm...

Zack_Johnston

#9
Nov 12, 2012, 12:48 am Last Edit: Nov 12, 2012, 12:54 am by Zack_Johnston Reason: 1
Secure connections? what do you mean?

I'm going for new batteries tomorrow...

But still, for a protocol which should be able to do 400 meters, strange that it won't do more than 30 cm...
[/quote]

By secure connections, I mean check the wires in the Arduino and make sure they are connected and working. :)

Good idea for the batteries. A while ago you said that you were wondering if you should go for 3v or 5v. I think you should try five because the reception might strengthen and improve.

I agree. It should be able to reach farther than 30 cm....:(

PeterH


I'm going for new batteries tomorrow...


I was about to suggest that. :)
I only provide help via the forum - please do not contact me for private consultancy.

Zack_Johnston

Messege me if you are still having problems tomorrow. Also let me know if it works. Thanks!

Lectere

Tried new batteries, no luck :(

Also, I've paired up the FS20 TK with remote power switch, and it easely switches on from great distance. (3 floors)

I've extended the antenna of the RX868SH-C3 to about 40 centimeter... No luck...

It must be a faulty RX868SH-C3 module. Can't think of anything else... :\

Lectere

Tried;
-getting an other type of RX868 controller from a working FS20 device
Same result, only when I hold the FS20 TK within 20 cm of the RX868 controller, I recieve a complete package.

I've did some other testing, I've connected a LED to digital port, and light it up, every time a interrupt occours.

Using this test setup, I do see a change in the LED when I press the FS20 TK, even over great distance.

So it must be a software thing. Something to so with timers/timing.

PeterH

Could it be that the two radio devices aren't on quite the right frequency/channel or using different encoding? It's pure speculation, but perhaps the radio link would be able to work despite the mismatch if the signal was extremely strong, but not when it is at normal levels.
I only provide help via the forum - please do not contact me for private consultancy.

Go Up