Go Down

Topic: Compatibility between Mega and UNO? (Read 5633 times) previous topic - next topic

Fleetz

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


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:
http://www.freetronics.com/pages/about
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

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:
http://www.freetronics.com/pages/about


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

Erdin

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.

oric_dan

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/Main/ArduinoBoardMega2560
http://arduino.cc/en/uploads/Main/arduino-mega2560_R3-sch.pdf
http://arduino.cc/en/Hacking/PinMapping2560
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:
Code: [Select]
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.

2. 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.

retrolefty

Quote
2. 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

oric_dan

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, ;-).

retrolefty


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, ;-).


I don't think
Code: [Select]
bitClear(EIMSK, INT0);

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

Lefty

oric_dan

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.

Fleetz

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

oric_dan

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].

westfw

Quote
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.

oric_dan

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
Code: [Select]
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);
Code: [Select]

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
Code: [Select]

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):
Code: [Select]

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

westfw

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.)

oric_dan

Quote
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
Code: [Select]
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:
Code: [Select]
#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.

Go Up