Multi-player linked Arduboys via a USB host (PC)

I’m fairly sure that enough of the USB implementation is done in hardware so that it can only be a USB device, not a USB host. This means that no amount of custom wiring and electronics, and/or low level software, would allow two ATmega32U4’s to communicate with each other over their built in USB hardware. At least, nothing short of putting a device between the two which acts like a host and liaison for both devices, which of course is what the PC would be doing in my initial proposal which began this topic.

I mentioned this earlier. There is a USB pin that could be read for input by some sort of serial protocol but I can’t find anything that we could use for output that would just let us turn it on/off at will apart from any USB higher level function.

Also if we COULD hack USB in such a function the device would require a reset in order to reprogram it since we’d be pretty much breaking the USB auto-reboot.

I think I’d be prepared to tentatively disagree on that point. The hardware architecture is basically memory mapped buffers, control registers, and interrupts. Nothing of the negotiation that makes a host a host and a client a client looks to be at the ATmega32 layer. It will still need to connect to a USB port and electronics, because of voltages and low-level timing, but maybe not much more than that.

I further looked over some sample USB keyboard code for the Teensy (also an ATmega32u4 device) and the entire content of buffers, management of VID and PID, sending and receiving, and the buffer management via interrupts, is there in the C code (from here ) which is part of the app, not part of the chip. That strongly suggests you can happily send and receive packets long before either side decides what it is. The only constraint is whether or not the D- and D+ pins are connected in a way that matches on the other end. And - a big one - will the USB interface operate without power on the USB VBUS line. I think it will. The notes in the datasheet show cross connecting VBUS to ATmega power supply pins to get a bus-powered device, while VBUS in the USB interface is just monitored through a control register to see if it is connected.

I’m keeping in mind that since we have two Arduboys trying to chat to each other, we can accept anything that works. USB Host would be too difficult to implement, but we don’t need USB Host. We can get by with bare-bones send a buffer, receive a buffer, possibly even slightly lower than the equivalent of the USB control packet level. We don’t need to implement either USB host or USB client. Some low level packet USB sends are ‘best effort’ which is exactly the type of thing needed to communicate between two small devices running a shared game. It leverages the fact that USB devices need to be able to chat just to explain who they are and set up a particular type of connection. Rather than climb the chain to managed USB devices, you just stop when you reach basic send/receive and use that.

At this level the whole USB OTG thing is just a distraction. The ATmega32 docs even indicate that the ability to read the bit for the ID pin exists, but it always returns 1 - there is no real pin. But getting two devices to agree on a peer to peer protocol when you don’t need to be compatible with anything else is far less difficult than building the USB protocol stack.

This is a design space that is not well explored, because the need to connect two Arduinos is likely less common than the need to connect an Arduino to a PC serial or USB port. And if you’re starting from scratch, with full hardware design control, you would use either the SPI or serial links to connect two Arduinos. There are easier ways to do this when you have all the design options available, so nobody is trying to leverage USB hardware in non-standard ways.

This is classic 8-bit console thinking, of course. There are no external standards - there’s only what works. The only standard that matters is the hardware, because everyone has the same thing. Anything the hardware will repeatedly and consistently do for you is fair game - whether it’s expected from the docs or not. This is the same type of thinking that rewrites video memory at the end of scan lines to get closer to bit-mapped graphics on small computers that were only supposed to have character graphics.

Uncertainty remains, but this is enough to give me some confidence. I think I’m off to kickstarter for a buddy pack! Even if peer to peer doesn’t work out, the kids and I can still have 8 bit wallet game systems!

1 Like

I kind of agree with you, but even the Arduino docs say that only more powerful Arduino boards can play USB Host (Due, etc).


It could be that being a host requires too much code or memory (and those are in short supply). Or that we’re missing part of the hardware. We do have a USB controller chip inside the CPU that the software drives… it could also be something important in the controller is required for Host… I honestly don’t know enough to say for sure. If possible I bet it’s not easy.

I don’t think it has been mentioned yet but there are six pads on the back of the arduboy this is most likely a programming header it might be possible to solder a connector to the back if you are extremely careful.

Most likely some of these pins are RX/TX/Gnd/Power. This would probably be the easiest point to connect.
Also it might be possible to solder an IR receiver and an IR Led to the pins then you could have wireless multiplayer. However I would not be willing to risk breaking my DEV kit to test either of these options.

If you’e willing to solder a whole new world opens up to you. My only interest (speaking only for myself) was if we could use the manufactured and already exposed USB port for 2 player communication. From everything I’ve seen so far I think that answer is no.

I think running it through a central system such as a PC would be fine and could offload so much work onto the PC if it is not needed instantly.

Regardless of what pads are on the development kit version:

But those buffers can only contain raw data to be packetized with additional header and trailer bytes by the hardware then sent to a host, or data that has been received by the hardware in packets from a host. The host is the master; the device is a slave. Data packets can only be sent by the device to the host when the host requests it by sending an in token packet. Data packets are sent by the host by preceding them with an out token packet.

The ATmega32u4’s USB hardware is not capable of generating an in packet, and you can’t generate one via software (buffer contents can only go out as data packets). Therefore, there’s no way for one ATmega32u4 to signal the other to send a packet. Likewise, an ATmega32u4 wouldn’t be able to generate the out packet required as a host to be sent before sending a data packet.

In summary, no data can be sent or received over the USB bus without leading in or out token packets which are received and handled by the ATmega32u4’s hardware, not software. The ATmega32u4’s USB hardware doesn’t have the capability to behave as a host to send these token packets, so the sending of and receiving of data packets, from data set in the buffers, is impossible.

Further, in addition to in and out, there are other required token packets that only a host can send, such as setup. The ATmega32u4 wouldn’t be able to generate these using hardware or software either.

Enough of the low level USB functions are implemented in the ATmega32u4’s hardware that it requires a host on the other end. But, the ATmega32u4 on the other end doesn’t have the capabilities to adequately assume the roll of a host.

I found this tutorial useful, along with the ATmega32u4 datasheet, in helping to understand all of this.


And – that’s why it was “tentatively disagree”. MLXXXp, those are invaluable details for sorting this out.

That BeyondLogic reference for USB is fantastic. It reminds me of just how much “not well understood” technology is buried in our current devices. For me, in spite of what I did know about USB, I didn’t know it down to this level. Reading stuff like that just sucks me right in for hours at a time.

So - we are not going to be sending any almost-USB packets between a pair of Arduboys connected by a cable.

But hardware can still have hidden talents. Go take a look at the forums here where they are doing multilevel gray scale demos on an Arduboy “black and white” display.

Going back over the datasheet with the BeyondLogic details in my mind, I would test a different approach. It appears that creative use of the DETACH and LSM control bits may be able to cause the USB Data lines to change voltage. On the other end of the cable, this may be sufficient to trigger a WAKEUPI interrupt. If that actually happens, add some creative use of software timers, and you’ve got the weirdest serial port going. As a technology, this is roughly equivalent to Morse code - but if it works, it may be enough to allow the transmission of a few tens or hundreds of bits between two stock Arduboys connected with a stock OTG Micro/Micro cable. This potential ability would need to be validated in testing - this is way out of plan for the chip and it’s architecture, and success is definitely not guaranteed.

I will note that going with a hub PC type of device will absolutely work, and can even have a good shot at enabling not only two-player, but also multi-player, modes, along with easy configuration updates such as levels, and maybe even a tiny portable loader for changing games on the road. With careful thought about what is needed, it could be portable and compact - essentially a Arduboy Pocket Server. At the end of the day, though, it’s still another device, and it won’t be something users can easily find in any technology store nor are they likely to have a portable version on hand. I would be concerned that although it would be capable, it would be too rare.

Getting around that for some of the users is why I would also want to work out a standard cable solution. If you and a friend discover you both have an Arduboy, the addition of a cable you might find in the cell phone shop is enough to get you into head-to-head mode. Alternatively, a pair of the usual USB micro cables could be back-to-backed with a USB type A gender changer, something that has already been available for years, and something small and inexpensive enough that a dedicated Arduboy gamer might buy and carry one just to have it on hand.

Also - I want to thank you. Involvement like yours is what will make a project like this get up and really run. It’s because of responses like yours that I have committed to a buddy pack - can’t test those multi-player modes without having several on hand!!!

The “pad” is connected and can be polled via VBUSTI… and is hardware interruptible (search PDF for VBUSTI). That is the source I was talking about you could hack to maybe be an input pin. And the LSM bit: “The LSM bit in UDCON register allows to select an internal pull up on D- (Low Speed mode) or D+ (Full Speed mode) data lines.” DETACH allows you to attach that circuit to the USB regulator. Page 246.

I have no idea if any of this is enough to get a signal out. I’d have to hook up a voltmeter and run some sketch tests.

Maybe I misread the datasheet, but I think you have crossed some wires.

VBUS refers to the +5v power line of the USB connection. DETACH and LSM change pull up resistor values attached to the D+ and D- lines. Those control bits should never affect any monitoring of VBUS. The WAKEUPI interrupt is specifically looking for state changes which would, to my thinking, include changes to the Data lines.

Slightly more specifically, I would test for wakeup interrupts with DETACH having the lines free-floating, while the other end device connects the lines and flips LSM to raise first one data line, then the other.

I said VBUSTI, it’s a USB interrupt source.

What needs to be tested is measuring output voltage on ANY fo the usb pins we can control. I’m 90% sure we can get input.

You have to consider that whatever scheme you come up with can’t use so much processing power that it causes a burden on the actual game, or other application, that you wish to use it with. Code size would also have to be a considered.

If the hardware can do it I don’t think the code size would be that much of an issue… mostly it’s timing, flipping bits, and then maybe a small transmission/receive buffer.

I was going to draw up a simple diagram covering two Arduboys, the ATmega32u4’s and the connections, with some of the internals from the datasheet mapped in. I figured it would help discussions.

But - first - should we make “Peer-to-peer Arduboy exploration” a separate topic? Running several Arduboys hubbed should work just fine at the USB level, and the issues and questions there will be complete different that exploring what might work in the peer-to-peer space.

I’ll give it a couple hours - chime in if you want to leave the discussion here, otherwise: new topic.

It might be best to make it a new topic, but please continue from this one by using the + Reply as linked Topic feature that you get at the top right, when you hover your mouse over a post. You should decide whether you want the new topic to be just for USB connections, or also include other peer-to-peer methods, such as using the Rx and Tx pins as previously discussed, and make this clear in the subject.

If you do start a new topic, I’ll change the title of this tread to something like Multi-player linked Arduboys via a USB host PC

You could plug 8 Arduboys into a laptop and if you ran some sort of “hub” program put they’d all put the Arduboys on a “network”… but then you have to carry another device with you (computer, Raspberry Pi, etc). The simplest “network” would be old school hub (pre-switch)… The Arduboys send an “ID” (1-8 for 8 devices) and a packet and then the master devices just echo that packet back to every other Arduino. Boom, you can send packets and receive packets from X other devices. Then it’s just up to a software stack to do something with those packets.

You could have a small “handshake” to get the IDs also… send a random # to the master and it will echo the random # back along with your ID. From that point you talk on your ID. Very simple version of DHCP. :slight_smile:

Old school? Pre-switch? Are we taking about USB or Ethernet?

All USB port expanders are called hubs, and they all require a USB host as a liaison if you want one USB device on a hub to communicate with another USB device.