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

Do you mean between two Arduboys? If so, the answer is: possibly. I2C is really only meant for chip to chip communications on a circuit board or within a single chassis.

If you kept the wires fairly short, say under 2 meters (6 feet), and ran at a slow I2C clock speed, it would probably work.

One issue might be mismatched voltages, like when one Arduboy has a full battery and the other has a fairly low battery, or when one Arduboy is powered by USB and the other’s on battery. In this case you may need level shifters or clamping circuitry to prevent damaged inputs due to overvoltage. If power and ground was provided on the connector, it might be possible to switch off the battery of one Arduboy and power both of them from the other, thus guaranteeing that the voltages would be matched. This would be true for Rx/Tx serial connections as well.

Another thing is that I2C uses open collector/drain drivers, so you need pull up resistors on each signal. This means that power and ground would have to be available on the connector.

I don’t think there would be any advantage to using I2C instead of just serial using Rx and Tx (which wouldn’t need pull ups), unless you wanted to connect more than 2 Arduboys together.

1 Like

I think with i2c you get the protocol timing and stuff for “free”, or is that all done in software not hardware? Most of the hardware stuff you mentioned there is over my head. :smile:

1 Like

Something that would get around the problem of mismatched signal voltages, and allow much longer cable lengths, for an Rx/Tx serial link, would be to put RS232 converters at each end of the cable. It would be simple but would require that power was available on the Arduboy connector.

Something like the one shown in the following picture is what I had in mind. They’re small and cheap and easy to obtain. You could wire one to each end of a cable and enclose it in heat shrink tubing.

Of course, all this depends on having a connector added to the production Arduboy that includes at least Rx, Tx, Power and Ground, or having people hack the Arduboy to bring out these signals.

It’s good that at least @bateske said in a comment on Kickstarter:

Extra Pinouts for Hacking: Yes any of the unused pins from the microcontroller will be brought out to test pads so you can open the device and hack it.

I think a Raspberry Pi would be a good idea and stick a battery on it and it can be a 4 player portable server.

Is it possible for an external device to write directly to the Arduboy RAM or EEPROM whilst it is switched on? At that point, we could even be considering the possibility of storing some slow large data on a raspberry pi like maps and only needs to be on the device

The built in I2C capabilities just give you the ability to connect multiple devices over just two wires (plus a ground wire) and easily address them. You still have to define the protocol for what you’re going to send and receive.

If you only want to talk back and forth between two Arduboys, using the UART on the Rx and Tx pins is probably easier. Also, as I posted previously, solving signal voltage mismatches and achieving long cable lengths would be quite easy using Rx/Tx.

If you want to talk between more that two Arduboys, using a small PC with USB connections, as I proposed in the original post, would probably be easier than coming up with some kind of multi-way I2C cable with the proper pull ups and signal protection.

No. You would have to have your sketch receive serial commands and data, then this sketch would have decode them and write to RAM or EEPROM itself.

I started a topic today about this here.

I don’t know if it would be that difficult. What you thinking of already exists - it’s called USB On The Go, usually USB OTG.

My phone (now nearly two years old) has this, and it means I can either plug it into a computer as a mass storage device OR I can plug a mass storage device into it. I can also plug a keyboard or a sound card into my phone.

The key seems to be that fifth pin on the Micro B connector. There are Micro B to Micro B cables (I have several) but they have one key difference – one end has the ID pin grounded, the other lets it float. Thus, the cable determines which device is client and which is host. They are usually called “Micro B to Micro B HOST” cables. The USB shell on both ends is identical, with the only difference being the ID pin as described above.

All this would be meaningless except that I have seen application notes indicating that the ATmega32 can actually do USB OTG. Perhaps the ID pin connection needs to be somewhat standard (and I have NO IDEA what standard is for this platform), and then it could be possible that two Arduboys could be connected with a cable for head to head games. I do know that the Arduboy is somewhat “USB flexible” since they show the idea of using it as a custom keyboard.

Perhaps someone with more background on the Arduino platform can chime in. I think this is a key item, and I have been looking for info before I finalize my backing. More particularly, I was actually looking for circuit diagrams, but (not surprising) did not find them. If the simple connection of one pin in the USB connector is all that is needed to make this work, then it would be worth letting Kevin and his team know about this possibility.

You are probably mistaken in you interpretation of said application notes. OTG requires one device configure itself as a USB host and the other to act as a USB device. Both devices must be able to handle both host and device modes. The ID pin just tells each device which mode it should use.

Unfortunately, the ATmega32U4 used by the Arduboy only supports device mode. It cannot go into host mode, so OTG can’t be supported.

It’s probable (though I don’t know for sure) that the ATmega32U4 could connect with an OTG capable device as long as that device is put in to host mode by inserting the correct end of the cable. However, with two Arduboys connected together neither would be able to assume the host role. I don’t think you even could connect two Arduboys together with a standard OTG cable because the ends are supposed to be different and only the “B” end could be plugged into the “B” type connector on the Arduboy.

There’s nothing exotic about the ID pin. It’s left unconnected on the “B” end of the cable and tied to ground on the “A” end.

Ah - too concise there, I guess. It can do USB OTG Client, but not USB OTG Host. Hmmm. Ok. Thank you for the clarification!

My final question then (and it’s a real newbie question) is regarding how the USB protocol is implemented on the ATmega32? Is it all buried in locked in device firmware, just exposed through I/O type calls? Or is the ATmega implementation exposing the lowest hardware level, and the sketch brings in most of the code to make a particular type of USB client device happen?

What I would want to check next is whether the data communication capabilities are completely hidden in the lower layers, or can you use the hardware to communicate ATmega to ATmega over a USB cable, but having to invent some on-the-wire protocol that can use the existing hardware?

It’s been a while since I’ve cracked open a 400 page datasheet, but I could use some engrossing reading on the subway!

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 https://www.pjrc.com/teensy/rawhid.html ) 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).

Ref: http://www.arduino.cc/en/Reference/USBHost

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.

2 Likes

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.