What am I missing? Nano vs Mega!

Hi guys

Im quite new to programming so am quite limited in my experience. I have an issue with using the mega board. It works just fine when uploaded to a Duo board, but when I upload it to the mega the buttons in my program dont work at all except one of them (fill button). I thought all of these boards are compatible, as they are labeled the same, but obviously not. If anyone could help me out with this i would greatly appreciate it.

Thanks

P.S sorry if this should have been posted in another section, but this one seemed to make sense to me.

BIG_BUTTON_MOD_LED_PIN_A3.ino (19 KB)

int BigButton = 19;
...
int BankLED = 17;

Neither the Nano nor the Mega have a pin 19 or 17 label. I think this is the problem with your port. Try using the analog designations instead, A0-A5. Try:

int BigButton = A5;
...
int BankLED = A3;

You buried a secret pin number in the code, unbury it with a declaration and use Ax number instead:

  CHANNELSELECT= analogRead(2);

That may also break portability, use

const byte <pin name you give it> A2;
...
  CHANNELSELECT= analogRead(<pin name you give it>);

You probably buried more literal pin numbers in your code, but it’s too big for me to comb through, you have to look for them because as you know, they don’t generate any error.

Thanks for the reply aarg. What do you mean by “buried”? sorry if its a stupid question. The channel select knob is actually one of the things that work when porting. Is it still worth me changing it as you described?

aarg:
Neither the Nano nor the Mega have a pin 19 or 17 label.

The Mega certainly has - they go all way up to 50 or more.

The analog pins can also be referenced by numbers - but that varies from board to board because the analog pins are numbered after the digital pins. For example on an Uno A0 is the same as 14. You can find out the value with

Serial.println(A0);

...R

gface83:
Thanks for the reply aarg. What do you mean by "buried"? sorry if its a stupid question. The channel select knob is actually one of the things that work when porting. Is it still worth me changing it as you described?

You declared most of your pin constants at the beginning of the file. The pin constants are then used throughout the program. This is the correct way to do it, as you seem to already know. If you do not do this, when it is time to examine or change them, they are "hidden" or "buried" since you have to scope the entire program by eye to find it. A search for '2' isn't practical, since there are so many '2's in many programs.

Yes, it is definitely worth declaring all pin constants at the beginning of the file (or sometimes function if there are huge functions). It pays to use the core defined constants as they are the most portable between different Arduino devices.

You should also declare them with the const keyword so they can't accidentally be written to, using the smallest data type that matches what it will be used for.

const byte BigButton = A5;

not

int BigButton = A5;

Robin2:
The Mega certainly has - they go all way up to 50 or more.

Oh, right. I see now, it's been a while since I used a Mega. That perfectly shows the problem since unlike the Uno and Nano, the pins 14-19 are not analog pins and so don't have the alias A0-A5.

Thank you both for the reply. Just changing those pin numbers to the actual name i.e. 17, 19 to A5 and A3 has done the trick. Im so happy Thank you. I will change the other things you have suggested though to keep the code tidy. I thought I was never going to sort it out. I still have so much to learn.

Thanks again

This code makes redundant conditional checks:

  if (0<KnobVal)   { KnobValue = 0;}
  if (127<KnobVal) { KnobValue = 1;}
  if (254<KnobVal) { KnobValue = 2;}
  if (383<KnobVal) { KnobValue = 3;}
  if (511<KnobVal) { KnobValue = 4;}
  if (638<KnobVal) { KnobValue = 5;}
  if (767<KnobVal) { KnobValue = 6;}
  if (895<KnobVal) { KnobValue = 7;}
  if (1000<KnobVal){ KnobValue = 8;}

Suppose KnobVal == 42, then KnobValue = 1. But then all the other tests are still performed. Why? It’s easy to see that they can’t pass, because we already know KnobVal is not that big. Instead, use if-else:

  if (0<KnobVal)   { KnobValue = 0;}
  else if (127<KnobVal) { KnobValue = 1;}
  else if (254<KnobVal) { KnobValue = 2;}
  else if (383<KnobVal) { KnobValue = 3;}
  else if (511<KnobVal) { KnobValue = 4;}
  else if (638<KnobVal) { KnobValue = 5;}
  else if (767<KnobVal) { KnobValue = 6;}
  else if (895<KnobVal) { KnobValue = 7;}
  else { KnobValue = 8;}

There are some other problems here. KnobVal was an analog read so it can’t ever be negative. Thus KnobValue will never == 0.

Ah yes right, I get what you mean. There's probably a few bits like that in the code. Thanks for pointing that out, Il l be sure to change it.

Actually, I misread the code… if KnobVal == 42 then KnobValue = 0. The way it’s expressed is unconventional. Normally you would bracket it like:

  if (KnobVal < 128)   { KnobValue = 0;}
  else if (KnobVal < 255 ) { KnobValue = 1;}
  else if (KnobVal < 384) { KnobValue = 2;}
 ...
  else if (KnobVal < 1001) { KnobValue = 8;}

Comparisons should follow English, e.g. “if Paul is less than 5 feet tall”, vs. “if 5 feet is the same or more than Paul’s height”.

I’m not sure what you would do with a reading over 1001… in the original code, you do nothing.

I would say that this is much simpler

KnobVal=(KnobVal/128)+1;

Ah Ok, I will keep that in mind. Thanks for the help, Youre Awesome!! I dont think you can have a reading over 1000, can you? It is a potentiometer knob. I thought any analogue reading is from 0-1000. 1000 being the full voltage range if you know what I mean.

No, the range is 0-1023.

so could "KnobVal=(KnobVal/128)+1" replace all of that code? Ah yes, thats right 1023 my bad.

gface83:
so could "KnobVal=(KnobVal/128)+1" replace all of that code? Ah yes, thats right 1023 my bad.

The above code places the result in the wrong variable. It's a great example of the perils of variable naming. The two names looked too similar. This mistake wouldn't have happened if 'KnobVal' was called 'KnobReadADCValue' or something like that...

So, you can just use

KnobValue = KnobReadADCValue >>  7;

The plus one won't make any difference in your application.

Wouldn't a value of 1001 just return knob value 8?

Ok, that type of coding is out of my depth, I haven't got a clue what that means. Also, Wouldn't a value of 1001 just return knob value 8?

1001 / 128 == 7

7 has the same effect on an unsigned integer as /128 does, if you want to be more obvious:

KnobValue = KnobReadADCValue /  128;