Arduino Button Mappings

It’s less about CPU speed, more about reducing compiled Sketch sizes…

Yep, so all we need is a pull request. :smile:

PR for hardware changes? Bring it!

I vote for the C button. Compared to the original sega genesis controller, the only difference is shape. Plus, all the people who have complaints about a/b ordering will have slightly less reason to complain about, although I prefer ditching gameboy style and using the initials by far anyways. It’s not like any major gaming system uses that layout marking anymore. Nintendo ain’t what it used to be, and it makes me sad.

Since @bateske has said, in the comments section on Kickstarter, that he intends to add a Start button, there will now be 7 buttons total. Getting them all on one port would be difficult:

Port B:
2 pins, are needed to talk to the display in SPI mode. Two others can’t be used for GPIO when in SPI mode. That leaves only 3 pins on Port B.

Port C: Only 2 pins are physically present.

Port D: This is possible but it would be really nice if PD0 - PD3 were left unused and brought out to pads for hacking. PD0 and PD1 are for the I2C bus and PD2 and PD3 are Rx and Tx for hardware UART serial communication.

Port E:
Only two pins are physically present.

Port F:
Close, but only 6 pins are physicaly present.

This does not really matter. It simply doesn’t. To track extended button states (which quite a few games will need) you have to loop over an array and store hold counts anyways, and then there is turning the pull-ups on and off to save power… so at that point there isn’t much advantage at all. The hardware polling takes no time either way (for a normal 100+ FPS game), so we’re only talking about storage now… and reading from 3 ports and a few bit operations just is not that heavy code wise. Now someone will show the exact difference and might be a lot for JUST the polling but if you figure in the full button management and power saving code the % diff starts to get a lot less.

The above code could be optimized further to do less bitshifting since each shift is a single op against the processor, but I don’t know if that would result in a smaller compiled size.

There are lot of fatter places we could be looking it… maybe this just has caught peoples interest because it seems easy?

Again, I think a PR would be welcome here, but either @bateske will change the hardware or he won’t. I think he’s heard us by now.

To be clear my response is because I get this “OMG, the sky is falling if we can’t have one port” vibe from this thread - and that’s ridiculous. We’ll be fine either way. There would be a lot more benefit to the SSD1306 on the single port (parallel) we have than the buttons.

First, I’ll state that I agree with you that there isn’t much to gain, in the grand scheme of things, by having all the buttons on one port.

The internal pull-up on a pin only uses power while the button is being held down. In most games you would only be pressing one button at a time. I would guess that, worst case for most games, over all the pull-ups you would see the equivalent average power draw of one button down 100% of the time.

The minimum pull-up resistance is 20K. At 4V the current draw would be 0.2mA. The display alone will average about 14mA, which is 70 times what the pull-ups will use with the above estimation. Therefore, turning the pull-ups on and off is about as useful, from a power point of view, as putting all pins on one port is, from a speed point of view.

Ok, that closes off one other thought; all the Port B pins can be configured as Pin Change Interrupt sources. For some games, you can tremendously streamline your design if the game “just runs” on a main loop, and button presses are always an interrupt. But that would need 6 of 8 Port B pins, and that went away the moment the display used SPI. And I don’t see much advantage in having only some of the buttons being interrupt capable.

I have seen buttons overloaded on single analog pins using a resistor chain, but that removes the ability to handle multiple button press tracking at the same time. NKRO is valuable in a game system!!!

Hey Dreamer3- agreed this isn’t a burning issue. However, I think we all see the benefits of a PWM pin for audio. At this point, there’s no ‘small’ change to the PCB design IMHO- so why not prepare a wishlist! At least it’s useful for Gen2 :wink:

Some data from a quick test, compiling ‘Digital Input Pull Up’ - Ardunio IDE example:
5,466 bytes (19%) - As provided.
4,874 bytes (16%) - Removed Serial commands
4,764 bytes (16%) - Removed Digital read
4,774 bytes (16%) - Digital read replaced with direct PORT read
4,252 bytes (14%) - Empty default sketch, just void() and loop()

So you might save ~100 bytes for each digitalRead you can avoid. The significance of this is pretty subjective and relative to your needs… My take home message, is that for code requiring real performance you will avoid the Arduino IDE…

I"m not sure that’s right… the buttons are 1 when unpressed - they are held high all the time and only go low when pressed. I assume gamebuino wouldn’t have gone to all the trouble if there wasn’t some real power savings to be had (though I didn’t scan back thru the commit history - but that wouldn’t be hard).

Interesting - that would be for games that didn’t need to change the screen at all. I already planned on the core library sleeping as much as possible but this is a different idea… deep sleep until a key is pressed. I had consider that, but only for “screen off” power save mode that could be engage if you sat the device down and forgot to turn off the power.

I hasn’t considered that normal games could do that. If we’re going to run at 8Mhz the power savings from all this stuff starts to drop off after a while - since the OLED becomes the main draw.

So you might save ~100 bytes for each digitalRead you can avoid.

We don’t have to use digitalRead() either way. If it’s 1 or 3 ports we can access them directly faster no doubt. So what you’d have to compare is an optimized 3 port read vs single port read. :smile:

And I don’t think it’s EACH digitalRead… that would be very weird if true… more likely you’re compelling in a pin/port mapping table that’s sucking up some of that space.


Regarding buttons and power saving:

“Experiment 5) Turning all the unused pins to inputs and writing them low did not help, but writing low with pullups did hurt (62uA). You need to be careful with this. Enabling pull up resistors or driving a load can use a lot of power.”

There is an entire class of games where interaction is minimal, and the player spends a lot of time studying the screen. My (poor) recollection is that someone has done chess for the Arduino, but I am certain that chess programs have been implemented with as little as about 1K of program space! In that case, the ability to goto sleep until a button is pressed might extend battery life quite significantly.

Just today I was thinking of writing a tamagotchi style game. Of course there is no hardware clock to leverage but having a power-save mode with the screen off and minimal cpu activity sounds very good for this kind of application

[quote=“Dreamer3, post:20, topic:128”]

I"m not sure that’s right… [/quote]

Refer to the following diagram, which I copied from here

This shows the circuit we are using for the buttons, with the button released on the left and the button pushed on the right. The pull-up is the 20K internal one. The right pointing arrow goes to the input in the CPU. I’ll give all currents in milliamps (mA) for easy comparisons.

The CPU inputs are specified as having a maximum leakage current of 1uA which is 0.001mA. This is worst case, at 5.5V over the full temperature range. At 4V and typical temperatures, it would probably be more like 0.0005mA or less. Either way, it’s so low as to not be a consideration. Therefore, the only current flow, resulting in power used, will be in the circuit pictured (just the pull-up and button).

The switch itself will not use any power. This is obvious for when it’s open. When it’s closed it has zero ohms resistance, so although current will flow through it, it will use no power because power equals current squared times resistance (and again, resistance is zero). That leaves the only thing that can use power being the pull-up resistor.

From the circuit on the left you can see that there’s no path for current to flow through the resistor with the switch open (as we’ve already said that current flow via the input is irrelevant). Since no current is flowing through the resistor, there is no power consumed.

Another way to determine this is by the voltage differential across the two leads of the resistor.
The diagram on the left shows that the voltage on both leads is Vcc, therefore the differential voltage on the resistor is 0V. Power is voltage squared divided by resistance, so since the voltage is zero, again we see that no power is consumed.

From the circuit on the right, we can see that when the button is pushed there is a path for current to flow from Vcc through the resistor and switch to GND. The switch will pull the side of the resistor attached to the input all the way to GND, so the differential voltage across the resistor will be equivalent to Vcc. Ohm’s law states that current equals voltage divided by resistance. With a voltage of 4V and a resistance of 20000 ohms, we get 4/20000=0.0002A which is 0.2mA. This is worst case. The voltage will usually be lower and the resistance somewhat higher.

Conclusion: The button circuitry as implemented by the Arduboy only uses power when a button is pressed (and by my previous post, this power is very small with respect to overall power used by the entire unit).

Something else of note:
Section 10.2.6 Unconnected Pins of the ATmega32U4 datasheet states:

Only the button is attached to the input, so when the button is not pressed the input is floating and equivalent to being unused. According to this then, disabling the internal pull-up is actually not recommended.

In those cases you’re still stuck with the OLED though… so that greatly limits your potential savings.

Conclusion: The button circuitry as implemented by the Arduboy only uses power when a button is pressed (and by my previous post, this power is very small with respect to overall power used by the entire unit).

You’re going over my head. I don’t understand all the theory. I look around and people say it can be significant, gamebuino makes the effort to turn pull-ups on/off… seems to strangely contradict that it doesn’t matter… of course they both could have it wrong, but make me suspicious there is something there. I’d feel better if someone tested it with an amp meter. To me real numbers like that goes a lot further than the theory.

From their respective datasheets:
The operating current drawn by the display, with 50% of the pixels lit, is about 14mA. The ATmega32U4 running at 8MHz with a 5V supply uses about 10mA, but I’m guessing that could drop to about 9mA at 3.3V.

So, even though the display draws a significant amount, putting the processor to sleep could save around 30% of the power.

For cases where the display can be blank, such as pausing a game to take a phone call or have lunch, the display could be turned off through software and would draw very little power in that state. In this case, if just a single button has interrupt capability, the processor could be put to sleep and that button could be used to wake it up.

Keep in mind that the Arduboy will likely run for about 7 hours on a full charge. I don’t know how many people will be concerned about extending that. Those that are could carry one of those portable USB chargers to extend the life.

I’ll try to find the time to do this. I have all the equipment required to measure this accurately.

12 is better than 7. 9 is better than 7. If it’s just something we have to figure out and write into the lib or bootloader and then everyone gets the benefit I"m all for it. from what I’ve seen you can cut the default consumption of the chip by over 50% easily (when it’s running full throttle) with creative power saving. I don’t know where your getting the 9mA from (I thought I’d seen much lower in the PDF for 8Mhz), but if that were the case going from 9mA to 4.5mA (without even touching sleep modes) would be a big win for battery life.

3 of the buttons are hardware interruptable now (8, 9, 10). All the DPAD except Right. But that’s so weird. I’d trade all three for having both the circle buttons… (or the new start button)… they just seem more natural for a “wake from sleep”. Of course if it ships that way could always tell people “hit the left DPAD to wake from sleep”.

It would be really nice to get sleep mode so low you could just leave it on for a week or two… preserving your game state. From what I’ve read that’s doable if we can go into deep sleep and also have a circuit to completely cut the power to the screen.

Here the relevant portion of the table from the datasheet:

The OLED display can be put into sleep mode via software, where it draws almost nothing. From the datasheet:

If we can get the ATmega32U4 into power down mode with the watchdog timer disabled, it will draw about 5uA or less. The display in sleep mode will draw about 15uA worst case but probably closer to 3uA. Total worst case would be about 20uA.

With a fully charged 180mAh battery, the Arduboy could sleep for over 9000 hours, which is 375 days, or over 1 year. However, it would probably be quite a bit less than that due to self discharge of the battery. A week or two is no problem. Two or three months is realistic.

@bateske said there is some issue with powering off the screen via software… the voltage goes haywire or something. He said it needed an actual circuit to completely cut the screen power if we aren’t using it. I haven’t experimented. I don’t recall anything about “sleep” mode though. Do you just mean issuing a “screen off” command to the SSD1306?

Here the relevant portion of the table from the data sheet:

I’m thinking of the graphs on page 368 of the specs.

Sure looks to me like 3.7-4v at 8Mhz would be around 4mA.