Wednesday, 29 February 2012

Wireless sensor node - prototype node (9)

It's finally time to build my first proper prototype wireless sensor node. The components are as follows:
  • CR2032 3V battery + battery holder
  • ATtiny85 MCU + 8 pin socket
  • TMP36 temperature sensor + 3 pin female header
  • 315MHz RF TX module + 4 pin female header
  • A small amount of tripad board
The process of soldering these parts together went quite smoothly. And yes, that is some beer brewing beside me!


 The results without any parts in place looks like this.


And this is what it looks like with all the parts in place.


I'm fairly pleased with how neat the soldering turned out.


Sadly having built this I found that the RF TX no longer worked reliably and the temperature sensor wasn't reporting accurate readings! This required some software fixes!

1) Fixing the RF TX

I have historically used a scheme where I sent three 16 bit values and then combined them at the receiver. However, the Manchester lib now supports sending longer messages so I've retired my pointless message combining code and simply send a single longer message.

2) Getting accurate readings out of the TMP36

The basic method for getting temp readings is as follows.

  int sensorValue = analogRead(TmpPin);
  // Constant: 5000 / 1024
  float milliVolts = sensorValue * 4.8828125;
  float tempC = (milliVolts - 500) / 10;
  return tempC;


The crucial change to make when running on an ATtiny85 is to change the constant which adjusts for the reference voltage being used which in my case is certainly not 5V!

First, add the following to your setup method. This tells the ATtiny85 to use the internal 1.1V reference voltage in preference to the VCC which will change as our battery runs down.

  // Select the 1.1V internal ref voltage
  analogReference(INTERNAL);


Secondly, update the temp reading code as follows.

  int sensorValue = analogRead(TmpPin);
  // Constant: 1100 / 1024
  float milliVolts = sensorValue * 1.07421875;
  float tempC = (milliVolts - 500) / 10;
  return tempC;

3) Getting more accurate readings out of the TMP36

The ATtiny85 internal 1.1V reference voltage isn't very accurate so it's worth calibrating the constant you are using. To do this I took a temperature reading from the TMP36 when connected to my ATtiny85 and when connected to an Arduino Uno. I then used the following formula:

V_calib = V_base * ((T_ref + 50) / (T_base + 50))
V_base = 1100
T_ref = temp as measured on Arduino Uno
T_base = temp as measured on ATtiny85

I ended up with V_calib = 1028 which gave me fairly accurate temp readings.

The results?

A working wireless sensor node! (I have added a ~20cm antenna wire since the previous pictures)



I have tested this node briefly but I won't deploy it until I do some more work.

For the wireless sensor node I want to build an enclosure.

For the base station I want to build an enclosure and write code to handle storing readings and allowing download over bluetooth.

As ever, the Arduino code is available on Github:

37 comments:

  1. Hello
    I have download your library modified Manchester, but I cannot seem to make it work . I have 1 Attiny45 8Mhz ( internal OSC. ) for the TX with RF 315Mhz ( http://www.seeedstudio.com/depot/315mhz-rf-link-kit-p-76.html?cPath=139_140 ) and Arduino Uno for RX .

    Sketch TX :

    #include

    void setup()
    {
    MANCHESTER.SetTxPin(1);
    }

    void loop()
    {
    unsigned int data = 1234;
    MANCHESTER.Transmit(data);
    delay(100);
    }

    Sketch RX :

    #include

    void setup()
    {
    MANRX_SetRxPin(4);
    MANRX_SetupReceive();
    MANRX_BeginReceive();
    Serial.begin(9600);
    }

    void loop()
    {
    delay(1);
    if (MANRX_ReceiveComplete())
    {
    unsigned int data = MANRX_GetMessage();
    MANRX_BeginReceive();
    Serial.print("data");
    Serial.println(data);
    }
    }
    Can you tell me what's wrong? Thanks

    ReplyDelete
    Replies
    1. There are a number of reasons why this might not work for you.

      Are you sure the ATtiny45 is actually configured to run at 8MHz? Have you tried sending a simple on/off signal without the Manchester library e.g. on for 1 second, off for 1 second. Your RX node could then poll the received value more frequently (e.g. 10 times a second) to validate that you receive the expected on/off value at the expected rate.

      What kind of aerial are you using?

      Delete
  2. Hi Martin,

    Thought you might be interested in my version, which is basically a remake of yours. Had been meaning to do something similar for a while but seeing yours spurred me into action.

    I put the code on github at https://github.com/fasaxc/WirelessSensorNode. I thought about just using your code but part of the fun for me was writing it myself so I ended up starting over.

    Haven't done much on the logging end yet, I'm just using an Arduino to decode the manchester encoding and spit it out to the serial port. I have a little server box that's just logging the output to disk for now.

    -Shaun

    ReplyDelete
  3. I really like your laser cut box - its very nice looking. I might try making something like that for one of my future wireless sensors.

    I've not done much with my wireless sensors in a while as I'm waiting for my Raspberry Pi (due in the next few days) to be my always on home server for uploading readings to the Internet (probably to Pachube).

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Thank you for the information you are sharing, it helps me a lot for my project.

    I have one question though...

    If I set ATtiny85 to run at 1MHz (To save battery), what do I need to change on my arduino in order to sync with the transmission?

    I tried set ATtiny85 to 1MHz without changing anything on Arduino and it doesn't seem to pick up any data.. (ATtiny is for sending data, Arduino is for receiving)

    Can you please give me some advice?
    Thank you :)

    ReplyDelete
    Replies
    1. There is a comment on this post which should help you: http://mchr3k-arduino.blogspot.co.uk/2012/01/wireless-sensor-node-part-2.html

      Delete
  6. Hello,
    i've spend numerous ammount of time, trying to make this library work with my hw.
    I've set up attiny85+DHT11 as transmitter - transmitting temperature from sensor. -> OK
    For receiver i use arduino UNO - i'm never getting any interrupts and i never reach body of MANRX_ReceiveComplete().
    Unfortunatelly tutorials, that are listed with code are not obvious. Can you make explanation - what do we put to setup and loop() ?

    ReplyDelete
    Replies
    1. The code i use:

      #include
      byte ledPin = 3;
      void setup()
      {
      pinMode(ledPin, OUTPUT);
      Serial.begin(115200);
      MANRX_SetRxPin(4);
      MANRX_SetupReceive();

      MANRX_BeginReceive();
      }

      void loop()
      {
      delay(1);
      if (MANRX_ReceiveComplete())
      {
      MANRX_BeginReceive();
      Serial.println("recv complete");

      digitalWrite(ledPin, HIGH);
      unsigned int data = MANRX_GetMessage();
      Serial.println(data);
      delay(1000);
      digitalWrite(ledPin, LOW);
      delay(1000);
      }

      delay(100);
      }

      Delete
    2. This is my code: https://github.com/mchr3k/arduino/blob/master/wsn_arduino/wsn_arduino.ino

      recordReceivedData() is the method which handles the message reception. Note that I had to call delay(1) before the MANRX_ReceiveComplete() line for reasins which I never understood.

      You must call GetMessage *before* calling BeginReceive again.

      Delete
  7. So HelloManchester will be:

    TX:
    #include

    int txPin = 4;

    void setup()
    {
    MANCHESTER.SetTxPin(txPin);
    }

    void loop()
    {
    MANCHESTER.Transmit(11111111);
    delay(5000);
    }

    RX:
    #include

    void setup()
    {
    pinMode(ledPin, OUTPUT);
    Serial.begin(115200);
    MANRX_SetRxPin(4);
    MANRX_SetupReceive();
    MANRX_BeginReceive();
    }

    unsigned int data;
    void loop()
    {
    delay(1);
    if (MANRX_ReceiveComplete())
    {
    data = MANRX_GetMessage();//you said to call getmessage before executing next one
    MANRX_BeginReceive();
    Serial.println(data);
    data = MANRX_GetMessage();
    Serial.println(data);
    }
    }

    ReplyDelete
    Replies
    1. Or even RX is smaller:

      #include

      void setup()
      {
      Serial.begin(115200);
      MANRX_SetRxPin(4);
      MANRX_SetupReceive();
      MANRX_BeginReceive();
      }

      unsigned int data;
      void loop()
      {
      delay(1);
      if (MANRX_ReceiveComplete())
      {
      data = MANRX_GetMessage();//you said to call getmessage before executing next one
      Serial.println(data);
      MANRX_BeginReceive();
      }
      }

      Delete
    2. This looks fine to me. Does it work for you?

      If not you may have a hardware problem which I can't easily help you with.

      Delete
    3. Nope.

      I will check profiles, that i'm using, but it's like:
      arduino uno (atmgea328 + external 16mhz crystal)
      attiny85-PU (8MHZ internal + BOD disabled).

      1) I will try to re-upload code to attiny using your hardware.txt profiles.

      2) And i will check what is transmitted for 11111111, and if it is recieved correct with digitalRead().

      3) One thing that i didnt think about is my transmitter receiver:
      http://www.ebay.com/itm/433Mhz-RF-transmitter-and-receiver-link-kit-for-ARM-MCU-WL-/230838475678?pt=LH_DefaultDomain_2&hash=item35bf0b9b9e

      Maybe there is issue with current type of transmitters.


      Delete
    4. (2) This sounds like the right approach. You are ultimately going to have to read and understand the Manchester code to understand how it should work.

      (3) Your TX/RF look fine.

      Delete
    5. Ok, still no signal, but i'm getting some progress.
      I've put output of received signal and find out that i need pulldown resistors for both TX and RX.
      I've tried clean arduino with your sketch, but didn't help.
      Well try something else tommorow. :)

      Delete
  8. Hi, I have some doubts about the physical connection of the RF module and the TMP36. The following pinout is right?

    Thanks in advance!

    RF TX Data pin -> ATTiny 85 P4 (Physical pin 3)
    RF TX Vcc pin -> ATTiny 85 P3 (Physical pin 2)
    RF TX GND pin -> Battery GND
    TMP36 Vcc pin -> ATTiny 85 P1 (Physical pin 6)
    TMP36 GND Pin -> Battery GND
    TMP36 Data pin -> ATTiny 85 P2 (Physical pin 7)

    ReplyDelete
    Replies
    1. https://github.com/mchr3k/arduino/blob/master/wsn_attiny/wsn_attiny.ino

      // ATTiny85:
      // u
      // Reset (1) (8) VCC
      // P3 (A3) (2) (7) P2 (A1)
      // P4 (A2) (3) (6) P1 (PWM)
      // GND (4) (5) P0 (PWM)
      //
      // Temp calibration formula:
      // V_calib = V_base * ((T_ref + 50) / (T_base + 50))

      #define TmpPin 1 // Analog pin 1 - digital pin 2
      #define TmpDPin 2
      #define TmpPwr 1
      #define TxPin 4
      #define TxPwr 3

      Looks like you have it correct :)

      Delete
  9. Hi there,

    first of all I think that your project is cool. To me it looks both cute and polished and it used as few parts as seems reasonable.

    I have some questions because I'd like to build something similar in order to control our heating at home.
    1. What is the distance of the radio signal (in a house), i.e., can it pass, say, three walls and make it to a receiver that is 20 meters (60 feet) away?
    2. Can you distinguish more than one sender, i.e., does your thermometer have a unique ID that is transmitted together with the temperature?
    3. How long does the battery last?
    4. Would a change to, say, two AA batteries make the circuit more complex?

    As you can see from my questions, I'm quite new to the biz :) but I hope you dont mind answering.

    Thanks in advance!

    ReplyDelete
    Replies
    1. 1) You should be able to get it through a couple of walls.
      2) Yes I send a unique ID as part of my data from a wireless node.
      3) I have got battery life calculations in another blog post.
      4) Changing the battery type shouldn't make too much difference but you will need to make sure the voltage is in an acceptable range.

      Delete
  10. Hi, I am using a 315Mhz RF Link and an ATtiny85 to duplicate what you did (I use the ATtiny85 at the transmitter side, and UNO at the receiver side). I downloaded the all the code from:
    https://github.com/mchr3k/arduino

    I followed all the steps from your posts, so I already configured ATtiny to 8Mhz (I use arduino 1.0 to configuration, and 2.2 to program ATtiny), am able to program it in ISP mode, changed the hfuse. But when I compiled code wsn_attiny from: https://github.com/mchr3k/arduino/blob/master/wsn_attiny/wsn_attiny.ino

    I always have these error messages:
    C:\Softwares\arduino-0022\libraries\Manchester\MANCHESTER.cpp: In function 'void MANRX_SetupReceive()':
    C:\Softwares\arduino-0022\libraries\Manchester\MANCHESTER.cpp:195: error: 'TCCR2A' was not declared in this scope
    C:\Softwares\arduino-0022\libraries\Manchester\MANCHESTER.cpp:195: error: 'WGM21' was not declared in this scope
    C:\Softwares\arduino-0022\libraries\Manchester\MANCHESTER.cpp:196: error: 'TCCR2B' was not declared in this scope
    C:\Softwares\arduino-0022\libraries\Manchester\MANCHESTER.cpp:196: error: 'CS22' was not declared in this scope
    C:\Softwares\arduino-0022\libraries\Manchester\MANCHESTER.cpp:196: error: 'CS21' was not declared in this scope
    C:\Softwares\arduino-0022\libraries\Manchester\MANCHESTER.cpp:197: error: 'OCR2A' was not declared in this scope
    C:\Softwares\arduino-0022\libraries\Manchester\MANCHESTER.cpp:198: error: 'TIMSK2' was not declared in this scope
    C:\Softwares\arduino-0022\libraries\Manchester\MANCHESTER.cpp:198: error: 'OCIE2A' was not declared in this scope
    C:\Softwares\arduino-0022\libraries\Manchester\MANCHESTER.cpp:199: error: 'TCNT2' was not declared in this scope

    Please give me some hint, what is wrong here. Thanks a lot.

    ReplyDelete
    Replies
    1. I fixed this, but now I always receive 0s.

      Delete
    2. Hi,
      I have the same problem when compiling. How did you fix it?

      David.

      Delete
    3. I have the same problem too? any news?

      Delete
  11. Hi, I have a question: is possible change the temperature sensor by a relay and connect this one to a light switch?

    ReplyDelete
    Replies
    1. What do you mean by "change the temperature sensor"?

      Delete
  12. Thanks for the information. I found this when I was trying to investigate variations in the internal voltages of the ATTiny range.
    I realise you did this a while ago, but I've written a calibration code for ATTiny, which might be useful to you or others.
    To use it you upload the code to your device, apply a known voltage to the input and it calcualtes the internal reference. This is then stored into EEPROM as a milliVolt reading.
    This can then be read when you upload new code and can help improve measurement accuracy.
    I found the 2.56V reference was actually 2.473V on my IC, which is within specifications, but meant all my caluclations were incorrect.
    Its in a blog post here:
    http://www.re-innovation.co.uk/web12/index.php/en/blog-75/264-accurate-voltage-measurment

    Cheers, Matt.

    ReplyDelete
    Replies
    1. Thanks - that looks really interesting!

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

    ReplyDelete
  14. Hi,
    I have already blogged about this but just in case it isnt noticed I am asking again just in case it slipped by:-

    My problem is that although I can get the Manchester code to compile for an UNO it fails for a ATtiny85. I get the following compile errors:

    C:\Documents and Settings\David\My Documents\Arduino\arduino-1.0.5\libraries\Manchester_1\Manchester.cpp: In function 'void MANRX_SetupReceive(uint8_t)':
    C:\Documents and Settings\David\My Documents\Arduino\arduino-1.0.5\libraries\Manchester_1\Manchester.cpp:366: error: 'TCCR2A' was not declared in this scope
    C:\Documents and Settings\David\My Documents\Arduino\arduino-1.0.5\libraries\Manchester_1\Manchester.cpp:366: error: 'WGM21' was not declared in this scope
    C:\Documents and Settings\David\My Documents\Arduino\arduino-1.0.5\libraries\Manchester_1\Manchester.cpp:371: error: 'TCCR2B' was not declared in this scope
    C:\Documents and Settings\David\My Documents\Arduino\arduino-1.0.5\libraries\Manchester_1\Manchester.cpp:371: error: 'CS21' was not declared in this scope
    C:\Documents and Settings\David\My Documents\Arduino\arduino-1.0.5\libraries\Manchester_1\Manchester.cpp:371: error: 'CS20' was not declared in this scope
    C:\Documents and Settings\David\My Documents\Arduino\arduino-1.0.5\libraries\Manchester_1\Manchester.cpp:372: error: 'OCR2A' was not declared in this scope
    C:\Documents and Settings\David\My Documents\Arduino\arduino-1.0.5\libraries\Manchester_1\Manchester.cpp:379: error: 'TIMSK2' was not declared in this scope
    C:\Documents and Settings\David\My Documents\Arduino\arduino-1.0.5\libraries\Manchester_1\Manchester.cpp:379: error: 'OCIE2A' was not declared in this scope
    C:\Documents and Settings\David\My Documents\Arduino\arduino-1.0.5\libraries\Manchester_1\Manchester.cpp:380: error: 'TCNT2' was not declared in this scope

    I am pretty sure its because I am missing a Core file or two somewhere. But I have downloaded lots of core stuff too and it still doesnt work.

    Can anyone advise on a procedure for library and core files that they used which worked?

    Thanks,

    David.

    ReplyDelete
  15. Good afternoon, I'd like to know how can I upload the sketch in my attiny85, when I compile(board=attiny85 programer=arduinoasISP) I always have errors like this:

    C:\Program Files (x86)\Arduino\libraries\manchester\Manchester.cpp: In function 'void MANRX_SetupReceive(uint8_t)':
    C:\Program Files (x86)\Arduino\libraries\manchester\Manchester.cpp:366: error: 'TCCR2A' was not declared in this scope
    C:\Program Files (x86)\Arduino\libraries\manchester\Manchester.cpp:366: error: 'WGM21' was not declared in this scope
    C:\Program Files (x86)\Arduino\libraries\manchester\Manchester.cpp:371: error: 'TCCR2B' was not declared in this scope
    C:\Program Files (x86)\Arduino\libraries\manchester\Manchester.cpp:371: error: 'CS21' was not declared in this scope
    C:\Program Files (x86)\Arduino\libraries\manchester\Manchester.cpp:371: error: 'CS20' was not declared in this scope
    C:\Program Files (x86)\Arduino\libraries\manchester\Manchester.cpp:372: error: 'OCR2A' was not declared in this scope
    C:\Program Files (x86)\Arduino\libraries\manchester\Manchester.cpp:379: error: 'TIMSK2' was not declared in this scope
    C:\Program Files (x86)\Arduino\libraries\manchester\Manchester.cpp:379: error: 'OCIE2A' was not declared in this scope
    C:\Program Files (x86)\Arduino\libraries\manchester\Manchester.cpp:380: error: 'TCNT2' was not declared in this scope

    Do you know why? and how can I compile and upload? thak you

    ReplyDelete
  16. great job, hope you innovate new things Good luck

    WiFi

    ReplyDelete
  17. Hi mchr ---- I admire your work... especially your Wireless sensor node. I don have exactly same environment as you and maybe that why I am not successful. Would you mind if I ask you for help? Just quick information. Raspberry is a programmer for attiny85 like in these tutorial http://www.instructables.com/id/Programming-the-ATtiny85-from-Raspberry-Pi/ attiny85 should be connected to ds18b20 and 433 transmitter. But I am not able to find which libraries should I use. Everything is write for arduino. Many thanks for your response. donvonhill

    ReplyDelete
  18. Thank you for sharing this very informative post


    wireless control systems


    ReplyDelete
  19. Hi! is there any way to get the schematics for this project?

    ReplyDelete
  20. This comment has been removed by the author.

    ReplyDelete
  21. Hi Martin,

    I am trying to contact you in regards to a wireless sensor node project. Do you have an email I can contact you on?

    See my work and contact info here - www.ben-dror.com

    ReplyDelete