{"id":9355,"date":"2020-11-02T22:44:12","date_gmt":"2020-11-02T22:44:12","guid":{"rendered":"https:\/\/wolles-elektronikkiste.de\/pong-for-arduino-computer-table-tennis"},"modified":"2020-11-29T12:15:00","modified_gmt":"2020-11-29T12:15:00","slug":"pong-for-arduino-computer-table-tennis","status":"publish","type":"post","link":"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis","title":{"rendered":"Pong for Arduino &#8211; computer table tennis"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">About the post<\/h2>\n<p>In this post I would like to introduce you to my &#8220;Pong for Arduino&#8221;, inspired by the classic from the last century and for a 1.8 inch display. Some may have got to know the game under different names, but everyone (from my age group) knows it and a lot of people associate nostalgic feelings with it.&nbsp;<\/p>\r\n<p>In the video you can see it in action. Unfortunately, the quality of filming the TFT display has suffered a little. In the original it looks more beautiful, especially the &#8220;pull-up effect&#8221; of the ball is not so pronounced.&nbsp;<\/p>\r\n<p>And of course, my Pong for Arduino lacks the typical old look. In the first step, however, I was already happy to be able to implement it in principle. Maybe you want to develop a more &#8220;original&#8221; version of it.<\/p>\r\n\n<figure class=\"wp-block-video\"><video height=\"480\" style=\"aspect-ratio: 720 \/ 480;\" width=\"720\" controls=\"\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Tennis_bearb_klein.mp4\"><\/video><figcaption>Pong for Arduino in action<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\">The hardware<\/h2>\n<p>The circuit for Pong for Arduino is not very complex. Two 10 k<span style=\"font-family: 'Arial',sans-serif;\">\u03a9<\/span> potentiometers serve as control for the rackets. A LOW-active button provides the signal for the start of the game or the restart. The screen is a 1.8 inch display with a fabulous 128&#215;160 pixels, as you can get for less than ten euros e.g. on <a href=\"https:\/\/smile.amazon.de\/s?k=tft+display+1.8+zoll+arduino&amp;__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91&amp;ref=nb_sb_noss\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon.<\/a> I used a version with SD card slot because I just had it in my drawer &#8211; of course you don&#8217;t need it.<\/p>\r\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Display.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"475\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Display-1024x475.jpg\" alt=\"The display for Pong for Arduino\" class=\"wp-image-8139\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Display-1024x475.jpg 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Display-300x139.jpg 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Display-768x356.jpg 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Display-1320x612.jpg 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Display.jpg 1800w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure><p>As a microcontroller I used an Arduino Nano. This is nicely small and can be powered via its USB port. For this purpose, I like to use a power bank. The power consumption is large enough that it does not turn off. The USB socket is also handy if you want to change the sketch again. You don&#8217;t even have to screw up the housing.<\/p>\r\n<p>I put it all in a plastic case. The main board is mounted on spacers. For the USB socket of the Arduino I sawed out a hole. Plastic is not a nice material for sawing or milling as it melts quickly, and thus the hole looks a bit ugly. I screwed in the display and cut a (even not perfect) slot into the case for its pins. For the pushbutton I drilled four small holes and fixed it with superglue. For strain relieve of the cables connecting the control units I have used cable ties:<\/p>\r\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Hauptkasten.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"825\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Hauptkasten-1024x825.jpg\" alt=\"The main unit of the Pong for Arduino. \" class=\"wp-image-8140\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Hauptkasten-1024x825.jpg 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Hauptkasten-300x242.jpg 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Hauptkasten-768x619.jpg 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Hauptkasten-1320x1063.jpg 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Hauptkasten.jpg 2000w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>The main unit of the Pong for Arduino. <\/figcaption><\/figure>\n<figure class=\"wp-block-image\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Hauptplatine.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Hauptplatine-1024x768.jpg\" alt=\"The main unit, opened\" class=\"wp-image-8141\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Hauptplatine-1024x768.jpg 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Hauptplatine-300x225.jpg 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Hauptplatine-768x576.jpg 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Hauptplatine-1320x990.jpg 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Hauptplatine.jpg 2000w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>The main unit, opened<\/figcaption><\/figure><p>The two control units are small plastic housings on which I have mounted the 10 k<span style=\"font-family: 'Arial',sans-serif;\">\u03a9<\/span> potentiometers. As you can see, there is actually nothing in the case. It is only for the purpose of strain relieve and for the feel. The control units are connected to the main unit via three-pole cables.&nbsp;<\/p>\r\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Steuerung_offen.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"623\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Steuerung_offen-1024x623.jpg\" alt=\"The control unit \" class=\"wp-image-8142\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Steuerung_offen-1024x623.jpg 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Steuerung_offen-300x183.jpg 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Steuerung_offen-768x468.jpg 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Steuerung_offen-1320x804.jpg 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Steuerung_offen.jpg 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>One of the control units, opened<\/figcaption><\/figure>\n<h3 class=\"wp-block-heading\">The wiring for Pong for Arduino <\/h3>\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"772\" height=\"404\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Anschluss_Schema.png\" alt=\"Connection scheme for Pong for Arduino\" class=\"wp-image-8145\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Anschluss_Schema.png 772w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Anschluss_Schema-300x157.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Anschluss_Schema-768x402.png 768w\" sizes=\"auto, (max-width: 772px) 100vw, 772px\" \/><figcaption>Connection scheme<\/figcaption><\/figure><p>The display is controlled via SPI. The display only accepts data and does not send anything back, thus MISO (D12) remains unconnected. An active-LOW interrupt with internal pull-up is set up at D2. A push button triggers the interrupt. Between the 10 k<span style=\"font-family: 'Arial',sans-serif;\">\u03a9 <\/span>Potis and GND there is still a 1 k<span style=\"font-family: 'Arial',sans-serif;\">\u03a9<\/span> resistor, in order to limit current at the end stop. The potentiometer voltage is read at A0 or A1.&nbsp;<\/p>\r\n<p>&nbsp;<\/p>\r\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Tennis_Wiring_combined.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"795\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Tennis_Wiring_combined-1024x795.png\" alt=\"Fritzing scheme of Pong for the Arduino\" class=\"wp-image-8143\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Tennis_Wiring_combined-1024x795.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Tennis_Wiring_combined-300x233.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Tennis_Wiring_combined-768x596.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Tennis_Wiring_combined.png 1145w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Fritzing scheme<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\">The Pong for Arduino Sketch<\/h2>\n<p>The programming of the sketch took me a lot more time than I thought and it has also become much more complex than I expected at first. I will try to guide you through the code in broad strokes so that you can customize it &#8211; if you want &#8211; to your own liking. I hope you can follow my logic!<\/p>\r\n<p>The program code of Pong for Arduino consists of four parts:<\/p>\r\n<ul>\r\n<li>pong.ino: contains definitions, setup, the main loop and some functions<\/li>\r\n<li>draw.ino: contains functions that primarily have something to do with the display<\/li>\r\n<li>Ball.h\/Ball.cpp: the class for the ball<\/li>\r\n<li>Racket.h\/Racket.cpp: the class for the two rackets<\/li>\r\n<\/ul>\r\n<p>You can download the code from Github <a href=\"https:\/\/github.com\/wollewald\/Pong_for_Arduino\" target=\"_blank\" rel=\"noopener noreferrer\">via this link.<\/a> Unpack it into your library folder. Open Pong.ino in the Arduino IDE and save the sketch in your sketch folder. &nbsp;<\/p>\r\n<p>In addition, the two libraries SPI and TFT, are used. The TFT library extends the Adafruit libraries GFX and ST7735. These should already be in place. But also no problem to install them later. Most of the TFT library functions I used should be self-explanatory. For more details check <a href=\"https:\/\/www.arduino.cc\/en\/Reference\/TFTLibrary\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>.<\/p>\r\n\n<h3 class=\"wp-block-heading\">Fundamental considerations<\/h3>\n<ul>\r\n<li>Note that the TFT display originates at the top left. This means that the x-values of the pixels increase from left to right, the y-values increase from top to bottom, which takes getting used to.&nbsp;<\/li>\r\n<li>The ball is four by four pixels. When I talk about the position of the ball, it refers to the origin (upper left corner). With regard to the reference point, the same applies to the rackets.<\/li>\r\n<li>The ball has four directions of movement, Right-Up (DIR_RU), Right-Down (DIR_RD), Left-Up (DIR_LU) and Left-Down (DIR_LD). The direction is defined in Ball.h as enum: <code> enum BallDir {DIR_LU = 1, DIR_LD, DIR_RU, DIR_RD, NEW_BALL}<\/code>. A new ball does not initially have a defined direction, for this NEW_BALL is needed.&nbsp;<\/li>\r\n<li>A motion step consists of two pixels in horizontal and one step in the vertical direction. The angle vs. the horizontal is therefore always the same (the absolute value). My good old Pong for TV had besides the &#8220;normal&#8221; angle a bigger one. This was activated when you hit the ball with the edge of the racket &#8211; that&#8217;s maybe something I could implement in a Pong for Arduino 2.0.&nbsp;<\/li>\r\n<li>If a point has been scored, the game status is briefly displayed, then the game will automatically continue.&nbsp;<\/li>\r\n<li>The game ends when one of the players has 15 points.<\/li>\r\n<\/ul>\r\n\n<h3 class=\"wp-block-heading\">pong.ino<\/h3>\n<p>The main sketch pong.ino starts with definitions and the integration of the libraries.\u00a0 I hope that the code is understandable by the many comments (sorry, still only in German) inserted.\u00a0<\/p><div class=\"scroll-paragraph-long\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-title=\"pong.ino\" data-enlighter-group=\"pong.ino\" data-enlighter-language=\"cpp\">#include\u00a0&lt;TFT.h&gt;\r\n#include\u00a0&lt;SPI.h&gt;\r\n#include\u00a0&lt;Ball.h&gt;\u00a0\u00a0 \/\/\u00a0Bibliothek\u00a0f\u00fcr\u00a0den\u00a0Ball\r\n#include\u00a0&lt;Racket.h&gt;\u00a0\u00a0 \/\/\u00a0Bibliothek\u00a0f\u00fcr\u00a0den\u00a0Schl\u00e4ger\r\n#define\u00a0CS\u00a0\u00a0\u00a010\u00a0 \/\/\u00a0Chip\u00a0Select\u00a0Pin\r\n#define\u00a0DC\u00a0\u00a0\u00a08\u00a0\u00a0 \/\/\u00a0Data\u00a0\/\u00a0Command\u00a0Pin\r\n#define\u00a0RESET\u00a0\u00a09\u00a0\u00a0 \/\/\u00a0Reset\u00a0Pin\r\n#define\u00a0TAST_PIN\u00a02\u00a0\u00a0 \/\/\u00a0Taster\u00a0Pin\u00a0f\u00fcr\u00a0Game\u00a0Reset\r\n#define\u00a0RED\u00a01\u00a0\u00a0 \/\/\u00a0Farbendefinition\u00a0-&gt;\u00a0siehe\u00a0colour\u00a0Funktion\r\n#define\u00a0BLUE\u00a02\r\n#define\u00a0GREEN\u00a03\r\n#define\u00a0BLACK\u00a04\r\n#define\u00a0LIGHTBLUE\u00a05\r\n#define\u00a0GREY\u00a06\r\n#define\u00a0RIGHT_RACKET_XPOS\u00a0148\u00a0\u00a0 \/\/\u00a0x-Position\u00a0rechter\u00a0Schlaeger\r\n#define\u00a0RIGHT_RACKET_POTI_PIN\u00a01\u00a0\/\/\u00a0der\u00a0Pin\u00a0f\u00fcr\u00a0den\u00a0Poti\u00a0vom\u00a0rechten\u00a0Schlaeger\r\n#define\u00a0LEFT_RACKET_XPOS\u00a010\u00a0 \/\/\u00a0x-Position\u00a0linker\u00a0Schlaeger\r\n#define\u00a0LEFT_RACKET_POTI_PIN\u00a00\u00a0 \/\/\u00a0der\u00a0Pin\u00a0f\u00fcr\u00a0den\u00a0Poti\u00a0vom\u00a0linken\u00a0Schlaeger\u00a0\r\n#define\u00a0WINSCORE\u00a015\u00a0 \/\/\u00a0Bei\u00a015\u00a0gewinnt\u00a0man\r\n#define\u00a0BALLDELAY\u00a01000\u00a0 \/\/\u00a0Verz\u00f6gerungswert\u00a01\u00a0in\u00a0microseconds\r\n#define\u00a0BALLDELAY2\u00a06500\u00a0\/\/\u00a0Verz\u00f6gerungswert\u00a02\r\n\r\nvolatile\u00a0bool\u00a0gameReset;\u00a0\/\/\u00a0steuert\u00a0den\u00a0Spielreset,\u00a0wird\u00a0\"TRUE\"\u00a0bei\u00a0Tasterdruck\u00a0(Interrupt)\r\nconst\u00a0int\u00a0RACKET_WIDTH\u00a0=\u00a02;\u00a0\/\/\u00a0Schlaeger\u00a0Breite\r\nconst\u00a0int\u00a0RACKET_HEIGHT\u00a0=\u00a012;\u00a0\/\/\u00a0Schlaeger\u00a0Hoehe\r\nconst\u00a0int\u00a0BALL_WIDTH\u00a0=\u00a04;\u00a0\/\/\u00a0Der\u00a0Ball\u00a0ist\u00a04x4\u00a0Pixel\u00a0gro\u00df\r\nint\u00a0currentLeftRacketYPos;\u00a0\/\/\u00a0y\u00a0Position\u00a0linker\u00a0Schlaeger\u00a0\r\nint\u00a0currentRightRacketYPos;\u00a0\/\/\u00a0y\u00a0Position\u00a0rechter\u00a0Schlager\r\nint\u00a0currentBallXPos;\u00a0\/\/\u00a0x\u00a0Position\u00a0Ball\r\nint\u00a0currentBallYPos;\u00a0\/\/\u00a0y\u00a0Position\u00a0Ball\r\n\/\/\u00a0Position\u00a0bedeutet:\u00a0Koordinaten\u00a0der\u00a0linken\u00a0oberen\u00a0Ecke\r\nint\u00a0score[2]={0,0};\u00a0\/\/\u00a0Spielstand\r\nBallDir\u00a0currentFlightDir;\u00a0\/\/\u00a0Flugrichtung\u00a0des\u00a0Balls\u00a0(in\u00a0Ball.h\u00a0definiert)\r\n\r\nTFT\u00a0myScreen\u00a0=\u00a0TFT(CS,\u00a0DC,\u00a0RESET);\r\nBall\u00a0myBall;\r\nRacket\u00a0leftRacket(LEFT_RACKET_XPOS,\u00a0LEFT_RACKET_POTI_PIN);\r\nRacket\u00a0rightRacket(RIGHT_RACKET_XPOS,\u00a0RIGHT_RACKET_POTI_PIN);\r\nenum\u00a0racketSide\u00a0{LEFT=0,RIGHT}\u00a0racket;\r\n\r\nvoid\u00a0setup(){\r\n\u00a0\u00a0pinMode(TAST_PIN,\u00a0INPUT_PULLUP);\u00a0\/\/\u00a0Tasterpin:\u00a0bei\u00a0Low\u00a0ist\u00a0aktiv\r\n\u00a0\u00a0attachInterrupt(digitalPinToInterrupt(TAST_PIN),\u00a0gameResetPress,\u00a0FALLING);\r\n\u00a0\u00a0myScreen.begin();\u00a0\u00a0\/\/\u00a0Bildschirm\u00a0wird\u00a0initialisiert\r\n\u00a0\u00a0myScreen.setRotation(1);\u00a0\/\/\u00a0Portrait\u00a0-&gt;\u00a0Landscape,\u00a00\/0\u00a0=\u00a0oben\u00a0links\r\n\u00a0\u00a0myScreen.setTextSize(4);\u00a0\/\/\u00a0Textgroesse\u00a0fuer\u00a0Spielstand\r\n\u00a0\u00a0myScreen.background(0,0,0);\u00a0\u00a0\/\/\u00a0einmal\u00a0Bildschirm\u00a0schwarz\u00a0machen\r\n\u00a0\u00a0showScore();\u00a0\/\/\u00a0Spielstand\u00a0(hier\u00a00:0)\u00a0wird\u00a0angezeigt\r\n\u00a0\u00a0resetField();\u00a0\/\/\u00a0das\u00a0Spielfeld\u00a0wird\u00a0angelegt,\u00a0die\u00a0Schl\u00e4ger\u00a0erscheinen\r\n\u00a0\u00a0myBall.newBall();\u00a0\/\/\u00a0jetzt\u00a0kommt\u00a0der\u00a0Ball\u00a0ins\u00a0Spiel\r\n\u00a0\u00a0gameReset\u00a0=\u00a0false;\u00a0\/\/\u00a0kein\u00a0Reset\u00a0bis\u00a0Tasterduck\u00a0\r\n}\r\n\r\nvoid\u00a0loop(){\u00a0\u00a0\r\n\u00a0\u00a0myBall.move();\u00a0\/\/\u00a0Der\u00a0Ball\u00a0macht\u00a0einen\u00a0Schritt\r\n\u00a0\u00a0checkPositions();\u00a0\/\/\u00a0die\u00a0Position\u00a0der\u00a0Schl\u00e4ger,\u00a0des\u00a0Balls\u00a0und\u00a0die\u00a0Flugrichtung\u00a0werden\u00a0ermittelt\r\n\u00a0\u00a0drawBall();\u00a0\/\/\u00a0der\u00a0Ball\u00a0wird\u00a0an\u00a0der\u00a0neuen\u00a0Position\u00a0\"gemalt\"\u00a0und\u00a0die\u00a0alten\u00a0Pixel\u00a0gel\u00f6scht\r\n\u00a0\u00a0myBall.fenceCheck();\u00a0\/\/\u00a0Check\u00a0ob\u00a0der\u00a0Ball\u00a0die\u00a0Bande\u00a0ber\u00fchrt\r\n\u00a0\u00a0\/\/\u00a0Check,\u00a0ob\u00a0der\u00a0Ball\u00a0einen\u00a0Schl\u00e4ger\u00a0(von\u00a0der\u00a0richtigen\u00a0Seite!)\u00a0ber\u00fchrt:\r\n\u00a0\u00a0myBall.racketHitCheck(LEFT_RACKET_XPOS,\u00a0currentLeftRacketYPos,\u00a0RIGHT_RACKET_XPOS,\u00a0currentRightRacketYPos,\u00a0BALL_WIDTH,\u00a0RACKET_HEIGHT,\u00a0RACKET_WIDTH);\r\n\u00a0\u00a0moveRacketsToNewPos(false);\u00a0\/\/\u00a0der\u00a0Schl\u00e4ger\u00a0bewegt\u00a0sich\u00a0zur\u00a0aktuellen\u00a0Position\r\n\u00a0\u00a0if(myBall.goalCheck()){\u00a0\/\/\u00a0Wenn\u00a0der\u00a0Ball\u00a0ueber\u00a0die\u00a0Linie\u00a0geht,\u00a0dann.....\r\n\u00a0\u00a0\u00a0\u00a0deleteBall();\u00a0\/\/\u00a0Randpixel\u00a0beseitigen\r\n\u00a0\u00a0\u00a0\u00a0if((currentFlightDir==DIR_RU)||(currentFlightDir==DIR_RD))\u00a0score[0]++;\u00a0\/\/\u00a0wessen\u00a0Punkt?\r\n\u00a0\u00a0\u00a0\u00a0else\u00a0score[1]++;\r\n\u00a0\u00a0\u00a0\u00a0showScore();\r\n\u00a0\u00a0\u00a0\u00a0if(!gameReset){\u00a0\/\/\u00a0n\u00e4chste\u00a0Runde\u00a0innerhalb\u00a0eines\u00a0Spiels\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0resetField();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myBall.newBall();\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\u00a0\u00a0\u00a0\u00a0else\u00a0newGame();\u00a0\/\/\u00a0neues\u00a0Spiel\u00a0\r\n\u00a0\u00a0}\r\n}\r\n\r\nvoid\u00a0gameResetPress(){\u00a0\u00a0\/\/\u00a0Routine\u00a0f\u00fcr\u00a0den\u00a0Interrupt\r\n\u00a0\u00a0gameReset=true;\u00a0\r\n}\r\n\r\nvoid\u00a0newGame(){\u00a0\/\/\u00a0Routine\u00a0f\u00fcr\u00a0neues\u00a0Spiel\u00a0-\u00a0selbsterkl\u00e4rend\r\n\u00a0\u00a0\u00a0myBall.newBall(NEW_BALL);\r\n\u00a0\u00a0\u00a0score[0]=0;\u00a0score[1]=0;\r\n\u00a0\u00a0\u00a0showScore();\r\n\u00a0\u00a0\u00a0resetField();\r\n\u00a0\u00a0\u00a0gameReset=false;\u00a0\u00a0\r\n}\r\n\r\nvoid\u00a0checkPositions(){\u00a0\/\/\u00a0Positionsermittlungen\r\n\u00a0\u00a0currentLeftRacketYPos\u00a0=\u00a0leftRacket.getYPos();\r\n\u00a0\u00a0currentRightRacketYPos\u00a0=\u00a0rightRacket.getYPos();\r\n\u00a0\u00a0currentBallXPos\u00a0=\u00a0myBall.getXPos();\r\n\u00a0\u00a0currentBallYPos\u00a0=\u00a0myBall.getYPos();\u00a0\r\n\u00a0\u00a0currentFlightDir\u00a0=\u00a0myBall.getFlightDir();\u00a0\r\n}\r\n<\/pre>\r\n<p>&nbsp;<\/p>\r\n<\/div>\n<h3 class=\"wp-block-heading\">draw.ino<\/h3>\n<p>Most functions in the draw.ino program section should be reasonably understandable. The functions drawBall and moveRacketsToNewPos are somewhat more complex. They are explained in detail below.<\/p>\r\n<div class=\"scroll-paragraph-long\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-title=\"draw.ino\" data-enlighter-group=\"draw.ino\">void\u00a0colour(int\u00a0farbe){\u00a0\u00a0\/\/\u00a0Farbdefinitionen\u00a0-\u00a0selbsterkl\u00e4rend\r\n\u00a0\u00a0switch(farbe){\r\n\u00a0\u00a0\u00a0\u00a0case\u00a0RED:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.fill(0,0,255);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.stroke(0,0,255);\u00a0break;\r\n\u00a0\u00a0\u00a0\u00a0case\u00a0GREEN:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.fill(0,255,0);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.stroke(0,255,0);\u00a0break;\r\n\u00a0\u00a0\u00a0\u00a0case\u00a0BLUE:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.fill(255,0,0);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.stroke(255,0,0);\u00a0break;\r\n\u00a0\u00a0\u00a0\u00a0case\u00a0LIGHTBLUE:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.fill(255,128,128);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.stroke(255,128,128);break;\r\n\u00a0\u00a0\u00a0\u00a0case\u00a0GREY:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.fill(64,64,64);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.stroke(64,64,64);break;\r\n\u00a0\u00a0\u00a0\u00a0case\u00a0BLACK:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.fill(0,0,0);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.stroke(0,0,0);\u00a0break;\r\n\u00a0\u00a0\u00a0\u00a0default:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.stroke(0,0,255);\u00a0\u00a0\r\n\u00a0\u00a0}\r\n}\r\n\r\nvoid\u00a0drawBall()\u00a0{\u00a0\/\/\u00a0Das\u00a0Bedarf\u00a0einer\u00a0gesonderten\u00a0Erkl\u00e4rung,\u00a0siehe\u00a0Beitrag\r\n\u00a0\u00a0int\u00a0formerBallXPos,\u00a0formerBallYPos;\r\n\u00a0\u00a0switch\u00a0(currentFlightDir)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0case\u00a0DIR_LU:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0formerBallXPos\u00a0=\u00a0currentBallXPos\u00a0+\u00a02;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0formerBallYPos\u00a0=\u00a0currentBallYPos\u00a0+\u00a01;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.rect(formerBallXPos\u00a0-\u00a02,\u00a0formerBallYPos,\u00a0BALL_WIDTH,\u00a0BALL_WIDTH);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0colour(BLACK);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.rect(formerBallXPos\u00a0+\u00a02,\u00a0formerBallYPos,\u00a02,\u00a04);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delayMicroseconds(BALLDELAY);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0colour(GREEN);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.rect(formerBallXPos\u00a0-\u00a02,\u00a0formerBallYPos\u00a0-\u00a01,\u00a0BALL_WIDTH,\u00a0BALL_WIDTH);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0colour(BLACK);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.line(formerBallXPos\u00a0-\u00a02,\u00a0formerBallYPos\u00a0+\u00a03,\u00a0formerBallXPos\u00a0+\u00a02,\u00a0formerBallYPos\u00a0+\u00a03);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delayMicroseconds(BALLDELAY2);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;\r\n\r\n\u00a0\u00a0\u00a0\u00a0case\u00a0DIR_LD:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0formerBallXPos\u00a0=\u00a0currentBallXPos\u00a0+\u00a02;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0formerBallYPos\u00a0=\u00a0currentBallYPos\u00a0-\u00a01;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.rect(formerBallXPos\u00a0-\u00a02,\u00a0formerBallYPos,\u00a0BALL_WIDTH,\u00a0BALL_WIDTH);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0colour(BLACK);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.rect(formerBallXPos\u00a0+\u00a02,\u00a0formerBallYPos,\u00a02,\u00a04);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delayMicroseconds(BALLDELAY);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0colour(GREEN);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.rect(formerBallXPos\u00a0-\u00a02,\u00a0formerBallYPos\u00a0+\u00a01,\u00a0BALL_WIDTH,\u00a0BALL_WIDTH);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0colour(BLACK);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.line(formerBallXPos\u00a0-\u00a02,\u00a0formerBallYPos,\u00a0formerBallXPos\u00a0+\u00a02,\u00a0formerBallYPos);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delayMicroseconds(BALLDELAY2);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;\r\n\r\n\u00a0\u00a0\u00a0\u00a0case\u00a0DIR_RU:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0formerBallXPos\u00a0=\u00a0currentBallXPos\u00a0-\u00a02;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0formerBallYPos\u00a0=\u00a0currentBallYPos\u00a0+\u00a01;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.rect(formerBallXPos\u00a0+\u00a02,\u00a0formerBallYPos,\u00a0BALL_WIDTH,\u00a0BALL_WIDTH);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0colour(BLACK);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.rect(formerBallXPos,\u00a0formerBallYPos,\u00a02,\u00a04);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delayMicroseconds(BALLDELAY);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0colour(GREEN);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.rect(formerBallXPos\u00a0+\u00a02,\u00a0formerBallYPos\u00a0-\u00a01,\u00a0BALL_WIDTH,\u00a0BALL_WIDTH);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0colour(BLACK);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.line(formerBallXPos\u00a0+\u00a02,\u00a0formerBallYPos\u00a0+\u00a03,\u00a0formerBallXPos\u00a0+\u00a06,\u00a0formerBallYPos\u00a0+\u00a03);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delayMicroseconds(BALLDELAY2);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;\r\n\r\n\u00a0\u00a0\u00a0\u00a0case\u00a0DIR_RD:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0formerBallXPos\u00a0=\u00a0currentBallXPos\u00a0-\u00a02;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0formerBallYPos\u00a0=\u00a0currentBallYPos\u00a0-\u00a01;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.rect(formerBallXPos\u00a0+\u00a02,\u00a0formerBallYPos,\u00a0BALL_WIDTH,\u00a0BALL_WIDTH);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0colour(BLACK);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.rect(formerBallXPos,\u00a0formerBallYPos,\u00a02,\u00a04);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delayMicroseconds(BALLDELAY);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0colour(GREEN);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.rect(formerBallXPos\u00a0+\u00a02,\u00a0formerBallYPos\u00a0+\u00a01,\u00a0BALL_WIDTH,\u00a0BALL_WIDTH);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0colour(BLACK);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.line(formerBallXPos\u00a0+\u00a02,\u00a0formerBallYPos,\u00a0formerBallXPos\u00a0+\u00a06,\u00a0formerBallYPos);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0delayMicroseconds(BALLDELAY2);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;\r\n\u00a0\u00a0}\r\n\u00a0\u00a0colour(GREEN);\r\n}\r\n\r\nvoid\u00a0deleteBall(){\u00a0\/\/\u00a0Geht\u00a0ein\u00a0Ball\u00a0\u00fcber\u00a0die\u00a0\"Torlinie\",\u00a0muss\u00a0er\u00a0komplett\u00a0gel\u00f6scht\u00a0werden\r\n\u00a0\u00a0colour(BLACK);\r\n\u00a0\u00a0myScreen.rect(currentBallXPos,\u00a0currentBallYPos,\u00a0BALL_WIDTH,\u00a0BALL_WIDTH);\r\n}\r\n\r\nvoid\u00a0drawRacket(racketSide\u00a0racket)\u00a0{\u00a0\/\/\u00a0zeichnet\u00a0einen\u00a0neuen\u00a0Schl\u00e4ger\r\n\u00a0\u00a0colour(GREEN);\r\n\u00a0\u00a0switch\u00a0(racket)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0case\u00a0LEFT:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.rect(LEFT_RACKET_XPOS,\u00a0currentLeftRacketYPos,\u00a0RACKET_WIDTH,\u00a0RACKET_HEIGHT);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;\r\n\u00a0\u00a0\u00a0\u00a0case\u00a0RIGHT:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0myScreen.rect(RIGHT_RACKET_XPOS,\u00a0currentRightRacketYPos,\u00a0RACKET_WIDTH,\u00a0RACKET_HEIGHT);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;\r\n\u00a0\u00a0}\r\n}\r\n\r\nvoid\u00a0moveRacketsToNewPos(bool\u00a0newField)\u00a0{\u00a0\u00a0\/\/\u00a0zieht\u00a0den\u00a0Schl\u00e4ger\u00a0in\u00a0die\u00a0aktuelle\u00a0Position\r\n\u00a0\u00a0static\u00a0int\u00a0prevLeftYPos\u00a0=\u00a0currentLeftRacketYPos;\r\n\u00a0\u00a0static\u00a0int\u00a0prevRightYPos\u00a0=\u00a0currentRightRacketYPos;\r\n\r\n\u00a0\u00a0if(newField){\r\n\u00a0\u00a0\u00a0\u00a0prevLeftYPos\u00a0=\u00a0currentLeftRacketYPos;\r\n\u00a0\u00a0\u00a0\u00a0prevRightYPos\u00a0=\u00a0currentRightRacketYPos;\r\n\u00a0\u00a0}\r\n\r\n\u00a0\u00a0while\u00a0(prevLeftYPos\u00a0&lt;\u00a0currentLeftRacketYPos)\u00a0{\u00a0\/\/fuege\u00a0Balken\u00a0oben\u00a0zu,\u00a0loesche\u00a0untere\u00a0Balken\r\n\u00a0\u00a0\u00a0\u00a0colour(GREEN);\r\n\u00a0\u00a0\u00a0\u00a0myScreen.line(LEFT_RACKET_XPOS,\u00a0prevLeftYPos\u00a0+\u00a0RACKET_HEIGHT,\u00a0LEFT_RACKET_XPOS\u00a0+\u00a0RACKET_WIDTH\u00a0,\u00a0prevLeftYPos\u00a0+\u00a0RACKET_HEIGHT);\r\n\u00a0\u00a0\u00a0\u00a0colour(BLACK);\r\n\u00a0\u00a0\u00a0\u00a0myScreen.line(LEFT_RACKET_XPOS,\u00a0prevLeftYPos,\u00a0LEFT_RACKET_XPOS\u00a0+\u00a0RACKET_WIDTH\u00a0,\u00a0prevLeftYPos);\r\n\u00a0\u00a0\u00a0\u00a0prevLeftYPos++;\r\n\u00a0\u00a0}\r\n\u00a0\u00a0while\u00a0(currentLeftRacketYPos\u00a0&lt;\u00a0prevLeftYPos)\u00a0{\u00a0\/\/\u00a0andersrum\r\n\u00a0\u00a0\u00a0\u00a0colour(BLACK);\r\n\u00a0\u00a0\u00a0\u00a0myScreen.line(LEFT_RACKET_XPOS,\u00a0prevLeftYPos\u00a0+\u00a0RACKET_HEIGHT,\u00a0LEFT_RACKET_XPOS\u00a0+\u00a0RACKET_WIDTH\u00a0,\u00a0prevLeftYPos\u00a0+\u00a0RACKET_HEIGHT);\r\n\u00a0\u00a0\u00a0\u00a0colour(GREEN);\r\n\u00a0\u00a0\u00a0\u00a0myScreen.line(LEFT_RACKET_XPOS,\u00a0prevLeftYPos,\u00a0LEFT_RACKET_XPOS\u00a0+\u00a0RACKET_WIDTH\u00a0,\u00a0prevLeftYPos);\r\n\u00a0\u00a0\u00a0\u00a0prevLeftYPos--;\r\n\u00a0\u00a0}\r\n\u00a0\u00a0while\u00a0(prevRightYPos\u00a0&lt;\u00a0currentRightRacketYPos)\u00a0{\u00a0\/\/fuege\u00a0Balken\u00a0oben\u00a0zu,\u00a0loesche\u00a0untere\u00a0Balken\r\n\u00a0\u00a0\u00a0\u00a0colour(GREEN);\r\n\u00a0\u00a0\u00a0\u00a0myScreen.line(RIGHT_RACKET_XPOS,\u00a0prevRightYPos\u00a0+\u00a0RACKET_HEIGHT,\u00a0RIGHT_RACKET_XPOS\u00a0+\u00a0RACKET_WIDTH\u00a0,\u00a0prevRightYPos\u00a0+\u00a0RACKET_HEIGHT);\r\n\u00a0\u00a0\u00a0\u00a0colour(BLACK);\r\n\u00a0\u00a0\u00a0\u00a0myScreen.line(RIGHT_RACKET_XPOS,\u00a0prevRightYPos,\u00a0RIGHT_RACKET_XPOS\u00a0+\u00a0RACKET_WIDTH\u00a0,\u00a0prevRightYPos);\r\n\u00a0\u00a0\u00a0\u00a0prevRightYPos++;\r\n\u00a0\u00a0}\r\n\u00a0\u00a0while\u00a0(currentRightRacketYPos\u00a0&lt;\u00a0prevRightYPos)\u00a0{\u00a0\/\/\u00a0andersrum\r\n\u00a0\u00a0\u00a0\u00a0colour(BLACK);\r\n\u00a0\u00a0\u00a0\u00a0myScreen.line(RIGHT_RACKET_XPOS,\u00a0prevRightYPos\u00a0+\u00a0RACKET_HEIGHT,\u00a0RIGHT_RACKET_XPOS\u00a0+\u00a0RACKET_WIDTH\u00a0,\u00a0prevRightYPos\u00a0+\u00a0RACKET_HEIGHT);\r\n\u00a0\u00a0\u00a0\u00a0colour(GREEN);\r\n\u00a0\u00a0\u00a0\u00a0myScreen.line(RIGHT_RACKET_XPOS,\u00a0prevRightYPos,\u00a0RIGHT_RACKET_XPOS\u00a0+\u00a0RACKET_WIDTH\u00a0,\u00a0prevRightYPos);\r\n\u00a0\u00a0\u00a0\u00a0prevRightYPos--;\r\n\u00a0\u00a0}\r\n\u00a0\u00a0colour(GREEN);\r\n}\r\n\r\nvoid\u00a0showScore(){\u00a0\/\/\u00a0zeige\u00a0den\u00a0Spielstand\r\n\u00a0\u00a0char\u00a0buf[3];\r\n\u00a0\u00a0int\u00a0leftScoreXPos;\/\/\u00a0x\u00a0Position\u00a0der\u00a0Punkte\u00a0des\u00a0linken\u00a0Spielers\u00a0\r\n\u00a0\u00a0int\u00a0rightScoreXPos;\r\n\u00a0\u00a0(score[0]&lt;10)?(leftScoreXPos=35):(leftScoreXPos=20);\u00a0\/\/\u00a0Position\u00a0in\u00a0Abhaengigkeit\u00a0ein-\/zweistellig\r\n\u00a0\u00a0(score[1]&lt;10)?(rightScoreXPos=115):(rightScoreXPos=100);\r\n\u00a0\u00a0myScreen.background(0,0,0);\r\n\u00a0\u00a0colour(LIGHTBLUE);\r\n\u00a0\u00a0if(score[0]&lt;WINSCORE\u00a0&amp;&amp;\u00a0score[1]&lt;WINSCORE){\u00a0\/\/wenn\u00a0noch\u00a0kein\u00a0Endstand\u00a0erreicht\u00a0ist\r\n\u00a0\u00a0\u00a0\u00a0itoa(score[0],\u00a0buf,\u00a010);\r\n\u00a0\u00a0\u00a0\u00a0myScreen.text(buf,leftScoreXPos,50);\r\n\u00a0\u00a0\u00a0\u00a0itoa(score[1],\u00a0buf,\u00a010);\r\n\u00a0\u00a0\u00a0\u00a0myScreen.text(buf,rightScoreXPos,50);\r\n\u00a0\u00a0\u00a0\u00a0myScreen.text(\":\",75,50);\r\n\u00a0\u00a0\u00a0\u00a0delay(1500);\r\n\u00a0\u00a0}\r\n\u00a0\u00a0else{\r\n\u00a0\u00a0\u00a0\u00a0if(score[0]==WINSCORE)\u00a0colour(GREEN);\u00a0\/\/\u00a0Endstand\u00a0erreicht\r\n\u00a0\u00a0\u00a0\u00a0else\u00a0colour(RED);\r\n\u00a0\u00a0\u00a0\u00a0itoa(score[0],\u00a0buf,\u00a010);\r\n\u00a0\u00a0\u00a0\u00a0myScreen.text(buf,leftScoreXPos,50);\r\n\u00a0\u00a0\u00a0\u00a0colour(LIGHTBLUE);\r\n\u00a0\u00a0\u00a0\u00a0myScreen.text(\":\",75,50);\r\n\u00a0\u00a0\u00a0\u00a0if(score[1]==WINSCORE)\u00a0colour(GREEN);\r\n\u00a0\u00a0\u00a0\u00a0else\u00a0colour(RED);\r\n\u00a0\u00a0\u00a0\u00a0itoa(score[1],\u00a0buf,\u00a010);\r\n\u00a0\u00a0\u00a0\u00a0myScreen.text(buf,rightScoreXPos,50);\r\n\u00a0\u00a0\u00a0\u00a0while(!gameReset){\/*WAIT*\/}\r\n\u00a0\u00a0}\r\n}\r\n\r\nvoid\u00a0resetField(){\r\n\u00a0\u00a0unsigned\u00a0long\u00a0prevTime\u00a0=\u00a0millis();\r\n\u00a0\u00a0myScreen.background(0,0,0);\r\n\u00a0\u00a0delay(100);\u00a0\u00a0\r\n\u00a0\u00a0colour(GREEN);\u00a0\u00a0\r\n\u00a0\u00a0checkPositions();\r\n\u00a0\u00a0drawRacket(LEFT);\r\n\u00a0\u00a0drawRacket(RIGHT);\r\n\u00a0\u00a0moveRacketsToNewPos(true);\r\n\u00a0\u00a0while((millis()-prevTime)\u00a0&lt;\u00a01000){\u00a0\/\/\u00a0Schlaeger\u00a0sind\u00a0beweglich\u00a0w\u00e4hrend\u00a0auf\u00a0den\u00a0Ball\u00a0gewartet\u00a0wird\r\n\u00a0\u00a0\u00a0\u00a0delay(5);\r\n\u00a0\u00a0\u00a0\u00a0checkPositions();\r\n\u00a0\u00a0\u00a0\u00a0moveRacketsToNewPos(false);\r\n\u00a0\u00a0}\r\n}<\/pre>\r\n<\/div>\n<h4 class=\"wp-block-heading\">The drawBall function<\/h4>\n<p>During the development of the sketch, I spent a lot of time finding a way to move the ball across the screen as smoothly as possible and with minimal &#8220;tail&#8221;. My first approach was the most obvious: you clear the ball at the old position (paint it over black) and redraw it at the new position. It looked really modest. What worked was to expand the ball in the x-direction, then delete the excess pixels and repeat the same in the y-direction.&nbsp;<\/p>\r\n<p>The disadvantage of this method is that it depends on the direction, i.e. you need a separate procedure for each direction. This is what the schematic for the movement DIR_RU, i.e. to the top right:<\/p>\r\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Ball_move_complete.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"254\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Ball_move_complete-1024x254.png\" alt=\"Ball movement in Pong for Arduino using the example DIR_RU\" class=\"wp-image-8146\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Ball_move_complete-1024x254.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Ball_move_complete-300x74.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Ball_move_complete-768x190.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/Ball_move_complete-1320x327.png 1320w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Ball movement to the top right from &#8220;Former Position&#8221; to &#8220;Current Position&#8221;<\/figcaption><\/figure><p>Here&#8217;s what the instructions for each step are:<\/p>\r\n<ol>\r\n<li><code>myScreen.rect(formerBallXPos + 2, formerBallYPos, BALL_WIDTH, BALL_WIDTH);<\/code><\/li>\r\n<li><code>colour(BLACK); myScreen.rect(formerBallXPos, formerBallYPos, 2, 4);<\/code><\/li>\r\n<li><code>colour(GREEN); myScreen.rect(formerBallXPos + 2, formerBallYPos - 1, BALL_WIDTH, BALL_WIDTH);<\/code>&nbsp;<\/li>\r\n<li><code>colour(BLACK); myScreen.line(formerBallXPos + 2, formerBallYPos + 3, formerBallXPos + 6, formerBallYPos + 3);<\/code><\/li>\r\n<\/ol>\r\n<p>So rectangles are simply flanged and cut off. The BALLDELAYS after steps 2 and 4 can be used to control the speed of the game and the appearance of the tail that cannot be completely prevented. Just try it yourself.&nbsp;<\/p>\r\n\n<h4 class=\"wp-block-heading\">The moveRacketsToNewPos function<\/h4>\n<p>In order to make the movement of the racket fluid, the pixels are attached line by line and cut off at the bottom until the racket is in the current position during an upward movement. For the downward movement, the procedure is correspondingly reversed. With the rackets, just like the ball, a simple deletion and drawing from scratch looked quite modest.<\/p>\r\n\n<h3 class=\"wp-block-heading\">The Racket Library  <\/h3>\n<p>Now to the more relevant parts of the Racket library. Essentially, it is about translating the voltage at the potentiometers into the respective y-position of the racket. Here is the class definition from Racket.h:<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-title=\"Racket.h\" data-enlighter-group=\"Racket.h\">class\u00a0Racket{\r\n\u00a0\u00a0public:\r\n\u00a0\u00a0\u00a0\u00a0Racket();\r\n\u00a0\u00a0\u00a0\u00a0Racket(int,\u00a0int);\r\n\u00a0\u00a0\u00a0\u00a0void\u00a0setXPos(int);\r\n\u00a0\u00a0\u00a0\u00a0int\u00a0getXPos();\r\n\u00a0\u00a0\u00a0\u00a0int\u00a0getYPos();\r\n\u00a0\u00a0\u00a0\u00a0void\u00a0move();\r\n\u00a0\u00a0\u00a0\u00a0\r\n\u00a0\u00a0private:\r\n\u00a0\u00a0\u00a0\u00a0int\u00a0xPos;\r\n\u00a0\u00a0\u00a0\u00a0int\u00a0yPos;\r\n\u00a0\u00a0\u00a0\u00a0int\u00a0potiPin;\r\n\u00a0\u00a0\u00a0\u00a0const\u00a0int\u00a0racketHeight\u00a0=\u00a012;\r\n\u00a0\u00a0\u00a0\u00a0const\u00a0int\u00a0topScreenBorder\u00a0=\u00a00;\r\n\u00a0\u00a0\u00a0\u00a0const\u00a0int\u00a0downScreenBorder\u00a0=\u00a0127;\r\n\u00a0\u00a0\u00a0\u00a0const\u00a0int\u00a0minPotiVal\u00a0=\u00a0160;\r\n\u00a0\u00a0\u00a0\u00a0const\u00a0int\u00a0maxPotiVal\u00a0=\u00a0700;\r\n};<\/pre><p>The function in Racket.cpp to determine the y-position is called getYPos:<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-title=\"Funktion getYPos\" data-enlighter-group=\"Funktion getYPos\">int\u00a0Racket::getYPos(){\r\n\u00a0\u00a0int\u00a0yPosRaw;\u00a0\r\n\u00a0\u00a0yPosRaw\u00a0=\u00a0analogRead(potiPin);\r\n\u00a0\u00a0if\u00a0(yPosRaw&lt;minPotiVal)\u00a0yPosRaw\u00a0=\u00a0minPotiVal;\r\n\u00a0\u00a0if\u00a0(yPosRaw&gt;maxPotiVal)\u00a0yPosRaw\u00a0=\u00a0maxPotiVal;\r\n\u00a0\u00a0return(map(yPosRaw,minPotiVal,maxPotiVal,0,downScreenBorder-racketHeight));\u00a0\r\n}<\/pre><p>Not the entire voltage range of the potentiometer is used, as the control must be usable. Above and below maxPotiVal and minPotiVal, the racket stops at the limit.&nbsp;<\/p>\r\n\n<h3 class=\"wp-block-heading\">The Ball library<\/h3>\n<p>The Ball Library is again a bit more complex and needs some explanations. I would like to explain a few functions in more detail.<\/p>\r\n\n<h4 class=\"wp-block-heading\">Function newBall<\/h4>\n<pre class=\"EnlighterJSRAW\" data-enlighter-title=\"newBall Funktion\" data-enlighter-group=\"newBall Funktion\">void\u00a0Ball::newBall(){\r\n\u00a0\u00a0int\u00a0randomNumber;\r\n\u00a0\u00a0randomNumber\u00a0=\u00a0random(0,999);\r\n\u00a0\u00a0yPos\u00a0=\u00a06\u00a0+(random((downScreenBorder-6)\/2))*2;\r\n\u00a0\u00a0if(flightDir==NEW_BALL)\u00a0(((random(0,999))%2)==0)?(flightDir\u00a0=\u00a0DIR_LU):(flightDir\u00a0=\u00a0DIR_RD);\r\n\u00a0\u00a0if((flightDir==DIR_LD)\u00a0||\u00a0(flightDir==DIR_LU)){\r\n\u00a0\u00a0\u00a0\u00a0(((randomNumber)%2)==0)?(flightDir\u00a0=\u00a0DIR_RU):(flightDir\u00a0=\u00a0DIR_RD);\r\n\u00a0\u00a0\u00a0\u00a0xPos=leftScreenBorder; \r\n\u00a0\u00a0}\r\n\u00a0\u00a0else\u00a0if((flightDir==DIR_RD)\u00a0||\u00a0(flightDir==DIR_RU)){\r\n\u00a0\u00a0\u00a0\u00a0(((randomNumber)%2)==0)?(flightDir\u00a0=\u00a0DIR_LU):(flightDir\u00a0=\u00a0DIR_LD);\r\n\u00a0\u00a0\u00a0\u00a0xPos=rightScreenBorder; \r\n\u00a0\u00a0}\r\n}<\/pre><p>If a new ball comes into play at the beginning of the game, then it has no direction (NEW_BALL). It then gets the direction DIR_LU or DIR_RD by random generator. If there is no start to the game, then the ball has already got a direction and one side has just made a point. The direction should then change (start for the player who did not get the last point). The second if construct also ensures that not only DIR_LU or DIR_RD is set as direction at the start of the game, which is the result of the first if construct.&nbsp;<\/p>\r\n\n<h4 class=\"wp-block-heading\">Functions fenceCheck and goalCheck<\/h4>\n<pre class=\"EnlighterJSRAW\" data-enlighter-title=\"Functions fenceCheck and goalCheck\" data-enlighter-group=\"Functions fenceCheck and goalCheck\">void\u00a0Ball::fenceCheck(){\r\n\u00a0\u00a0if(yPos==0){\r\n\u00a0\u00a0\u00a0\u00a0if(flightDir==DIR_LU)\u00a0flightDir\u00a0=\u00a0DIR_LD;\r\n\u00a0\u00a0\u00a0\u00a0else\u00a0if(flightDir==DIR_RU)\u00a0flightDir\u00a0=\u00a0DIR_RD;\r\n\u00a0\u00a0}\r\n\u00a0\u00a0else\u00a0if(yPos==124){\r\n\u00a0\u00a0\u00a0\u00a0if(flightDir==DIR_LD)\u00a0flightDir\u00a0=\u00a0DIR_LU;\r\n\u00a0\u00a0\u00a0\u00a0else\u00a0if(flightDir==DIR_RD)\u00a0flightDir\u00a0=\u00a0DIR_RU;\r\n\u00a0\u00a0}\r\n}\r\n\r\nbool\u00a0Ball::goalCheck(){\r\n\u00a0\u00a0if((xPos==leftScreenBorder)&amp;&amp;((flightDir==DIR_LD)||(flightDir==DIR_LU)))\u00a0return\u00a0true;\r\n\u00a0\u00a0else\u00a0if\u00a0((xPos==rightScreenBorder)&amp;&amp;((flightDir==DIR_RU)||(flightDir==DIR_RD)))\u00a0return\u00a0true;\r\n\u00a0\u00a0else\u00a0return\u00a0false;<\/pre><p>These functions are relatively simple. The fenceCheck function checks whether the ball has hit the top or bottom boarder. In this case, the direction must be changed accordingly. Note the extent of the ball and the position of its reference pixel at the top left. At the top, the ball hits directly with its reference point, i.e. at y = 0. At the bottom, the ball hits at y = 124 &nbsp; and not at 127. At first I thought that would happen at 127 &#8211; ball edge length, so at 123. Mistake in thinking!<\/p>\r\n<p>The function goalCheck checks whether the goal line has been crossed. In contrast to the fenceCheck, the line should actually be crossed. The ball crosses halfway the line and then disappears completely. Therefore, in Ball.h leftScreenBorder is defined as -2 and rightScreenBorder as 158.&nbsp;<\/p>\r\n\n<h4 class=\"wp-block-heading\">Function racketHitCheck<\/h4>\n<pre class=\"EnlighterJSRAW\" data-enlighter-title=\"Function racketHitCheck\" data-enlighter-group=\"Function racketHitCheck\">void\u00a0Ball::racketHitCheck(const\u00a0int\u00a0&amp;left_xp,\u00a0int\u00a0&amp;left_yp,\u00a0const\u00a0int\u00a0&amp;right_xp,\u00a0int\u00a0&amp;right_yp,\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const\u00a0int\u00a0&amp;ball_width,\u00a0const\u00a0int\u00a0&amp;height,\u00a0const\u00a0int\u00a0&amp;width){\r\n\u00a0\u00a0if((xPos==(left_xp\u00a0+\u00a0width))\u00a0&amp;&amp;\u00a0(yPos&gt;=(left_yp-ball_width))\u00a0&amp;&amp;\u00a0(yPos&lt;=(left_yp+height))){\r\n\u00a0\u00a0\u00a0\u00a0if(flightDir==DIR_LU)\u00a0flightDir\u00a0=\u00a0DIR_RU;\r\n\u00a0\u00a0\u00a0\u00a0else\u00a0if(flightDir==DIR_LD)\u00a0flightDir\u00a0=\u00a0DIR_RD;\r\n\u00a0\u00a0} \r\n\u00a0\u00a0else\u00a0if(xPos==(right_xp-ball_width)\u00a0&amp;&amp;\u00a0(yPos&gt;=(right_yp-ball_width))\u00a0&amp;&amp;\u00a0(yPos&lt;=(right_yp+height))){\r\n\u00a0\u00a0\u00a0\u00a0if(flightDir==DIR_RU)\u00a0flightDir\u00a0=\u00a0DIR_LU;\r\n\u00a0\u00a0\u00a0\u00a0else\u00a0if(flightDir==DIR_RD)\u00a0flightDir\u00a0=\u00a0DIR_LD;\r\n\u00a0\u00a0}\r\n}<\/pre><p>The racketHitCheck function checks whether a racket has been hit. The current position of the racket must be passed to the racketHitCheck function and the dimensions of the racket and the ball must be taken into account. In addition, the racket should only be active into the direction of the playing field. When a new ball comes into play and hits the racket from the other side, it shall be ignored. However, in this case he tears a hole in the racket, which is &#8220;healed&#8221; again when the racket moves. Shuting down this behaviour was simply too cumbersome for me.&nbsp;<\/p>\r\n\n<h2 class=\"wp-block-heading\">Final words<\/h2>\n<p>As you may have seen, the programming of Pong for Arduino is a bit more complex than you might imagine at first. At least for me as a hobby programmer this was quite challenging. Originally, I had the idea to program the whole thing in a way that you can also use other screen sizes or easily switch between tennis and a one-player squash mode. Perhaps others may continue to do so.<\/p>\r\n<p>I also realize that one or the other place is not completely &#8220;clean&#8221; programmed although it works. Nevertheless, I hope that it is a useful and above all fun suggestion for you. I welcome any feedback!<\/p>\r\n","protected":false},"excerpt":{"rendered":"<p>A simple version of Pong, realized with an Arduino for a 1.8 inch display. Hardware and Sketch are described in detail. <\/p>\n","protected":false},"author":1,"featured_media":8144,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[571],"tags":[775,779,778],"class_list":["post-9355","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-projects","tag-pong-en","tag-pong-for-arduino-en","tag-teletennis-en-2"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Pong for Arduino - computer table tennis &#8226; Wolles Elektronikkiste<\/title>\n<meta name=\"description\" content=\"A simple version of Pong, using an Arduino and a 1.8 inch display. Hardware and Sketch are described in detail.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Pong for Arduino - computer table tennis &#8226; Wolles Elektronikkiste\" \/>\n<meta property=\"og:description\" content=\"A simple version of Pong, using an Arduino and a 1.8 inch display. Hardware and Sketch are described in detail.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis\" \/>\n<meta property=\"og:site_name\" content=\"Wolles Elektronikkiste\" \/>\n<meta property=\"article:published_time\" content=\"2020-11-02T22:44:12+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-11-29T12:15:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/pong_pixabay_source.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"960\" \/>\n\t<meta property=\"og:image:height\" content=\"960\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Wolfgang Ewald\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Wolfgang Ewald\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/pong-for-arduino-computer-table-tennis#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/pong-for-arduino-computer-table-tennis\"},\"author\":{\"name\":\"Wolfgang Ewald\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"headline\":\"Pong for Arduino &#8211; computer table tennis\",\"datePublished\":\"2020-11-02T22:44:12+00:00\",\"dateModified\":\"2020-11-29T12:15:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/pong-for-arduino-computer-table-tennis\"},\"wordCount\":1845,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/pong-for-arduino-computer-table-tennis#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/07\\\/pong_pixabay_source.jpg\",\"keywords\":[\"Pong\",\"Pong for Arduino\",\"Teletennis\"],\"articleSection\":[\"Projects\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/pong-for-arduino-computer-table-tennis#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/pong-for-arduino-computer-table-tennis\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/pong-for-arduino-computer-table-tennis\",\"name\":\"Pong for Arduino - computer table tennis &#8226; Wolles Elektronikkiste\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/pong-for-arduino-computer-table-tennis#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/pong-for-arduino-computer-table-tennis#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/07\\\/pong_pixabay_source.jpg\",\"datePublished\":\"2020-11-02T22:44:12+00:00\",\"dateModified\":\"2020-11-29T12:15:00+00:00\",\"description\":\"A simple version of Pong, using an Arduino and a 1.8 inch display. Hardware and Sketch are described in detail.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/pong-for-arduino-computer-table-tennis#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/pong-for-arduino-computer-table-tennis\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/pong-for-arduino-computer-table-tennis#primaryimage\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/07\\\/pong_pixabay_source.jpg\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/07\\\/pong_pixabay_source.jpg\",\"width\":960,\"height\":960},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/pong-for-arduino-computer-table-tennis#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Pong for Arduino &#8211; computer table tennis\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\",\"name\":\"Wolles Elektronikkiste\",\"description\":\"Die wunderbare Welt der Elektronik\",\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\",\"name\":\"Wolfgang Ewald\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"width\":512,\"height\":512,\"caption\":\"Wolfgang Ewald\"},\"logo\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Pong for Arduino - computer table tennis &#8226; Wolles Elektronikkiste","description":"A simple version of Pong, using an Arduino and a 1.8 inch display. Hardware and Sketch are described in detail.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis","og_locale":"en_US","og_type":"article","og_title":"Pong for Arduino - computer table tennis &#8226; Wolles Elektronikkiste","og_description":"A simple version of Pong, using an Arduino and a 1.8 inch display. Hardware and Sketch are described in detail.","og_url":"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis","og_site_name":"Wolles Elektronikkiste","article_published_time":"2020-11-02T22:44:12+00:00","article_modified_time":"2020-11-29T12:15:00+00:00","og_image":[{"width":960,"height":960,"url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/pong_pixabay_source.jpg","type":"image\/jpeg"}],"author":"Wolfgang Ewald","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Wolfgang Ewald","Est. reading time":"17 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis#article","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis"},"author":{"name":"Wolfgang Ewald","@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"headline":"Pong for Arduino &#8211; computer table tennis","datePublished":"2020-11-02T22:44:12+00:00","dateModified":"2020-11-29T12:15:00+00:00","mainEntityOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis"},"wordCount":1845,"commentCount":0,"publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/pong_pixabay_source.jpg","keywords":["Pong","Pong for Arduino","Teletennis"],"articleSection":["Projects"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis","url":"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis","name":"Pong for Arduino - computer table tennis &#8226; Wolles Elektronikkiste","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#website"},"primaryImageOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis#primaryimage"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/pong_pixabay_source.jpg","datePublished":"2020-11-02T22:44:12+00:00","dateModified":"2020-11-29T12:15:00+00:00","description":"A simple version of Pong, using an Arduino and a 1.8 inch display. Hardware and Sketch are described in detail.","breadcrumb":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis#primaryimage","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/pong_pixabay_source.jpg","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/07\/pong_pixabay_source.jpg","width":960,"height":960},{"@type":"BreadcrumbList","@id":"https:\/\/wolles-elektronikkiste.de\/en\/pong-for-arduino-computer-table-tennis#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/wolles-elektronikkiste.de\/en"},{"@type":"ListItem","position":2,"name":"Pong for Arduino &#8211; computer table tennis"}]},{"@type":"WebSite","@id":"https:\/\/wolles-elektronikkiste.de\/en#website","url":"https:\/\/wolles-elektronikkiste.de\/en","name":"Wolles Elektronikkiste","description":"Die wunderbare Welt der Elektronik","publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wolles-elektronikkiste.de\/en?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46","name":"Wolfgang Ewald","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","width":512,"height":512,"caption":"Wolfgang Ewald"},"logo":{"@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png"}}]}},"_links":{"self":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/9355","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/comments?post=9355"}],"version-history":[{"count":0,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/9355\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media\/8144"}],"wp:attachment":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media?parent=9355"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/categories?post=9355"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/tags?post=9355"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}