- 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 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.
// 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:





Hello
ReplyDeleteI 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
There are a number of reasons why this might not work for you.
DeleteAre 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?
Hi Martin,
ReplyDeleteThought 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
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.
ReplyDeleteI'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).
This comment has been removed by the author.
ReplyDeleteThank you for the information you are sharing, it helps me a lot for my project.
ReplyDeleteI 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 :)
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
DeleteHello,
ReplyDeletei'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() ?
The code i use:
Delete#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);
}
This is my code: https://github.com/mchr3k/arduino/blob/master/wsn_arduino/wsn_arduino.ino
DeleterecordReceivedData() 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.
So HelloManchester will be:
ReplyDeleteTX:
#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);
}
}
Or even RX is smaller:
Delete#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();
}
}
This looks fine to me. Does it work for you?
DeleteIf not you may have a hardware problem which I can't easily help you with.
Nope.
DeleteI 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.
(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.
Delete(3) Your TX/RF look fine.
Ok, still no signal, but i'm getting some progress.
DeleteI'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. :)
Hi, I have some doubts about the physical connection of the RF module and the TMP36. The following pinout is right?
ReplyDeleteThanks 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)
https://github.com/mchr3k/arduino/blob/master/wsn_attiny/wsn_attiny.ino
Delete// 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 :)
Hi there,
ReplyDeletefirst 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!
1) You should be able to get it through a couple of walls.
Delete2) 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.
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:
ReplyDeletehttps://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.
I fixed this, but now I always receive 0s.
Delete