433Mhz shield on an Arduino Mega2560

315MHz and 433MHz wireless connections are very commonly used by consumer electronics including weather stations, home automation remote controls, power consumption meters, car alarms, and also many DIY projects.
Post Reply
Edgley
Posts: 2
Joined: Mon Apr 08, 2013 10:30 pm

433Mhz shield on an Arduino Mega2560

Post by Edgley » Mon Apr 08, 2013 10:48 pm

Has anyone successfully implemented the receiver shield on an Arduino Mega 2560.

Looking at the data sheets and schematics of both the Uno and the Mega 2560 it seems the ICP are on different pins and have slightly different configurations.

is there some example code I could look at for the Mega 2560?

I plan to couple the weather station data with 8 channels of pulse count captures from power meters so the power usage can be directly compared to the weather conditions.

Any help would be appreciated,
Ray

angusgr
Freetronics Staff
Freetronics Staff
Posts: 853
Joined: Tue Apr 09, 2013 11:19 pm
Location: Melbourne, Australia
Contact:

Re: 433Mhz shield on an Arduino Mega2560

Post by angusgr » Tue Apr 16, 2013 10:52 pm

Hi Edgley,

Sorry for the delay in responding.

Sounds like a fun project, so many power meters!

I'm not sure what you mean by ICP, but the 433 Mhz receiver shield only uses digital pin 8 for receiving data, the same pin on Megas as on smaller Arduinos. So it should be hardware compatible.

The VirtualWire library that we recommend for that shield also uses standard Arduino digitalRead/digitalWrite calls, and the common Timer1, so it should run perfectly on a Mega2560 as well.

If you're using plain avr C code, instead of the Arduino library, to talk to the weather station then you may need to change some of the source code port registers to match the ones for Digital Pin 8 on the Mega2560. This is one of the appeals of the Arduino library, it abstracts away lots of these fiddly details!

Hope this helps,

Angus

Edgley
Posts: 2
Joined: Mon Apr 08, 2013 10:30 pm

Re: 433Mhz shield on an Arduino Mega2560

Post by Edgley » Thu Apr 25, 2013 2:21 am

Plugging in the board and running the code just did not work.
Reading the source code does explain it a lot.
I have successfully tested the receiver on a UNO with no problems.

If you look at the notes at the top of the project file it does explain how it works using the ICP.

On the MEGA2560 the ICP is on a different pin.

Copied from the top of the project file.
/**
* WeatherStationReceiver
*
* Receives and decodes a pulse-width and transition encoded RF
* bitstream, received through a 433MHz receiver module into the PB0
* Input Capture Pin (ICP).
*
* The transmitter is from the La Crosse WS-2355 Weather Station
* package, the RF transmitter is the integrated thermo/hygro station,
* (part number WS-2300-25S), and cable connections between the rain and
* wind sensors are made to the WS-2300-25S unit as it is the central RF
* transmitter. The cable connected rainfall sensor is part number
* WS-2300-16. The cable connected wind speed and direction sensor is
* part number TX20.
*
* Copyright 2009 Marc Alexander <marc.alexander@gmail.com>
* Copyright 2009 Jonathan Oxer <jon@oxer.com.au>
* http://www.practicalarduino.com/project ... n-receiver
*/

The Mega328 only has one ICP which is on D8, the Mega2560 has a few ICPs as follows:
ICP1 - PD4 (Not connected in the Arduino)
ICP3 - PE7 (Not connected in the Arduino)
ICP4 - PL0 (D49 in the Arduino)
ICP5 - PL1 (D48 in the Arduino)

angusgr
Freetronics Staff
Freetronics Staff
Posts: 853
Joined: Tue Apr 09, 2013 11:19 pm
Location: Melbourne, Australia
Contact:

Re: 433Mhz shield on an Arduino Mega2560

Post by angusgr » Wed May 01, 2013 12:30 am

Hi Edgley,
Edgley wrote: If you look at the notes at the top of the project file it does explain how it works using the ICP.

On the MEGA2560 the ICP is on a different pin.
How embarassing, I'm very sorry. I actually never knew about this Input Capture functionality on an AVR (or that WeahterStation program.) I'm especially annoyed because I've written AVR code before to bit-bang this same functionality - clearly unnecessarily!
Edgley wrote: The Mega328 only has one ICP which is on D8, the Mega2560 has a few ICPs as follows:
ICP1 - PD4 (Not connected in the Arduino)
ICP3 - PE7 (Not connected in the Arduino)
ICP4 - PL0 (D49 in the Arduino)
ICP5 - PL1 (D48 in the Arduino)
It seems like you're most of the way through working this out yourself, now!

As you've pointed out, you should be able to use ICP4 or ICP5, with the associated Timer4 or Timer5. The good news is these are both 16-bit timers, pretty much functionally identical to Timer1 on the ATmega328p.

So, ther code changes need to change the timers and the port registers. In the function Init_RF_Interpreters, PORTB/DDRB becomes PORTL/DDRL. For the interrupt routines, anywhere with TIMER1_ becomes TIMER4_. EDIT: ICR1 becomes ICR4, too.

For the timer setup code, it's the same deal. Changing all the '1's to '4's should pretty much do it:

This:

Code: Select all

  TCCR1A = B00000000; //Normal mode of operation, TOP = 0xFFFF, TOV1 Flag Set on MAX
                        //This is supposed to come out of reset as 0x00, but something changed it, I had to zero it again here to make the TOP truly 0xFFFF
  TCCR1B = ( _BV(ICNC1) | _BV(CS11) | _BV(CS10) );
  SET_INPUT_CAPTURE_RISING_EDGE();
  //Timer1 Input Capture Interrupt Enable, Overflow Interrupt Enable
  TIMSK1 = ( _BV(ICIE1) | _BV(TOIE1) );
Becomes something like:

Code: Select all

TCCR4A = 0;
TCCR4B = _BV(ICNC4) | _BV(CS41) | _BV(CS40);
SET_INPUT_CAPTURE_RISING_EDGE();
TIMSK4 = ( _BV(ICIE4) | _BV(TOIE4) );
This block of macros in the header file will need to the same treatment:

Code: Select all

#define INPUT_CAPTURE_IS_RISING_EDGE() ((TCCR1B & _BV(ICES1)) != 0)
#define INPUT_CAPTURE_IS_FALLING_EDGE() ((TCCR1B & _BV(ICES1)) == 0)
#define SET_INPUT_CAPTURE_RISING_EDGE() (TCCR1B |= _BV(ICES1))
#define SET_INPUT_CAPTURE_FALLING_EDGE() (TCCR1B &= ~_BV(ICES1))
Of changing '1's to '4's. I think you probably get the idea. :)

I haven't tested this code, so let me know if you get compiler errors. I've also quite possibly missed one or two other places where Timer1 is mentioned.

To work out any details, the complete datasheets for the ATMega328p and the ATMega2560 are very helpful and can be downloaded from Atmel. You should be able to search for any of the register names (TCCR1B, etc.) mentioned here and see what all the various flags do.

At a glance everything looks equivalent between Timer1 on the ATMega328p, and Timer4 or 5 on the ATMega2560, so it should be quite straightforward, but I could easily have missed some minor detail.

I'll be interested to hear how you go,

Angus

TonyC
Posts: 2
Joined: Wed May 22, 2013 12:26 am

Re: 433Mhz shield on an Arduino Mega2560

Post by TonyC » Wed May 22, 2013 12:50 am

Angus -

Thanks for the help. Not being very familiar with timers, interrupts and registers, this would have taken much longer to figure out without your post.

With the 433MHz shield wired to the Mega like this: pin 6 to pin 43, pin 7 to pin 42, and pin 8 to pin 49, I had to make the following code changes to the Practical Arduino WeatherStationReceiver sketch (in addition to your changes):

In the Init_Ports function, comment out the DDRL code, and instead use pinMode to set the above three pins. (pinMode(49, INPUT); pinMode(42, OUTPUT); pinMode(43, OUTPUT);) I could have figured out the direct port manipulation method for Port L on the Mega, but pinMode took me far less time.

The Init_RF_Interpreters function also sets up the ICP and LED pins (don't know why they repeat the Init_Ports functionality), so I simply commented-out the DDR and PORT calls.

All should then work well on the Mega.

For those trying to integrate a simple wireless thermometer (e.g. La Crosse TX6U, or similar), the WSR_RFPACKETBITSIZE needs to be set to 44 in the .h file. You'll then receive data, but will still need to re-map the information (station ID, temp, etc.). Stay tuned, I'm working that now...

Thanks again -

Tony

angusgr
Freetronics Staff
Freetronics Staff
Posts: 853
Joined: Tue Apr 09, 2013 11:19 pm
Location: Melbourne, Australia
Contact:

Re: 433Mhz shield on an Arduino Mega2560

Post by angusgr » Wed May 22, 2013 4:16 am

Hi Tony,

Excellent news, glad those pointers were of use and you got it working. Thanks for posting the last pieces of the puzzle.

If you have a fully working modified source file that you could somewhere (either in a [

Code: Select all

 section here on the forums or using a server like pastebin.com or github.com) that'd be a great thing to share with anyone else trying to solve the same problem.

Good luck with your wireless thermometer project!

- Angus

TonyC
Posts: 2
Joined: Wed May 22, 2013 12:26 am

Re: 433Mhz shield on an Arduino Mega2560

Post by TonyC » Wed May 22, 2013 10:31 pm

Hi Angus -

Here's the code for the changes I noted above. After making your changes to move from ICP1 to ICP4, change the Init_ports function to:

Code: Select all

void Init_Ports()
{
//  DDRL = 0x2F;   // B00101111  (Commented-out)

//  Pin Mode calls, instead

    pinMode(49, INPUT);  // ICP 4 / PL0 - INPUT mode explicitly disables pullup
    pinMode(42, OUTPUT); // PL7 to shield D7 Red LED
    pinMode(43, OUTPUT); // PL6 to shield D6 Green LED

}
Remember to also comment-out the DDR and PORT calls in the Init_RF_Interpreters function:

Code: Select all

// DDRL  &= ~(1<<DDL0);    //PBO(ICP1) input
// PORTL &= ~(1<<PORTL0);  //ensure pullup resistor is also disabled

//DDRD |= B11000000; //(1<<PORTD6);  //DDRD |= (1<<PORTD7); (example of B prefix)
That's it! Combined with your changes, the Weather Station software will work with your 433MHz shield on a Mega. Of course, the shield must be connected as described earlier. Those using headers to stack the shield might want to clip pins D6, D7 and D8.

I've got the TX6U changes figured out to correctly map the station ID and temperature data. I'll post those code changes, too.

Tony

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests