Arduboy Kickstarter version design discussion

Continuing the discussion from Dev Kit Hardware:

I’ve started this topic to discuss what we know, speculate and suggest about what the final specifications and design of the Arduboy will be, as delivered to backers of the Kickstarter campaign.

I’ll start with details of my thoughts on the subject. Brace yourself, this is a long post! :slight_smile:

I’ll refer to the existing Development Kit version, that some people already have and are testing and experimenting with, as the Dev Kit. I’ll refer to the example product shown on Kickstarter as the Prototype.

The final version should be as close as possible to what is described and specified in the Kickstarter campaign, including anything stated by the Creator @bateske (Kevin Bates) in updates or comments.

Processor:
Kickstarter specifies an Atmel ATmega32U4 and that’s what the Dev Kit uses, so this is pretty much set in stone.

Power:
Kickstarter specifies a 180 mAh Thin-Film Lithium Polymer battery will be used to provide portable power. I’m guessing this likely is a GEB 014461. It’s specified as having a nominal voltage of 3.7V but can be as high 4.2V when charging or fully charged and can safely be used down to 3.0V. Based on typical lithium-ion battery discharge curves the voltage will probably drop quite rapidly when about 3.4V is reached.

The battery is charged from 5V provided by the specified Micro-USB port. A charge controller will be required to safely charge the battery. The photos of the Prototype show a 5-pin SOT-23 IC in the lower left corner. This is probably the charge controller (maybe a Linear Technology LTC4054).

I assume that the Arduboy will be able to run from the USB port while plugged in to charge the battery. The easiest way to allow switching between battery and USB power would be to actually just run the unit from the battery all the times. The 5v from USB would be fed to the input of the charge controller. The output of the charge controller would go to the battery and also to the power switch. The other side of the power switch would go the the rest of the circuitry.

As already stated, the battery voltage can be as high as 4.2V. The ATmega32U4 can operate safely over the full battery voltage range but the OLED display is only specified to be powered from 1.65V to 3.3V. If the chip at the lower left on the Prototype really is a charge controller, then I don’t see any sign of a voltage regulator for the display. I hope that the display isn’t being powered directly from the battery. If it is, I would add a 3.3V LDO regulator, such as a Micrel MIC5205, to power it.

If the ATmega32U4 remains powered directly at battery voltage, there is still a problem. The outputs that are driving the display inputs could go as high as 4.2V, which exceeds the absolute maximum 3.6V that the display allows. Level shifting circuitry could be added to safely drive the inputs, but it’s easier to just run the processor on the 3.3V from the regulator, as well.

The regulator output might start to drop when the battery goes below about 3.4V but this wouldn’t be a problem. There won’t be much life left in the battery when it’s between 3.4V and the 3.0V minimum, anyway.

Processor Clock Speed:
I think almost everyone agrees, from discussions under the Arduboy’s clock speed topic and elsewhere, that the ATmega32U4 is not running within spec, at 16MHz, if Vcc is below 4.5V (and thus the Dev Kit, at 16MHz with a 3V coin cell is being clocked out of spec). At 3.3V, up to a 10MHz clock is safe. However, looking at the ATmega32U4 datasheet I believe that only a 8MHz or 16Mhz clock can be used if you want to use the USB interface (please correct me if I’m wrong). Besides, any speed other than 8MHz or 16MHz could possibly cause problems with some aspects of Arduino compatibility. Therefore, I think an 8MHz clock should be used.

There’s been some discussion and desire to allow software to be able to switch the clock up to 16MHz, at the risk of possible unstable operation. This may be possible. A 16Mhz crystal would be used to generate the system clock. The CKDIV8 fuse would be programmed, which would set the clock prescaler to divide by 8 on power up, resulting in a 2MHz CPU clock. The bootloader would then set the prescaler to divide by 2, for 8MHz, and make any other settings so that all internal peripherals would behave exactly as an 8Mhz Arduino system would, before the user’s sketch starts executing. A sketch could then use a library function or some other means to switch the clock and peripherals between 16MHz and 8MHz operation.

I not sure if @bateske would be interested, or have the time to implement this overclocking capability. Those wishing to have this should probably implement and test it on the Dev Kit, to show everyone that it works and has no impact on 8MHz operation, and convince @bateske to include it in the final product.

Personally, I think just an 8MHz crystal should be used, with no overclocking capability. This would avoid possible disappointment for someone whose overclocked games kept crashing because their Arduboy had a processor with a newer revision or from a batch that wasn’t tolerant of running out of spec. It would also mean that it would be likely that a custom bootloader wouldn’t be required. A standard ATmega32U4 compatible Arduino bootloader could be used, meaning one less custom thing to develop and maintain.

Hackability:
@bateske has said that the Arduboy will be fully open-sourced, both hardware and software. I’m guessing that he wouldn’t object, and possibly even strive to make it relatively easy when possible, for someone to build their own Arduboy compatible device using readily available modules and discrete parts, without requiring custom circuit boards, surface mount parts, or other difficult construction. A compatible display module is available from Adafruit and from sources on eBay and other places. Many suitable batteries and charge control modules are available. Piezo speakers, LEDs, buttons, and other discrete components are available in through-hole or with terminals for easy soldering or breadboarding.

However, the ATmega32U4 processor is only available in surface mount packages, making it difficult to use as a discrete part. Being able to use a standard Arduino product that uses an ATmega32U4 processor would make things easier. If we want to run at 3.3V and 8MHz there aren’t many choices available, but the SparkFun Pro Micro - 3.3V/8MHz would probably be suitable. Its limitation is that it has fewer I/O pins brought out than an Arduino Leonardo or Arduino Micro (pins 11, 12, 13, A4, A5 are missing). I’ve kept this in mind in this proposal (but had some problems which I’ll note).

@bateske has stated in the Kickstarter comments:

With that in mind, I’ve tried to avoid using GPIO pins that have alternate functions which I feel would be especially useful for connecting to external devices:

  • 0 (PD2) USART1 Rx
  • 1 (PD3) USART1 Tx
  • TXLED (PD5) XCK1 This would allow the USART to be used as a second SPI host interface.
  • 2 (PD1) SDA for I2C
  • 3 (PD0) SCL for I2C

As far as I know, none of these pins have currently been used in the Dev Kit or Prototype.

Piezo Speaker:
On the Dev Kit the speaker is connected to both pins A2 and A3 shorted together. This is not good because if both A2 and A3 were made outputs, with one set high and the other low, it could cause damage to the processor. The intent was likely to allow different tones on each output to play on the speaker simultaneously. However, external mixing circuitry should have to be added to achieve this.

There’s been discussion that there may be an advantage to having the speaker on a PWM output. I suggest moving it to a single pin, 5. Pin 5 is capable of PWM from either Timer 3 or Timer 4. On the Dev Kit, pin 5 used for the Right button, so Right will have to be moved to a different pin.

It has also been suggested by @ChrisS that it may be useful to have both leads of the speaker each be connected to an I/O pin, instead of having one lead connected to ground. This may accomplish what was intended by connecting two shorted pins to the speaker. If this proves to be true and we want to implement it, then I suggest that pin 13 be used. Like pin 5, it also supports PWM using Timer 3 or Timer 4. If connected in this way, pin 13 would have to be programmed as an output set low when not in use, or else driving just pin 5 would make no sound.

With a Pro Micro, pin 13 isn’t brought out, so one of the spare “hacker” pins might have to sacrificed, along with minor code changes, for this functionality. For this reason, it would be good to recommend that sketches use primarily pin 5 to drive the speaker unless two pin operation is required. The Pro Micro would work properly with any sketches that didn’t use pin 13, by simply tying the second lead to ground.

Start Button:
@bateske has indicated that a new Start button will be added. There has been discussion about using this button (possibly using a long press) to put the unit into a low power “Sleep” mode and also to wake it back up. For a wake up, the button would have to generate an interrupt. I suggest using pin 7, since it can generate Arduino interrupt 4. The other Arduino interrupts, 0 to 3, are on my “hacker” designated pins. Other pins are capable of generating an interrupt but they aren’t directly supported by Arduino, so may be more difficult to use.

OLED Display:
The display is controlled using the SPI interface. MOSI and SCLK must be connected as they are now. RST, CS and DC can each go on any GPIO pin. Unless circuit board routing becomes an issue, I’d leave them where they are on the Dev Kit: RST 12, CS 6, DC 4.

With a Pro Micro, pin 12 isn’t brought out, so another pin may have to be found for display reset, along with minor code changes. It’s possible that the SPI MISO pin could be used. It can be a GPIO pin when not in SPI mode, so the code would have to disable SPI mode to reset the display then re-enable SPI mode. A switch or jumper may also be needed to disconnect MISO from the display, if using an ICSP to program the bootloader is required. A reset would probably only be done once, when initialising the display. Some available modules don’t even provide a reset line. They just reset the display using on board hardware upon power up.

LED:
On the Dev Kit, the LED is connected to pin 17. I’d leave it there.

On the Pro Micro, pin 17 is wired to the RXLED and not brought out to a pad. The RXLED would become the Ardyboy LED. If it was desired to move the LED off board, some wiring and soldering work would be required.

Buttons:
The 6 existing buttons could each go on any GPIO pin. I suspect the pins used on the Dev Kit were chosen only because their physical location on the processor made them easy to route to the buttons. Unless routing becomes an issue they may as well stay where they are, except Right on pin 5, which is now used for the speaker. I’d move Right to pin A2.

Battery Monitor:
There has been interest in having the processor be able to monitor the state of the battery. If we power the processor from a 3.3V regulator then we have a suitably accurate and stable voltage that can be used as the reference by the processor’s ADC. We just need to connect the unregulated battery voltage, after the power switch, to an ADC capable pin. Since the ADC input would not be allowed to go above 3.3V the battery output would have to be connected through a series resistor divider to scale the voltage to be within range. Scaling down to 75% would be about right but the exact ratio could be chosen so as to make the calculation of the true battery voltage easier. I’d make the total resistance of the two divider resistors be around 1Meg ohm and use 1% or better tolerance resistors.

A problem with the above technique is that if the battery goes too low (below about 3.4V), it will be below the dropout voltage of the regulator. If the regulator output starts to droop then the reference will change and the battery voltage readings will no longer be accurate (probably appearing not to change). There is a way, though, to detect this situation. Still with Vcc as the reference, we could occasionally use the ADC to measure the value of the bandgap. This reading should remain the same (within a small tolerance) as long as the regulator output remains at the proper 3.3V. However, if Vcc, and thus the reference voltage, starts to fall below 3.3V then the bandgap measurement value will rise in proportion. When we detect the bandgap voltage rising over time, it signals that the battery voltage is lower than the required regulator dropout voltage. We could use this to signal a battery low condition. Of note is that we can use this technique to detect a low battery even if we don’t implement the battery connection to a ADC pin. This is another advantage of powering the CPU via a regulator instead of straight from the battery.

In summary, having a battery to ADC input pin connection allows us to accurately measure the actual battery voltage, from fully charged to the point that it’s lower than the regulator dropout voltage. Measuring the bandgap for increasing over time allows us to detect that the battery voltage has fallen below the regulator dropout voltage.

I’d use pin A3 for the battery monitor input. Pin A3 is connected to the speaker on the Dev Kit, but moving it is recommended, as has previously been discussed.

Pads for hacking:
Again, @bateske has stated the intention of bringing unused pins out to test pads. I’ve actually thought of 24 signals that may be useful to have easy access to, for enhancing or repurposing an Arduboy. It would be nice if these signals:

  • were available on the back of the circuit board and not covered by the battery.
  • were on pads arranged in one or more straight rows, with pads spaced 0.1 inch apart.
  • had through holes so that standard 0.1 inch headers could be soldered in.

Even without holes for headers, rows of 0.1 inch spaced pads could make it easy to construct some kind of docking station, or an extended back containing another circuit board, using spring loaded “pogo” headers to make contact with the pads.

If I’m right that the battery will be 44.5mm x 61mm (66mm including leads), and it were placed at the bottom of the unit, then possibly there would be room to squeeze in all the pads, and traces to them, at the top, above and/or under the display. Some might also be able to go between the battery terminals.

Here are the signals:

Unused pins:

0/RXD1(PD2), 1/TXD1(PD3), TXLED/XCK1(PD5)
This is for USART1. It could be used for async serial communications, possibly to connect two Arduboys for multi-player games. It could also provide a second hardware SPI host interface.
On the Pro Micro, TXLED is an LED and not brought out to a pad. You would have to remove and/or tap off of the LED circuit to gain access to XCK1 for SPI.

2/SDA(PD1), 3/SCL(PD0)
These are the I2C data and clock pins. Many devices are avaliable which communicate using I2C bus protocol. I2C only requires these two signals plus ground. Since devices are individually addressed, more than one can be connected at the same time. One example would be an IMU board, allowing you to control the Arduboy by tilting, rotating or moving it in any direction.

11(PB7), 13(PC7), A4(PF1), A5(PF0)
Pins 11 and 13 are PWM capable. We’d only bring out pin 13 if we decide not to use it for the speaker.
On the Pro Micro, none of these pins are brought out to pads.

ICSP/SPI:

14/MISO(PB3), 15/SCLK(PB1), 16/MOSI(PB2), Processor RESET
MOSI and SCLK are used to control the display. All are required to flash the bootloader and for other In Circuit Serial Programming (ICSP). They could be used to control other SPI devices, along side of the display, by using other output(s) as CS (chip select) line(s).

Power:

GND, 3.3V, VBATT switched, VBATT unswitched
3.3V is the regulator output. It could provide power to external devices. The amount of current available would depend on the regulator used. VBATT is unregulated power straight from the battery (or through a polyfuse added for safety), before and after the power switch.

Button Pins:

8/UP(PB4), 9/LEFT(PB5), 10/DOWN(PB6), A2/RIGHT(PF5), A0/A(PF7), A1/B(PF6)
When a button isn’t pressed, it essentially isn’t in the circuit. Therefore any button pin could be used for other purposes, or even just to have an external button perform the same function.

For a pin configured as an input, if you needed to protect whatever output you connected from being shorted to ground, if the button was accidentally pressed, you just have to add a resistor between the pin and your output.

If you configure a button pin as an output, you’d have to make sure that the button wasn’t pressed when the output was high, maybe with a cover or something. Depending on what you’re driving, you could also protect from an accidental button press by setting the pin to an output for a low level but as an input, with either the internal pull-up enabled or with and external pull-up, for a high level.

All of the button pins except Start are ADC capable. So, for example, you could connect analog joysticks to them, which may be better than buttons for some games.

THE END

This is the end of my thoughts about what the ideal final Kickstarter Arduboy should be, taking into consideration what has been described and specified, while deviating as little as possible from what is known about the Dev Kit and Prototype, and attempting to remain practical.

1 Like

There isn’t anything to this - it’s not any type of party trick. The code has already been written (boards.txt file too). Some functions in the Arduino core library are written in assembly for timing (mills, micros), etc… that’s why Arduino IDE needs to know the speed of the boards it supports. It passes compile time flags to the stack to tell it the speed of the board, and then the appropriate assembly methods are used - so the timing is correct. You described the other part yourself… boot at 2MHz, then change the clock divisor. After that for all intents and purposes you’re effectively clocked at 8Mhz. To “hack” to 16Mhz one would merely need to use a boards.txt file with the Arduino IDE to tell it the final compile intends to run at 16MHz, and then a function in the core lib (or someone’s own library) could set the clock divisor back to 1 (for 16MHz operation).

I don’t have specifics for how this might work with Codebender though as I’m not at all familiar with it’s compile toolchain. I assume it might work the same way though - you’d have two targets - Arduboy (normal) and Arduboy (16Mhz)… it would set the proper compiler flags, and done.

Why can’t you run a 328 at those specs? You’re in a tough spot if you truly need 2.5k of RAM though, as that’s a unique benefit of the ATmega32u?

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

@ChrisS,
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