Electronics Projects, ATmega8 AT90S4433 Wireless RF Temperature Transmitter article
"atmega8 projects, avr project, microcontroller projects, " tagged with
And a beautiful project with ATmega8 AT90S4433 your computer from a remote location with the location’s wireless RF system temperature data come Mailbox temperature measured in the test program with garden-temperature condition is displayed on the computer
Wireless RF Temperature Transmitter
By Don Carveth, June 2002
Rev. 2, 7/12/03: Replaced AT90S4433 with an ATMEGA8. Added timing charge capacitor circuit. Using a slowly discharging capacitor instead of the internal clock for the long time delay allows the use of power down sleep mode (instead of idle mode), using effectively no current except when transmitting. The board still drew about 4 mA, 98% from the 5V regulator (compared to 12mA before), so I replaced the 78L05 regulator with a TL750L05 LDO regulator with a 10uF cap on the 5V side – the board now draws 1.2mA. If the regulator is bypassed current is about 0.15 mA. The downside of this timing method is loss of timing accuracy – not an issue in my circumstance. The new c code has the old code commented out. The schematic has also been updated and includes components for both timing methods. Quite a few pins can be freed up if the internal timer method is not used. The capacitor/resistor values chosen allow a max timing duration of about 2 hours. Reduce the capacitor value if this is too high to get better resolution.
Also updated the discussion on RF radio modules and added info on antenna design. Rev. 1, 12/24/02: Update to PC Mailbox software. Check under Mailbox on front page for latest version. Updated C programs to add returning length byte. Now compiles under GCC 3.2 without special header files. Now offering flashed AT90S4433 chips for sale.
Wireless RF Temperature Transmitter Features
Transmits six bytes of data at a fixed interval at 4800 baud using RF radio modules – Radiometrix TXM-433 / SILRX-433 Uses my own “Mailbox” protocol. The receiver is connected to my PC. The Visual Basic software sifts out the noise, decodes the message and presents it in a tabular display (also is an Active-X module).
Monitors on board temperature using a thermistor, 3 remote temperatures using thermistor probes, light level via an on-board photocell and battery voltage.
Enters “idle” mode between transmissions to save power.
Dip switch selectable send interval from 1 second to 2 hours.
Uses TCNT1 cascaded into TCNT0 for the long time delay
Powered by a lithium 10.8V 4500Ah laptop battery. I estimate it will last 3 to 4 weeks between charges.
Uses an AT90S4433 microprocessor with 4 MHz crystal
Programmed in GCC 3.2.
Constructed using wire-wrap technique.
Schematic prepared using Eagle 4.something.
So what am I doing with this little beauty? I can now, from the comfort of my computer room, monitor the temperature of three compost heaps in the back yard. I feel like I’m in a processing plant control room. This project, like most of my projects, was a spin-off from a related task. I had just got my two way RF link from my robot working well. I was starting to prepare my first summer compost heap and the light went on. A week later it was operational. Another week went into tweaking, playing and documenting.
Temperature Transmitter Data Collection
The AT90S4433 has six 10 bit A/D inputs. I utilize all six. When the uC “wakes up” from idle mode, it turns the ADC module on, turns on the voltage divider power, waits 100 milliseconds and then reads the six ports. Each raw value is conditioned and converted to an 8 bit value for transmission.
Temperature is sensed using a 10K nominal thermistor. Thermistors change resistance with temperature so a resistor / thermistor bridge with a fixed 8K resistor was used. Thermistors have a large resistance change over the 32 to 200 F range I was interested in but the resistance vs. Temperature curve is logarithmic, not linear. I used a look-up table to linearize the signal and return a value directly in degrees F. Along the way I did discover that there is really no such thing as a standard “10K nominal” thermistor. Get a curve for the device you buy or you will have to calibrate it yourself.
Light is sensed with a Cadmium Sulphide photocell which also changes resistance, this time with light. I set up a divider with a 2K resistor. The reading swings from 4 or 5 in near dark to 251 in bright sunshine.
Battery voltage is sensed with a resistor divider connected directly to the battery. I installed a 5.1 V Zener on the input “just in case”. The signal is conditioned to return a value in tenths of a volt, i.e. 12 volts reads as 120. I could see that battery life could become a big issue, even with a device that normally draws only 10mA. A standard 800 mAh NiCad AA cell would theoretically last 80 hours. That’s only three days. I decided to use a 4600 Ah lithium laptop battery I had available. Its been running two weeks now and has dropped from 12.1 to 11.4 volts. Should still have two weeks left.
Here is what I see on my PC:
Temperature Transmitter The Radios
I used the TXM-433 transmitter and SILRX-433 receiver from Radiometrix. These are capable of operation at 4800 baud. I purchased these a couple years ago but there are now lower cost modules and higher speed modules available for the same price that I would consider. Here is the result of some research on sources of low cost RF modules. I have not used any of these and cannot vouch for their performance.
The receiving end takes more work, both physically and on the software side. If you are connecting to a PC then you must convert the signal from the RF receiver module to RS-232 using a MAX233 or equivalent. I have a two way set up configured which involves a transmitter and considerably more control complexity. Locate the receiver a ways away from your PC. I located mine outside by a corner of the house and find it works well with the transmitter all over the yard and all over the house.
If you fire up the receiver with no transmitter in operation and take a look at the serial port with a program such as HyperTerminal, you will see a barrage of strange characters. When the transmitter is activated, the receiver “syncs” with the transmitter and much of the noise disappears. So far so good. The problem is that we don’t want the transmitter powered up all the time – it would use far too much power. So when we power it down the garbage returns. Our little tidbits of data get lost in a sea of noise. This situation also exists when doing two way commuication. I attempted to use the CD (carrier detect) to determine if a valid signal had been received but I could not get it working properly. The PC program as supplied does not use CD.
The PC must, therefore, filter out the noise. The VBasic software reads every byte that is received, looking for a valid packet. The “Mailbox” protocol is designed to be simple yet robust enough that only valid data gets through. Each packet is formatted as “UUUUU ::AaDdDdDdDdDd…Xx”. The “U”s are 1010 characters that aid the receiver in synchronizing. The “::” are the start bytes. Until “::” is read, no data is passed. The receiver must know the length of the incoming packet. Once a valid packet is identified bytes are read until this length is reached, then a checksum byte is compared.
Another issue arising from the need to stay synchronized is that characters with long periods without changes, like 0 or 0xFF, can cause the receiver to lose sync. Radiometrics recommends using “5050” characters only – characters with a balance of ones and zeroes. This pretty well kills an 8 bit protocol. Instead I convert to ASCII Hex, then to 5050. ASCII Hex converts the transmitted byte to two characters, i.e. the number 168, which is equivalent to 0xA8 hex, is converted to “A” followed by “8”. “A” and “8” are in turn converted to 5050 before transmission and converted back at the other end. The PC software abandons any packet that contains non-5050 characters.
The Aa and Dd in the packet thus represent the two bytes of the address (ID) and the data. Xx represents the two bytes of the checksum.
At this point it has operated for two weeks, transmitting every half hour and I have not yet seen a bad packet get through. Line of site it may miss a packet a day. If the transmitter is located behind a building it may miss 25%. Because of the reflections it is difficult to predict performance. Sometimes moving the transmitter (or receiver) just a few feet will make a significant difference.
Temperature Transmitter The MicroController
I selected an Atmel AT90S4433 – has enough flash (4K), enough RAM(128 bytes) and has 6 A/D inputs, all in a 28 pin narrow package. The RAM turned out to be a bit tight due to the comm buffers and look-up tables – more on this later. I selected the lowest frequency crystal I had on hand, 4 MHz. I plan to try a 500KHz ceramic resonator to see if it lowers power consumption significantly.
As mentioned above, the uC normally is in an “idle” state. In “idle”, the clock still operates but the rest of the uC is shut down. The clock must run as it is used to calculate the transmit interval.
The long delay is generated using the method discussed in Atmel’s app note (#1268). The TCNT1 (16 bit T/C) output compare is physically tied to an input configured as the clock source for TCNT0 (8 bit T/C). This effectively results in a 24 bit counter, adjustable by the value stored in the TCNT1 output compare register. With a 4 MHz crystal, this gives delays up to 2 hours.
When TCNT0 reaches the overflow point an ISR is triggered which performs all the duties. Once the ISR is complete the program returns to the main loop where the sleep instruction is executed, putting the device back into “idle”.
On reset the uC is initialized – all ports are configured as required, unused pins are configured as inputs with internal pullups, the Mailbox interface routines are initialized and the UART set up. The Send rate DIP switch is read and a single packet is transmitted.
The main routine is called GetAndSend(). It turns on the sensor power, the A/D and the LED, waits for 100 ms, reads the ADC inputs, turns the sensor power, A/D and LED off, then transmits the data packet.
The Mailbox system architecture is multiple master/single slave with the data originating on the slave. I refer to it as multiport/multiprotocol serial RAM and is also applicable for uC to uC communications. The master is normally reading from specific locations in the slave, i.e. the address. It can be configured such that the master, in this case the PC, can also receive fixed length, unsolicited data packets from a slave. The routines used here, contained in mbRFslv.c and mbRFslv.h, are a subset of the complete two way comm software. The slave does not wait for a request but simply transmits its data packet as desired.
The SendMaster() routine loads the six data bytes into the comm buffer and calls SendToMaster(), defind in mbRFslv.c. The address must match whatever is configured at the PC end. SendToMaster adds the sync characters and the “::” start characters. Note that the send routine is not the usual write to the UART then wait till done. The send routine writes a byte then returns to the main routine. As each byte has been transmitted, a UART buffer empty ISR is run which transmits the next character. This method is not really required in this application but is necessary where the Mailbox routines exist within a busy application. Since I had operable, tested code I used it.
I did run into difficulties with the available RAM (128 bytes). GCC stores an initialized constant array in flash and RAM. There is no built-in facility to tell it to store the array in flash only. I had lookup tables for the thermistor curve and for the 5050 conversion. Along with the comm buffers this was rapidly using up my available RAM. I was able to find some routines in the progmem header that allowed the array to be designated as type prog_char. Data can be read from the table using the PRG_RDB macro. This was not ideal but worked satisfactorily. I was able to get this working for single bytes but not for integers. Other compilers apparently have a “flash” data type that accomplishes what I was looking for. It seems to me that the keyword “const” should direct the compiler to store only in flash. The GCC source code is attached.
Construction: I like wire-wrap for one-off type projects such as this. I can wire-wrap a board like this in a couple hours. I find it to be highly reliable and changes can be made fairly easily. I now use a ground and power copper strip that I solder to – I find this goes a little quicker and results in a better power distribution system. I mounted the transmitter board directly on the lithium battery – makes a nice, tidy package. The board has an on-board 5V 78L05 regulator which is powered by the lithium batteries 9 to 12 volts. This could be made more efficient with an LDO regulator and lower voltage battery. The antenna is just a length of copper wire. The length is important – make sure it matches the quarter wave frequency of your transmitter/receiver. Check the documentation that comes with your RF modules.
The PC End: This article is primarily about the transmitter. I will discuss the receiving end software in enough detail to allow one to get the system operational.
I have found that the PC RS-232 port under Windows is not the most robust thing around. On my two PCs with four RS-232 ports only one will work as described here. This was three until I upgraded to XP from Win 98. The bottom line is that many PC ports have difficulty handling the barrage of garbage from the radio module. I have since constructed an interface board to handle this problem but I have not completed documenting this as of this writing.
The Mailbox software is a Windows based object written in Visual Basic 5.0. It’s basic purpose is to read from and write to slave Mailbox uCs using either an RF 5050 protocol (as used in this article) or an 8 bit protocol intended for hardwired applications. The program runs as an Active-X .exe server, which means it can operate standalone, or be called as a reference by another Windows application. The Windows application can request variables (bytes or 16 bit ints supported) from specific Mailbox addresses in the slave or send variables to specific addresses. The Mailbox software handles all of the packetizing, noise filtration, variable parsing, buffering activities.
The Mailbox software can also run in standalone mode. It will then startup with the main monitor screen active. This will allow you to send and receive data packets to/from specific addresses and monitor all incoming/outgoing data traffic. A data scroll screen is also included to watch the data progress over time.
The software needs to be installed like any other Windows application. You can run the program directly or it can be referenced as a component by another program. Also included are the source and executable files for MBTest, a simple program for testing Mailbox as an ActiveX server. The compatibility of this software has not been widely tested, but it does run on my two PCs.
The receiver board consists of the receiver module and an RS-232 level converter (MAX233). The board in the photos has both a receiver and transmitter and is set up for two way communications. Only the receiver is required for this application. I installed the board under a plastic weather guard with just the antenna poking through. I ran an RS-232 cable and a power wire from the PC to the receiver board. At the low baud rates used here you could likely run 100′ or more without problems. The receiver definitely works better when it is distanced from the PC.
Debugging: Debugging comm systems is always a challenge. There are many links in the chain and any one failure will bring the whole train to a halt. I recommend starting with a stripped down system – no radios, connect the transmitter directly to the PC port. You will need a CMOS to RS-232 level converter – I have one built into a serial cord – it’s ideal for this type of testing. Set the send rate at a fast interval, like once a second. If you have HyperTerminal or the Mailbox software running you should see a series of characters that looks like UUUU*ccDdDdDdDdXx once every second. If Mailbox is configured properly it should accept the packet and update the parsed data registers and the data scroll. If this is not working, try enabling the print_info() routine inside of main() and disable the Mailbox send routines.
If you have got this far its time to introduce the radios. Start with the radios together in the same room. I recommend having an oscilloscope on hand to monitor action at the various pins. If it doesn’t work recheck all your connections. I always like to have two of every component so I can check for functionality. Check for comm activity at the transmitter module data in pin and at the receiver module data out. Check if power is applied. Remember that power is disconnected at the transmitter until the transmit ISR is activated.
Operation: Now you can sit back and enjoy the excitement of watching real time data pour in. I set my transmitter up to send every half hour. It is connected to my spare PC, an old 233MMX, which perks along at about 18% load. I plan to try it on an even older 66MHz unit just for grins (and less power consumption). And now I can get back to the robot. Next project is a handheld communicator, with voice recognition, to converse with the robot, using the same RF methodology.
If you have any questions about the article, please contact the author at firstname.lastname@example.org.
source members.shaw.ca/Botgoodies2/TempXmtr/TempXmtr.htm ATmega8 AT90S4433 Wireless RF Temperature Transmitter project files alternative link: atmega8-at90s4433-wireless-rf-temperature-transmitter.rar alternative link3 alternative link4