Compatibility between Mega and UNO?

I am sure this has been covered here before however just about to get a Arduino and would like to know how compatible the Mega and UNO models are. They is not a large amount of money difference between the two but do not want to head the Mega path only to find compatibility issues like shields work on one and not the other etc.

I realise the differences from a hardware perspective as I am a retire electronics engineer so thing like a DIP and SMD package for the micro are understood.

What I would like to know is where there maybe any gotchas between the two.

Would both work on the same compiled code? ( sorry I am a code novice)

Are the shields totally compatible between the two models?

Given the small difference in the price between the two why wouldn't I buy the Mega or why should I buy the UNO?

Appreciate your input.

Thanks,

fleetz

Code gets recompiled for each one, so a .hex created for one will not work on the other.
Port assignments are differenct, so if you wrote for one with specific hardware assignments (direct port manipulation) that would need adjusting.
Shields expecting SPI signals on D10-11-12-13 - SPI is 50-51-52-53 on Mega, you will need to add some jumpers to the Mega and then not used D10-11-12-13.
Not I2C may need the same, not 100% sure on that.

Why buy one vs the other? Your project, your call. I've been making my own variants instead of trying make do with existing shields.
If I needed to use ethernet, standard cell phones, I might use a shield for one of those.
Gonna have more than 1 project? Go with a processor that supports that, going overkill doesn't gain you anything.
Australia - check these guys out too:

CrossRoads:
Code gets recompiled for each one, so a .hex created for one will not work on the other.
Port assignments are differenct, so if you wrote for one with specific hardware assignments (direct port manipulation) that would need adjusting.
Shields expecting SPI signals on D10-11-12-13 - SPI is 50-51-52-53 on Mega, you will need to add some jumpers to the Mega and then not used D10-11-12-13.
Not I2C may need the same, not 100% sure on that.

Why buy one vs the other? Your project, your call. I've been making my own variants instead of trying make do with existing shields.
If I needed to use ethernet, standard cell phones, I might use a shield for one of those.
Gonna have more than 1 project? Go with a processor that supports that, going overkill doesn't gain you anything.
Australia - check these guys out too:
About Freetronics | Freetronics

Thanks for the detailed comparison and you sound advice...appreciated.

Yes was aware of Freetronics an Aussie company, they kept popping up in searches I have been doing over the past day or so. They boast 100% Arduino compatibility with some added features...

Thanks again...

Change "or" into "and".
Buy the Uno and the Mega. When you start using 12V, a loose wire might touch the Arduino board and destroy it. Or when one board is used in a project you can test sensors with the other board.

Fleetz, since you ask about "compatibility", especially with shields, I'll express my opinion here. I've been working with UNO/Duemilanove boards for a couple of years, but only recently started using the Mega2560 board to any great extent. So, I consider myself to be a perfect "noobee" with the Mega board, and have been looking out especially for what might byte me in the butt.

As Bob mentioned, the single biggest divergence between the 2 boards is the SPI pins are not on the D10..D13 positions on the Mega board. From a practical viewpoint, this is tantamount to a disaster, since there are tons of shields out there that use D10..D13 for SPI. Like almost every shield I own.

OTOH, the standard ethernet shields will work ok on either board type, because they have an extra header sticking down that connects to the ICSP header on the Mega/UNO boards, so SPI is picked up there. But only for this shield.

There are also 2 other issues with the Mega board that I've just uncovered in the past couple of weeks, and wasted me a ton of time.

  1. there is a discrepancy between where the Mega board schematic and pinout diagrams show
    the INTx hardware interrupt pins to be, and where they are actually used with software.

http://arduino.cc/en/Reference/AttachInterrupt

Eg, INT4 is actually connected to D2, but INT0 is remapped to that pin via the WInterrupt.c file located in the IDE directory, in this uncommented section of code - note it doesn't even say this pertains to the Mega board:

void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
  if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
.....     
    switch (interruptNum) {
.....
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
    case 2:
      EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
      EIMSK |= (1 << INT0);
      break;
    case 3:
      EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
      EIMSK |= (1 << INT1);
      break;
    case 4:
      EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
      EIMSK |= (1 << INT2);
      break;
    case 5:
      EICRA = (EICRA & ~((1 << ISC30) | (1 << ISC31))) | (mode << ISC30);
      EIMSK |= (1 << INT3);
      break;
    case 0:
      EICRB = (EICRB & ~((1 << ISC40) | (1 << ISC41))) | (mode << ISC40);
      EIMSK |= (1 << INT4);
      break;
    case 1:
      EICRB = (EICRB & ~((1 << ISC50) | (1 << ISC51))) | (mode << ISC50);
      EIMSK |= (1 << INT5);
      break;
    case 6:
      EICRB = (EICRB & ~((1 << ISC60) | (1 << ISC61))) | (mode << ISC60);
      EIMSK |= (1 << INT6);
      break;
    case 7:
      EICRB = (EICRB & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70);
      EIMSK |= (1 << INT7);
      break;
.....

All of the INTx are remapped so. Therefore, if you use the schematic or pinout diagram for reference, you're in trouble. This discrepancy isn't even mentioned in the links given above. You get to discover it for yourself.

  1. in addition to this, it turns out the most basic Arduino pin operations will not work correctly
    with the Mega board, in all cases - as far as I can tell. IE, bitClear(x, n) and bitSet(x, n).

http://arduino.cc/en/Reference/BitSet
http://arduino.cc/en/Reference/BitClear

If you use these for the Mega with n = INTx, it will operate on the incorrect bits because of the remapping shown above. Talk about gotchas.

  1. in addition to this, it turns out the most basic Arduino pin operations will not work correctly
    with the Mega board, in all cases - as far as I can tell. IE, bitClear(x, n) and bitSet(x, n).

That makes little sense. bitClear and bitSet work on a software variable in a sketch not on any physical pins or interrupts that differentiate a Uno from a Mega?

Lefty

Yes, it makes little sense, however see replys #17 thru #19 on this thread,
http://forum.arduino.cc/index.php?topic=185029.msg1384903

Any additional clarification, here or there, might save me even more wasted time in the future, ;-).

oric_dan:
Yes, it makes little sense, however see replys #17 thru #19 on this thread,
Arduino drives crazy when engine is running - #8 by system - Project Guidance - Arduino Forum

Any additional clarification, here or there, might save me even more wasted time in the future, ;-).

I don't think

bitClear(EIMSK, INT0);

Is valid use of the bitClear command, but I'll let the stronger software gurus around here chew on it.

Lefty

In regards "valid" and clarification, all I can clearly say is ... I'm confused with a lot of this stuff. I think there's a good reason there are over 1,000,000 posts on this forum.

Thanks for the replies guys. Wow if you guys are struggling with a compatibility issue between the UNO and Mega like this I will not have a hope in hell. Whilst I have 40 years in electronics programming is a new world for me.

Don't think it is a good idea floating between two platforms knowing that some shield and software are not compatible between the two.

There clearly are differences......maybe an "R4" version may correct this I don't know. All I am looking to do decide which model to go with initially. My original thought which I was hoping to get confirmation on was the two are 100% compatible and the differences were simply size of memory,etc etc then it was a decision of do I spend $30 or $60 dollars. I am happy to spend the $60 or so on the Mega providing it there are no gotchas......appears there are so it is looking like going down the UNO path as my level of entry.

I need to keep it simple or as simple as possible and remove any variable as I set forth on my first programming experience.....the UNO seems it will be a better options.

Maybe down the track the issues that have been raised here are fixed in subsequent revisions of hardware and software for you guys that have to work around the issues flagged. One assumes that the Arduino principals are aware of these issues given they are raised on the official forum? Do Arduino people normal respond on the forum on issues like this?

Anyway thank you all for your input it has helped me decide to go UNO initially.

Regards

Fleetz

You have compatibility in the sense that, in general, the same sketches will compile on either board, and run fine. If you specify pin D7 or A0 for some function, just find where it is located on either board.

Also, in general, many of the 3rd party libraries will also be "software" compatible, since the pinout customization files, ie pins_arduino.h for each board variant, will take care of differences in chip pin routing to header pin Dx, Ax labels. However, as noted, the non-compatibility of many shields is a more serious matter.

The business about the INTx pins that I mentioned is probably something that 99% of users haven't even tumbled to. I just got burned because I wrongly assumed that the Mega board schematic and pinout diagrams accurately indicated the INTx functionality. Wrong.

That all being said, whatever you do, I would suggest "don't" jump over to the ATmega1284 board variants, if you want easy compatibility. Basically, there was essentially zero support in the IDE for 1284s, prior to IDE ver 1.05, plus I've had to debug every single 3rd party library that I've used with the 1284. Wasted countless hours over the past 6 months on this. And I'm saying this not because I'm any kind of Arduino expert, but rather just a poor dumb coder trying to get his stuff to work correctly.

And the R4 version is not likely to suddenly change all the pin wiring around - I shouldn't think - since then you would lose compatibility with all previous Mega board versions just to get better UNO shield compatibility.

[Despite how it may look, this is more an FYI than a rant, BTW - LOL].

If you specify pin D7

No such symbol...

As for "bitClear(EIMSK, INT0);" - that's perfectly valid code, but "INT0" has nothing to do with the "0" use in the attachInterrupt() function; there's an added level of abstraction, just like there is between "7" and "PORTD bit 7" or "chip pin 13"...

This is partly Atmels fault (INT0 is on PD2. Obviously!) And it is partly the Arduino team's fault (they nicely abstracted all the the other pin names, why keep 0/1 for the interrupts? It should have been "attachInterupt(2,...)"

If you're starting, get an Uno. Almost all the examples are for Uno-class boards. The MEGA is "mostly" compatible, but a newcomer shouldn't have to deal with what that "mostly" means.

You're right, no D7. You can use A0 for analog 0, by virtue of statements like the folllowing in the pins_arduino.h files

static const uint8_t A0 = 14;

but you must use 7 for Digital 7.

However, the other thing is all due to Arduino remapping the INTx pins, not to anything Atmel did, from what I can tell. Eg, on the UNO, INT0 appears on pin 2 (P2, Digital 2), and if you attach it, it calls the following line ... case 0: ... blah, blah (1 << INT0);

void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
....    
    switch (interruptNum) {
....
    case 0:
    #if defined(EICRA) && defined(ISC00) && defined(EIMSK)
      EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
      EIMSK |= (1 << INT0);
....

but as noted in a prior post, if you attach interruptNum = 0 on the Mega board, it also appears on pin 2 (P2, Digital 2) as a result of remapping according to

void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
....    
    switch (interruptNum) {
....
    case 0:
      EICRB = (EICRB & ~((1 << ISC40) | (1 << ISC41))) | (mode << ISC40);
      EIMSK |= (1 << INT4);
      break;

That is, in this case, the INT4 bit is actually being used. So what this means is what I already said, that if you're gonna use "bitClear(EIMSK, x);", you'll have to use it as follows when referring to whatever it is that been attached to pin 2 (P2, Digital 2):

UNO:  attachInterrupt(0, ...)
      bitClear(EIMSK, INT0);
Mega: attachInterrupt(0, ...)
      bitClear(EIMSK, INT4);

or can you show me another mapping that fixes this? This is the confusion I've been referring to, here and on the other thread. Head is spinning.
http://forum.arduino.cc/index.php?topic=185029.msg1384905#msg1384905

I think there should be "disableInterrupt(n)" where "n" matches the number used in "attachInterrupt(n, ...)" and then user-level sketches wouldn't have to touch EIMSK at all.
(and then, since "n" no longer matches INTn from Atmel's documents, "n" should just be the Arduino pin number, instead of some "magic" number your have to dig out of the datasheet and map differently for different CPUs.)
(I mean, this would exactly match what they did for implementing "Arduino pin numbers" in the first place.)

I think there should be "disableInterrupt(n)" where "n" matches the number used in "attachInterrupt(n, ...)" and then user-level sketches wouldn't have to touch EIMSK at all.
(and then, since "n" no longer matches INTn from Atmel's documents, "n" should just be the Arduino pin number, instead of some "magic" number your have to dig out of the datasheet and map differently for different CPUs.)
(I mean, this would exactly match what they did for implementing "Arduino pin numbers" in the first place.)

So that would be this code

void detachInterrupt(uint8_t interruptNum) {
  if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
....
    switch (interruptNum) {
....	
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
...
    case 0:
      EIMSK &= ~(1 << INT4);
      break;
....

So, in any case, I'm taking your answer to indirectly mean that everything I said previously about this is correct, and you would have to use "bitClear(EIMSK, INT4);" for the Mega, as I described, to be correct. IOW, the whole thing is a big confusing gotcha.

Just to reiterate, this whole discussion came about because I was debugging a 3rd party library, and they're the ones that use "bitClear(EIMSK, INT0);". They use this for every processor in the list including Mega, except Tiny:

#ifdef EIMSK
  bitClear(EIMSK, INT0);
  uint16_t r = XFERSlow(cmd);
  bitSet(EIMSK, INT0);
#else
  // ATtiny
  bitClear(GIMSK, INT0);
  uint16_t r = XFERSlow(cmd);
  bitSet(GIMSK, INT0);
#endif

If they put attachInterrupt(),detachInterrupt() in this code in place of bitClear,bitSet, I assume the throughput of the system would be rather small.

I'm taking your answer to indirectly mean that everything I said previously about this is correct

No! You said:

it turns out the most basic Arduino pin operations will not work correctly with the Mega board, in all cases - as far as I can tell. IE, bitClear(x, n) and bitSet(x, n).

which is NOT correct at all. bitClear and bitSet work just fine on MEGA, it's just that the MEGA "interrupt" code does a swell job of obscuring which bits are associated with which external interrupts.

I would claim that detachInterrupt and and disableInterrupt are worth having separate functions; disable (and the associated enable, which would also need to exist) allow code to temporarily prevent the interrupt without having to know which function it is "bound" to.

westfw:

I'm taking your answer to indirectly mean that everything I said previously about this is correct

No! You said:

it turns out the most basic Arduino pin operations will not work correctly with the Mega board, in all cases - as far as I can tell. IE, bitClear(x, n) and bitSet(x, n).

which is NOT correct at all. bitClear and bitSet work just fine on MEGA, it's just that the MEGA "interrupt" code does a swell job of obscuring which bits are associated with which external interrupts.

I would claim that detachInterrupt and and disableInterrupt are worth having separate functions; disable (and the associated enable, which would also need to exist) allow code to temporarily prevent the interrupt without having to know which function it is "bound" to.

Come on, Bill, you edited out what I actually said:

  1. in addition to this, it turns out the most basic Arduino pin operations will not work correctly
    with the Mega board, in all cases - as far as I can tell. IE, bitClear(x, n) and bitSet(x, n).

http://arduino.cc/en/Reference/BitSet
http://arduino.cc/en/Reference/BitClear

If you use these for the Mega with n = INTx, it will operate on the incorrect bits because of the remapping shown above. Talk about gotchas.

First I said "in all cases", and secondly, you have to read as far as the last sentence. As noted already several times, if you're dealing with attach interrupt 0 on the Mega, you would have to use INT4 in the Bit ops, and 4 does not equal 0. Maybe everything is clear enough to you, but it looks like mud to me.

Basically, what it comes down to is a set of unwritten rules that can only be discovered by reverse-engineering the source code, except in cases like mine, where they just come out and byte you in the hindside.