Arduboy Kickstarter version design discussion

I’m talking about readily available Arduino, or Arduino compatible, products that would be as close as possible to the Arduboy’s hardware. A 328 based device would have a hard time with some Arduboy sketches. Those that used the USB to emulate a mouse or keyboard, for example.

Sure, but I don’t think that is most sketches to be honest, though I see your point. At some point someone has to say what the Arduboy is. Sure it can be many things, but what is it to MOST people… if you’re building one yourself (from spare parts) AND you’re doing something very, very fringe then we’re not really talking about an Arduboy anymore - we’re talking about a custom Arduino system of some type. A 328 would work in MOST cases, except for “using as a USB input device”. If that was a requirement then yes, someone choices are more limited. If it’s not a requirement (and I think this is the most common case) then there a lot of chips that might work.

I believe in another thread you were even advocating we use a 328 for the core Arduboy. :slight_smile: Building “your own Arduboy” would be cooler if a kit was sold with the pieces, case, core board, etc… but with pads for customizing - vs starting from nothing. I think the RAM difference would be an issue for more sketches than the programmable USB.

I’m not saying it’s a party trick, or difficult to do. I even spelled out what would be required.

I’m saying it’s @bateske that you have to convince, and get him to do it. He, like I, may be uneasy with the possible instability that running at 16MHz could cause, no matter how much you warned users of the risks. He may also, as I suggested, wish to be able to use a “plain vanilla” Arduino bootloader.

I thought he was the one who thought maybe it could run at 16 all along with no issue at 4v. :slight_smile: Ultimately he’ll either put a 16 or 8Mhz crystal on it… and if so the bootloader will have to support 2Mhz -> 8Mhz boot-up - and there will be nothing to stop someone from kicking it up to 16. I’m not sure I really care if that happens or not. I think @bateske will make the right choice - whatever it is. But if it does happen I think it will be neat for hackers. :slight_smile:

Pros are that I’m not sure a 16Mhz crystal does much harm (maybe a hair more power?) and it allows for some neat hacking - and maybe some games that might not be possible at 8Mzh. Cons are people could fry their units by running them out of spec. Or a huge groundswell movement could spring up and all games are sloppily written to require 16 (with instructions for compiling) in which case the core “8mhz safe” experience would have been corrupted. Having only 8Mhz would avoid that unlikely possibility.

I was just trying to point out that 8Mhz is 8Mhz clock speed. There isn’t any real harm having a faster crystal.

Awesome writeup though.

1 Like

No, there are many other differences, between the 32U4 and the 328. The number and bit sizes of the timers being just one example. I think working with the limitations of a Pro Micro would bring you a lot closer to an actual Arduboy than working with a Pro Mini or some other 328 based device, especially if all my suggestions are followed.

I’d also consider using an Arduino Micro but that might require changing the crystal or on board regulator (since it’s only available as 5V/16MHz), depending on what is decided for the final Arduboy. This wouldn’t be a problem for me but it might for others, which is why I tried to accommodate the limitations of a Pro Micro. I also like the smaller size advantage of the Pro Micro.

No, I never advocated it. I offered it as a way to safely clock at 16MHz on a single cell lithium battery, along with other suggestions that involved changing the clock speed. If you read one of my later comments in that thread, you’ll see that using a 328 was never my preference.

Changes I’d like to suggest form the DevKit:

  • 8Mhz default operation, 16Mhz crystal
  • 3.3V regulator (MLXXXP makes this sounds like a great idea), and it would evidently give us longer battery life
  • Software should be able to completely cut power to OLED to properly power save - @bateske already said this would happen on IRC
  • Speaker on PWM port (or two?) Not sure about the electrical implications here for proper mixing. Having the speaker on hardware PWM means more CPU power for games and less for tones.
  • Start button hardware interruptible.
  • A button and B button hardware interruptible. (I think this would be nice to wake from sleep) A bunch of the DPAD buttons already are - so I’d just swap those leads for A and B.

Having Start (plus maybe A or B) would allow the device to go into deep power saving mode if laid down for a while (or even manually put into sleep mode)… without that we need the watchdog timer to check for pressed when sleeping, which isn’t the end of the world, but would reduce our sleep time since the watchdog timer uses more power on than off.

Your comments summarize things nicely and I agree with everything you said.

At 8MHz, only the oscillator circuit would run at 16Mz, so yes, additional power would be extremely low.

This could be true. But setting the system clock prescaler to divide by two isn’t the only thing you have to do. The PLL prescaler for the USB hardware also has to be adjusted separately. There may be other things as well that I haven’t looked into.

That’s why I suggested that somebody try this on the Dev Kit version, since it has a 16MHz clock. To quote you, about a similar situation related to input pullups:

The scary thing is that the Arduboy could ship to everyone with a 16MHz crystal and then later some unforeseen problem related to doing this, that’s difficult or impossible to work around, shows up. I know of no standard Arduino’s that are doing this to allow overclocking, so implementing and testing that the theory works in practice would be a good idea.

That’s fine with me, as long as nobody minds the additional deviation from the Dev Kit mappings (yes, I know it’s probably just a matter adding of some #ifdefs and #defines to the libraries and/or sketches). However, indications are that the Start button will be on an edge of the unit, and could be recessed, making it fairly difficult to press accidentally. The A and B buttons would be much easier to be pressed and held by something in a purse, pocket or wallet, thus increasing the possibility of an accidental wake up.

I’d actually recommend that it be required that two or more buttons need to be held to cause a wake up. To implement this, only one button would have to generate an interrupt.

If the USB hardware works at 8Mhz and the program is compiled 8Mhz then it should “just work”. Or is the PLL pre-scaler not set against the CPU clock, but the oscillator? If that was the case then you might have a point, but it’d just be another line of code divide the prescaler differently. In any case this isn’t a hard problem to solve. Someone is surely welcome to test it - and that can’t hurt.

These chips are designed to run at any range of speeds though and a clock crystal is a clock crystal. So it doesn’t personally cause me concern. That said if I had $400,000 or so of other peoples money then I might listen to your concerns with a little attention. :smile:

Sure, physical considerations would depend on the final hardware - but that’s not 100% known yet. A, B, start ALL hardware interruptible is best case, even if we decided not to use that functionality in the core lib.

Correct, the PLL pre-scaler is before the system clock prescaler. Again, I’m not saying that this is difficult, or that I’m totally against it. I just think it should be thoroughly tested before implementing it in the final product, to help avoid any unforeseen "gotcha"s. From an Arduino point of view, varying clock speeds with overclocking is treading in mostly uncharted waters, from what I can see.

Would you even need a different boards.txt file and create a 16Mhz library variation at compile time? I envision that the Arduino IDE would just be led to believe that it was an 8MHz system, and indeed it would be because the bootloader would set it up that way.

An Arduboy specific library would then have a function added which would change the prescaler(s), timers and anything else required to make everything operate seamlessly as a 16MHz system. Another function, or the same function called with different arguments, could then be used to restore everything to 8MHz operation.

For example:

A sketch, which like all sketches, would initially be running at 8MHz. It could then call setSystemSpeed(SPEED_16MHZ). Upon return from the function, everything would be running at 16MHz. All delay functions, sound generating functions, and anything else depending on timers (not specifically manipulated by the sketch) would still work properly because setSystemSpeed() would have changed the time bases as required.

If desired, at some point the sketch could call setSystemSpeed(SPEED_8MHZ) to return to 8MHz, as if switching to 16MHz had never happened.

We could probably even allow other values, like setSystemSpeed(SPEED_4MHZ) or setSystemSpeed(SPEED_2MHZ) for slower, lower power operation. It may be good to also have setSystemSpeed(SPEED_DEFAULT) in case the library is ported to Arduboy2 or some other similar system with a different native clock speed. SPEED_LOWEST and SPEED_HIGHEST and SPEED_HIGHEST_SAFE could also be considered as options.

There probably should also be a complimentary getSystemSpeed().

@Dreamer3, I’m sure you’re aware of this, but for the benefit of others who may misunderstand what you’re saying:
Just because a pin is PWM capable doesn’t mean it has to be used in PWM mode. It can still be configured as a standard software manipulated GPIO pin, as well. So in case anyone thinks otherwise, there’s no down side to moving the speaker from a pin that isn’t PWM capable to one that is.

In some cases, setting up and using PWM just to generate a simple “beep” may be overkill, when just using tone() would suffice.

Just skimmed through the page, looks amazing guys! I’ll look at it more in detail when I start crunching on the new prototypes next week. Nice work!

1 Like

Using a PWM pin to generate a straight tone (PWM at the fundamental frequency) is going to be extremely simple and economical of code. Using high-frequency PWM to create a low-frequency analog output is a really neat technique, consuming more memory (but not necessarily RAM).

I found a good summary of the multiple sound techniques here (multiple audio out options)

I had initially thought that the PWM high-frequency needed a low-pass filter, but this source suggests that if you run the PWM up near 60KHz, even this is not needed – but I would rather someone tested this! The example above is driving a PC sound input, which has rather differenct characteristics than the piezo speaker.

The PWM high-frequency mode can easily do multi-channel by doing multi-wavetable additive synthesis on the single pin. If you were doing the low-level bit-hammering yourself, you would not have the time, but the added overhead in this mode is quite low. It likely runs out of steam only because you want things like voice, frequency, and envelope control on each voice, and that takes resources.

That said - if you had an external source of digital audio data, you can feed almost anything. Someone has even configured an Arduino to operate as a USB sound card. Given that the data is running by on the fly and not consuming memory, there just might be enough resources to make Arduboy into USB “encrypted audio file playback device”.

(Apparently, I have become a big fan of high-frequency PWM audio generation…)

1 Like

So what are your thoughts about your “speaker across two outputs” idea? If the speaker were on just a single pin but with PWM capability, would that be acceptable, or do you still think the “two output” thing could be useful as well?

Let’s assume that the PWM pin(s) are high speed capable, as are the one(s) I’ve proposed using.
There are 5 basic speaker connection possibilities:

  • One lead to a non-PWM pin, the other lead to GND.
  • One lead to a PWM pin, the other to GND.
  • Each lead to a separate non-PWM pin.
  • One lead to a PWM pin, the other to a non-PWM pin.
  • Each lead to a PWM pin.

Obviously the last choice it the most flexible. I think at least one output should be PWM.

If they have little or no advantage, the options using two outputs would waste a pin that could be used for hacking or other purposes. Also, if you’re only actually using one pin, you have to make sure the other is set as an output.

If we need or want external filtering or mixing hardware, then other possibilities could be considered.

I have been assuming that there was some unknown idea as to why the two outputs were feeding the speaker. In hindsight, I now think it was the attempt to create two channel sound, without being aware of just what could be done with some sophisticated thinking and a PWM output.

I won’t lob any complaints about this - the PWM timer sections of the Arduinos and the ATmega32u4 are some of the most complex structures going where most of the moving parts can be controlled. It has taken some developers years to get a good handle on the possibilities.

I strongly think that one pin must be PWM for audio - there are just too many advantages. And someone needs to take a close look at the 4-channel high frequency PWM audio software, and make sure that a compatible timer is used on the Arduboy, as there are differences in number and types of timers across the various Arduino chips. (I think it is Timer4, but have no way to verify this, and it may actually be the case that the other timers are fast enough.)

That said, straight audio PWM is a classic retro technique, but very hard to multi-channel. I can see an advantage in having one PWM pin and one straight pin, where you put “tonal audio” on the PWM, and “noise burst” (hits, bumps, explosions) on the straight output for super simple classic gaming. Of course, the other retro technique is “one sound at a time”, without only one output pin.

Here’s my thought on each of the 5 possibles, with their ranking (in increasing order)

  • One lead to a non-PWM pin, the other lead to GND - Absolute minimum, no less (5/5)
  • Each lead to a separate non-PWM pin - not bad, but we can do better (4/5)
  • One lead to a PWM pin, the other to GND - good audio, reasonably flexible (3/5)
  • One lead to a PWM pin, the other to a non-PWM pin - fairly capable if PWM outs are limited (2/5)
  • Each lead to a PWM pin - best option (1/5)

“One lead to a PWM pin, the other to a non-PWM pin” would appear to give us hardware dual channel with a PWM for tones and noise bit for other stuff, using minimal code and space, while also allowing hifi multichannel PWM on the tone channel, with “percussion” on the noise bit. Thus - low resource usage and a dead simple programming model for games that need it, while providing an upward path to multi-channel hifi for those that want to devote the time and resources of both the chip and the developers, and all in software without opening up the back.

Note that if we use two actual pins for audio, then they are locked in. If a pin is used for audio, you can’t use it for anything else. If we had two PWM pins on the speaker, you can choose to use only one, but the other one must be locked low (or high).

One particularly interesting option is to make the two PWM pins both from the same timer, but different output compare registers. This provides a dual voice capability, because the duty cycle (leading to wave form) can be independently controlled by the different comparators, even while underlying timer runs at a constant frequency. And - as you noted, you don’t have to use PWM on that second pin, so you can drop the second voice and just bit-bang out noise for percussion. At the same time, it potentially soaks up less resources, because other timers remain free for such things as internal event dispatch via interrupts, or dispatching low-frequency audio changes. (The notes change far less often than the level of the output waveform!)

The double sided connection to the speaker should be tested by someone, because if it works it both adds capabilities and reduces part counts, since the speaker effectively becomes a speaker, a mixer, and a protective resistor all in one. If it does not work, then any two-pin solution has to deal with a mixing option.

Although allowing hacking of the unused pins is going to be nice for some, I confess to wanting to maximize the value with the case closed. Capabilities built-in to the default are available for leveraging by all developers. If we drop some of that capability for the purpose of having unused pins, we create a resource which is used by a relatively smaller number of people. But that’s a tradeoff at a level up, not just in the audio side.

1 Like

Technically no, but it feels a lot nicer. If you found a Leonardo hardware item that ran at 8Mhz and used that as your choice it should compile correctly - just as it does now for 16Mhz Leonardo - and you’d just need the software to step it down during the boot cycle. Of course if someone is going to burn a new bootloader or set fuses it make sense to have those things codified in our own boards.txt file, that’s what the file is for - for custom hardware built on Arduino.

If desired, at some point the sketch could call setSystemSpeed(SPEED_8MHZ) to return to 8MHz, as if switching to 16MHz had never happened.

This is of course doable (much anything is in software) but has all sorts of complications - for delay routines, for hand-crafted assembly, for timers, for USB/SPI clocks, etc. Almost all of the Arduino core stuff wants to know the speed at compile time and a bunch of low-level changes happen as a result of that. There is already a library that does this somewhat (prescaler.h), but it provides it’s own delay, millis, micros functions that you use that are altered to be aware of the currently running clock.

Switching speeds multiple times while running isn’t something I’d think most programs would ever need or want to do.

If we had PWM our tone function could use it. It’s not something game developers would even need to think about. They’d just get more CPU for free.

This is why I recommend using Arduino pin 5 as the primary, or only, speaker pin. This is processor pin PC6. It can be complimentary PWM output A for Timer 4, which is the high speed timer. It can also be PWM output A for Timer 3, which is a 16 bit timer. One, probably minor, draw back of using this pin is that it’s currently used on the Dev Kit for the Right button, so Right would have to be reassigned.

I chose Arduino pin 13 for the second speaker pin (if we decide to have dual output capability) for a similar reason. This is processor pin PC7. It can be the direct PWM output A for (high speed) Timer 4. The only issue I have with using pin 13 is that it’s not available on a Pro Micro but this is only a minor consideration.

With both of these pins each connected to a separate lead of the speaker, for each pin you could independently choose one of:

For pin 5 (PC6):

  • A solid low (or high, it makes no difference)
  • A software generated signal
  • PWM from 16 bit Timer 3
  • (complimentary) PWM from high speed Timer 4

For pin 13 (PC7):

  • A solid low (or high, it makes no difference)
  • A software generated signal
  • (direct) PWM from high speed Timer 4

Actually, there’s one more possibly for each pin, which is “set as an input”. This would effectively act as a mute for the other pin.

For audio, it makes no difference if the PWM is direct or complimentary. However, though I can’t say for sure, I think if you set both pins to output PWM from timer 4 the volume of sound would be higher than if one pin were set to a solid low. This dual volume level capability might prove to be another benefit of having two outputs.

Also, if dual volume, as a result of generating a single ended or complimentary PWM signal, actually works, then it would also work for software generated single ended or complimentary signals.