Particle Photons are Quite Versatile
You can do so much with a Photon. IoT stuff, yes. Especially with Particle's built-in cloud services. But there's way more than they can do.
The Basis for the Game: Pong
I've spent over a year of time by now working on a Game Engine using Java. So far, the one game implementation that exists is the classic game of Pong. The details are a bit complicated, of course, but every single game runs of a Client-Server basis. By creating a Client implementation using the Photon, it was possible to turn the Photon into a wireless controller for Pong.
Hardware
The hardware consists of a Photon as well as a breadboard, two buttons that act as up and down controls, and a bunch of wires and resistors. The breadboard itself doesn't look very pretty.
Of course, it doesn't have to. It's a prototype, and it works. That's what matters. But what good is this hardware without accompanying software to actually make it work?
Software
The software of the Photon is based on the same software as Arduinos, allowing much compatibility. In addition, Particle has provided many useful libraries in addition to the default Arduino ones that unlock additional functionality that the Photon and other Particle boards have the hardware capable of using. Among the others, there is the class TCPClient, which is what it sounds like. When used in conjunction with a TCP Server, no matter what the source, TCPClient allows for the transmission of data across the internet. Of course, in this case, the client and server are right next to each other. But by the nature of TCP, as long as both devices are connected to the internet (and not firewalled or whatever), it is possible to communicate between the devices. Compared to Bluetooth or other near-range communications, using the internet effectively extends the range to anywhere in the world.
Of course, anywhere in the world is a bit optimistic, as this is Pong after all. There is no way that the Photon is powerful enough to display the real-time playing field of Pong, at least not with the fidelity required to play it well. Thus, the Photon is effectively tied to the computer displaying Pong, a sad reality for the once-limitless Photon.
Communication How?
On the Java side, the server makes use of Java's SocketChannel, ServerSocketChannel and ByteBuffer classes. The server itself runs based on the tick model. Any data that needs to be sent is aggregated until the end of a tick, when it is sent all at once in a manner similar to Nagle's algorithm. A separate thread exists to read packets received by the TCP and UDP channels so that processing is possible as soon as a tick begins.
The Photon uses the Firmware's built-in class TCPClient, akin to SocketChannel. But before it can connect, it has to know what to connect to. That's why functions to set the host address and port are exposed using the Particle Cloud. Via the Particle app, it's possible to tell the Photon what to connect to. From there, the TCPClient instance attempts to connect to the ServerSocketChannel on the server. If all is done properly, including setting up the host, then the Photon will connect to the Computer and the game will begin.
Using the two different backends is no problem, however, as they are unified by TCP (and UDP, but it's not used in this case). On the Photon, all the packets received are discarded, as they wouldn't be useful anyways. However, it does send one packet to the server in the format of an Input Packet. What goes into that packet? Time to find out...
Using the two different backends is no problem, however, as they are unified by TCP (and UDP, but it's not used in this case). On the Photon, all the packets received are discarded, as they wouldn't be useful anyways. However, it does send one packet to the server in the format of an Input Packet. What goes into that packet? Time to find out...
Anatomy of a Packet
So what goes into the packet that's sent? Well, every packet sent has its ID as a 4-byte int added to the buffer first. Then, all the data that the packet contains is added to the buffer. In the case of the Input Packet, its ID is 6. So the integer 6 is written into the buffer as 00 00 00 06. The data of the input packet is a 2-byte short that specifies the player number, and a 1-byte byte that specifies the direction that the player wants to move the paddle. The player number for the Photon should always be 1, so the player number is written to the buffer as 00 01. The direction that the player wants to move is dependent on the buttons pressed. Internally, the directions are known as 1 for up, 0 for stop, and -1 for down. However, these values are known internally as 01, 00, and FF respectively. Finally, the end delimiter is written as a substitute to the next Packet ID, which is the minimum value for a signed 4-byte int. The internal value of that is 80 00 00 00.
Overall, the packet is thus 00 00 00 06 00 01 DIRECTION 80 00 00 00.
Overall, the packet is thus 00 00 00 06 00 01 DIRECTION 80 00 00 00.
Prove It!
The following shows the Wireshark analysis for the data. From here, we can see a few things. The Photon's IP is 141.213.30.71, so we're looking for packets sent to and from that. The highlighted packet shows one sample of input packet. Obviously, this is way more than 11 bytes of data. 88 bytes, in fact. This is due to the fact that the Photon's delay is only 5 milliseconds, which allows it to send many different inputs which are aggregated together. The server only processes the first one, as the end delimiter is encountered right after it.
Looking at just the first 11 bytes, we see that the data are indeed correct. Awesome!
No comments:
Post a Comment