Thursday, 19 January 2012

Wireless sensor node - rf link working (2)

Good news! I have managed to get my RF link working! (Part 1 of this series)

Here are the pictures:

1) The RF base station receiver.


2) The RF transmitter - powered by 3x AA batteries.


OK, so what did it take to get this working?

0) You may wish to read my previous post about getting started with ATtiny85.

1) Two versions of the Arduino IDE.
  • Arduino 0022 - I use this for programming the Arduino and ATTiny
  • Arduino 1.0 - I use this to set the clock on the ATTiny
2)  The config files to add support for ATTiny. I used a combination of 3 distributions.
  • damellis-attiny-6bff522.zip - This adds support for ATTiny85 to Arduino 1.0.
  • attiny45_85.zip - This adds support for ATTiny85 to Arduino 0022.
  • manchester.zip - This contains the RF link library along with some modified attiny45_85 files which need to be extracted and used to overwrite the files from attiny45_85.zip. This file is from this thread.
NOTE: Combining the last two of these is a bit awkward so I have combined them into a new zip file which I have hosted here. The contents of manchester.zip\manchester\hardware should be unzipped into your <sketchbook-location>\hardware folder.

EDIT (29/01/2012) - The latest files are now available here.

However, you will still need to get the damellis file to get Arduino 1.0 support.

3) Use Arduino 0022 to program your Arduino as an ISP using the ArduinoISP example.

4) In Arduino 1.0 select the correct ATTiny board and programmer.

Tools -> Board -> ATtiny 85 (internal 8Mhz clock)
Tools -> Programmer -> Arduino as ISP

Set the clock speed by choosing Tools -> Burn Bootloader.

5) Use Arduino 0022 to program your ATTiny. Remember to choose the correct board.

Tools -> Board -> ATtiny85 (/w Arduino as ISP)

Here is the ATtiny85 project which I programmed my ATtiny with: https://github.com/mchr3k/arduino/tree/master/wsn_attiny

The only interesting point with the main .pde file is that the #include of the MANCHESTER.h file uses "" instead of <> (#include "MANCHESTER.h"). I had to change this from the example included with the manchester.zip file.

6) Use Arduino 0022 to program your Arduino. Remember to choose the correct board, "Arduino Uno" in my case.
____

Wiring up the actual circuits was straightforward.

The result of all of this was an ATtiny85 which was able to send a count back to the base station over the RF link. I carried the transmitter around the house and the link mostly worked great. Some numbers came through wrong but the vast majority came through fine and the link recovered after each transmission error.

Next steps? I think it's time to write some code to add error detection and possibly correction to the link.

27 comments:

  1. I've been following these instructions - thanks for the detail and the repackaged files!

    One issue though - you have to reprogram the ATTiny85 to use the 8MHz clock, not the 1MHz clock.

    ReplyDelete
  2. Good point! That's what I meant. I have fixed it now.

    ReplyDelete
  3. Very helpful, thanks ! Is it possible to use 1Mhz internal clock instead of 8Mhz (to reduce power consumption) ?

    ReplyDelete
  4. That would be fine but you would have to adjust the constants in the Manchester library to make the timings correct. You might need to reduce the bit rate a bit.

    ReplyDelete
  5. So, what is the value for for TCCR1 with 1Mhz ?
    #if defined( __AVR_ATtinyX5__ )
    TCCR1 = ? ;
    TIMSK = 0;
    #endif
    ?
    Thanks :)

    ReplyDelete
    Replies
    1. I think you want to do 1MHz TX which should just work without any code changes.

      For reference here is the change you would need to make to https://github.com/mchr3k/arduino-libs-manchester/blob/master/MANCHESTER.cpp to enable RX at 1MHz.

      #if defined( __AVR_ATtinyX5__ )
      /*Timer 1 is used with a ATtiny85. The base clock is 1MHz. We use a 1/16 clock divider which gives 16uS per count.

      1 / (8,000,000 / 128) = 16uS/count
      1,000 / 16 = 62.5 counts/bit

      At this rate we expect 62.5 counts/bit.

      http://www.atmel.com/dyn/resources/prod_documents/doc2586.pdf
      */
      TCCR1 = _BV(CTC1) | _BV(CS13) | _BC(CS10); //counts every 16 usec with 1Mhz clock
      OCR1A = 4; // interrupt every 5 counts (0->4)
      TIMSK = _BV(OCIE1A); // Turn on interrupt
      TCNT1 = 0; // Set counter to 0
      #else

      Delete
  6. I can't seem to get the RX code to run on attiny85. I think it may have something to do with the interrupts.

    ISR(TIMER2_COMPA_vect) is for ATMega
    ISR(TIM1_COMPA_vect) is for ATTiny

    Is this correct? Even when I make this change I can't seem to get it working. Here's my test RX code:

    #include

    void setup()
    {
    pinMode(1, OUTPUT);

    // Set digital TX pin
    MANRX_SetRxPin(0);
    // Prepare interrupts
    MANRX_SetupReceive();
    // Begin receiving data
    MANRX_BeginReceive();
    }

    void loop()
    {
    if (MANRX_ReceiveComplete())
    {
    //light up an LED
    digitalWrite(1, HIGH);
    unsigned int data = MANRX_GetMessage();
    MANRX_BeginReceive();
    }
    }

    Thanks,

    ReplyDelete
    Replies
    1. I have never tested RX on an ATtiny85. However, it sounds like you are doing the right thing. Are you sure you have configured your ATtiny85 to run at 8Mhz?

      Delete
    2. Yes. I've debugged it as much as I can, but I'm no pro with AVRs. I ended up using the original code that you based your implementation on (carl47's).

      I'm still eager to get your implementation going, but I don't know where to go next...

      Delete
    3. When I was originally developing the code I added extra variables into the receiving code to expose a bit more of the internal state. Things like counters of the largest number of bits received helped me to distinguish between cases where the signal was just a little out of sync or completely wrong. However, it is simply very difficult to debug code on these micro controllers.

      Delete
    4. I also wanted to use receiver on attiny85, and it also does not work for me.
      What I have found out is that delay(1000) executed before:
      MANRX_SetupReceive();
      lasts 1 second, and delay(16000) after that line also lasts 1 second (delay(8000) lasts 0.5 seconds.
      I think this might point to some problem with timer, but I am not such expert.
      Can you point us/me what might be problem?

      Thank you

      Delete
    5. The change in timer duration is because the call to SetupReceive (https://github.com/mchr3k/arduino-libs-manchester/blob/master/MANCHESTER.cpp) configures Timer1 on the ATTiny85. This is the same timer used to control how long a sleep lasts. I don't know whether using this Timer could cause the Manchester RX code to break.

      Delete
  7. i use this to make a wireless motion sensor device, i wanna thank you a lot for publishing your progress. i'm gonna publish mine in a step by step guide (in instructables) and send all the people to your blog. :)

    ReplyDelete
    Replies
    1. I'm glad this blog was helpful for you! I look forward to seeing your instructable - please post a link here :)

      Delete
  8. I am trying to use an attiny84 at 8hz and it doesnt have the proper prescaler to do a 62.5 counts/bit.. what do I need to change in the code to allow a different count/bit ratio since i cant get the receiver to work? The two closest prescalers I can set TCCR1B to is is 64 and 256. Can you help out?

    ReplyDelete
    Replies
    1. i set the tccr1b prescaler to 256 and changed the microsecond delays in the sendone and sendzero methods from 1000 microseconds to 2000 microseconds and got the receiver to work but I am not exactly sure how it happened. I am using your old manchester library without the interrupt based receiving.

      thanks.

      Delete
    2. 1 / (8,000,000 / 256) = 32uS/count
      2000 / 32 = 62.5 counts/bit

      Delete
  9. Hi...

    I just bought a ATtiny85 today... first time outside of the Arduino system :)

    I've set up the transmitter to work with the ATtiny85, but when I'm trying to receive with my Arduino Uno I just get this...

    9359
    25743
    37455

    I use 'unsigned int data = MANCHESTER.Receive();' to receive...

    Any comments on what Im doing wrong?

    Great job on the MANCHESTER library!

    ReplyDelete
    Replies
    1. I suggest you try my up to date manchester library: https://github.com/mchr3k/arduino-libs-manchester. There are docs on that page about how to send/receive data.

      Delete
  10. Hello,

    Trying to use this with Arduino 1.0.1 and your latest library and the ATTiny84, not the 85. after modifying the #if defined to __AVR_ATtiny84__)I get the following: TCCR1 was not declared in this scope. then CTC1, CS13,TIMSK.

    Clearly I am hacking my way through this. What modifications will help this to work on the ATtiny84?

    ReplyDelete
    Replies
    1. Sorry but I'm not sure and I don't have any ATTiny84 to try myself. You're in your own - good luck!

      Delete
  11. This comment has been removed by the author.

    ReplyDelete
  12. Hello, I am trying to make a simple communication between an Attiny85 and an Arduino Nano using a standard 433 Mhz Tx/Rx.

    I have managed to send and receive with the old library (even though the data received is not what I was sending) but when I tried to use the new library on any of my Arduino IDEs ( 1.0 and 0022) they don't recognize the library. I have followed all the steps as you say but the new library don't load in any of the Arduino IDEs.

    What am I doing wrong?

    Thanks

    ReplyDelete
  13. Is this also available/working for Tiny84?

    ReplyDelete
    Replies
    1. This should work now: https://github.com/mchr3k/arduino-libs-manchester/pull/6

      Delete
  14. I have followed all the instructions here and now end up with these compile error messages:
    Attiny85_Manchester_TX.cpp: In function 'void doSendMsg(unsigned int, unsigned char)':
    Attiny85_Manchester_TX:148: error: 'class MANCHESTERClass' has no member named 'TransmitBytes'

    This happens on IDE 22
    Any clues on what maybe the problem?
    When I try out the TX library example then I get this:
    manchesterT.cpp:1:24: error: MANCHESTER.h: No such file or directory
    manchesterT.cpp: In function 'void setup()':
    manchesterT:8: error: 'MANCHESTER' was not declared in this scope
    manchesterT.cpp: In function 'void loop()':
    manchesterT:14: error: 'MANCHESTER' was not declared in this scope

    Thanks
    Thanks

    ReplyDelete
    Replies
    1. It sounds like you don't have MANCHESTER.h in the right place. You should make sure to follow the instructions on this page: http://mchr3k.github.io/arduino-libs-manchester/

      Delete