datagod's Feed

datagod
08-25-2019 at 10:52 AM
10 Comments
Rate this Entry

Raspberry Pi: distributed graphics project

I post a lot about Raspberry Pi's, and give little glimpses into what I am doing. This time, I am going to use my blog here at Twin Galaxies as a running commentary on my next project, and to allow me to document my thoughts as I go along.

Synchronized Multi Unit Graphics Displays A fancy way of saying I want 2+ Raspberry Pi's to be able to co-ordinate their LCD displays. My first project will be to get 2 8x8 LCD's co-ordinating their graphics

. One of the games I build for my Arcade Retro Clock is called Outbreak. It is inspired by the game of life, but I put a spin on things. The little virises move around and consume food that they find. They have a small chance of mutating, and when they touch other viruses they will battle it out. The winning virus takes over the other, changing their color and current state of mutation.

That is a lot of action to convey on an 8x8 scree, but I pull it off by having the action take place in a world of 6 screens. The camera scrolls from room to room, following the action. What I want to do now is have 2 computers working together, and display two different rooms simultaneously.

My first thought was to have the game running on both machines, and have them co-ordinate the world object which contains all the game objects. After thinking about how to achieve that, I believe it is a bit too complicated to have them co-ordinate like that. What I am going to do now is have a master computer that calculates the game, and have 2 or more computers receive a data packet on what to display.

The LCD hardware can refresh at 60 frames per second. I am hoping that by using TCP connections I can pass a 8x8 array of integers to each display quickly enough that the viewer will still be pleased with the result. The central computer will run the game and then run a function to determine what each screen should be displaying. That information will be sent to the other machines which will in turn simply refresh the display with the new information.

The central computer will have a display as well. Thankfully the API I am using already has capture screen buffer and display screen buffer functions. I modify the buffer before displaying already in my own functions. I am very pumped about this!

Comments
  1. Riatoju's Avatar

    I found a forum a while back where folks where developing their own operating systems for these. Coding down to the metal is what they called it. It reminds me of another forum I ran into where they were building their own 6802 computers. Either of those things I would have loved to do, unfortunately I got to pick and choose my battles. I already lost alot of my life to trying to design a game and social network with very little success. I tend to bite off more than I can chew.

    However, after the 2600, I been toying with the thought of basing a project around the Apple II, or quite possibly the Macintosh (System 7). I also wouldn't mind developing for A classic Mac with the last version of A/UX (Apple's version of UNIX) that was designed for the 680x0 models. If I had more time, I would probably target those two, and eventually build upon it and create a successor. It would be a universal computer with a closed environment, designed specifically for particular purposes, such as a gaming console or whatever. Everything would work right out of the box, you'd never have to worry about newer libraries making old ones obsolete or the update hell windows users have to deal with. It would be sorta like your computer emulators, or virtaulized environments. The benefit would be nothing you make for it would ever go obsolete, it would always work.


    There's a man who built his own OS, Temple OS, the guy is crazy, but his idea isn't too bad. It's hard to describe but man would that be fun.

    Yeah when I was a kid, I had a big fascination for operating systems, I wanted to design my own. I had alot of ideas on how to make a better one.

    Thanksdatagod thanked this post
    Likesdatagod liked this post
  2. datagod's Avatar

    I read about Temple OS, very cool. Don't every think of a programming project as a waste. The goal is the journey, not the destination.

    It is like practicing for a marathon. It is exercising the brain. You get more powerful the more you do it. Our minds will be far younger than those around us who get off on lottery tickets and shows like Dancing with the Stars.

    I hate the formatting on this site. Gotta go back and fix my post.

    LikesRiatoju liked this post
  3. datagod's Avatar


    After doing a big of research, and fooling around a bit, I have decided to send data using UDP as opposed to TCP.

    User Datagram Protocol

    UDP (User Datagram Protocol) is an alternative communications protocol to Transmission Control Protocol (TCP) used primarily for establishing low-latency and loss-tolerating connections between applications on the internet.

    Bothh UDP and TCP run on top of the Internet Protocol (IP) and are sometimes referred to as UDP/IP or TCP/IP. But there are important differences between the two.

    Where UDP enables process-to-process communication, TCP supports host-to-host communication. TCP sends individual packets and is considered a reliable transport medium; UDP sends messages, called datagrams, and is considered a best-effort mode of communications.


    For displaying images on a screen, I don't care if I lose a few frames here and there. I need speed over accuracy.


  4. datagod's Avatar

    After a few hours of tinkering I got the sockets working between two Raspberry Pi computers.

    What is confusing is that I am using a Master/Slave paradigm, but sockets uses CLIENT/SERVER which is not quite the same. My master clock will send packets to several slave displays, but in the socket world. each slave clock is running as a server and a client is sending it information. Usually you have multiple clients and one server. I have multiple servers and one client (the master clock).

    Whatevs.


    This is the python code for the MASTER which will be sending display data to the SLAVE.



    And here is the code that runs on the SLAVE display listening for incoming packets.


    What tripped me up was that I did not have the SlaveHost IP address set properly on the SLAVE. It needs to be localhost / 0.0.0.0 I had the IP of the Master, which in hindsight was silly.


  5. datagod's Avatar

    Oh, I am very happy to report that on my little network I was able to send about 3000 packets a second. WAY faster than I was hoping for. I am very confident that my displays will be synchronized and give a great experience.

    Imagine a game of pong being played on a wall of LCD screens a couple of feet apart.

    Man I can't wait! This datagod has to get some sleep though. My real job starts in 6 hours!!

  6. datagod's Avatar



    After a few hours of hard core head scratching and googling, I got everything working! Here you see two raspberry pi computers, the one on the left is a 3 that is running the Arcade Retro Clock. The one of the left is a mediocre powered A, which is connected to the network via wireless dongle.

    The left display is the master, and it displays a moving camera view of a little collection of virises zooming around a playfield. It also sends a 256 byte packet over a network socket to the A which is the remote display. The remote display is only showing what is happening in a particular 8x8 region of the map, while the main display shows where the main focus of the game is.

    This is beta version.

    I need to work on performance now, as the network gets a bit laggy.

    I am using TCP, but I want to use UDP, because it is much leaner and I don't need to display every single frame. If packets are not read in time, to bad baby. The game must go on.

    LikesRiatoju liked this post
  7. datagod's Avatar

    I finally figured out how to use UDP (User Datagram Protocol). It is far faster than TCP and does not need to wait for any acknowledgements. A firehose of display strings are sent to the slave display, and it keeps up as best as it can. The sending program doesn't wait for a response, it just keeps on going.




    Here is the function I use to read an 8x8 grid from the playfield, then converts the RGB values found into a comma delimited string. That string is trimmed of a trailing comma, then sent to the slave display over the network.

    The grid itself is populated with game objects, and only some of them have rgb attributes. That is why I have to use the "hasattr" function to see if the attribute r is there. If r is there, so is g and b (hopefully!)

  8. datagod's Avatar

    Allow me to say once again that other than syntax examples, the concepts I am using in this project are all from my own ideas. There are likely way better ways to implement, but part of the joy of this project is to come up with solutions to the various challenges all on my own.

    Animated sprites, game worlds with live objects, and now support for multiple displays.

    My IQ just got 2 points higher today. :)

  9. datagod's Avatar

    Huge Performance Gains

    if (PacketString <> self.PreviousPacketString):
    #print ("Display: ",self.name,"No change detected")
    self.DisplaySocket.sendto(PacketString,self.Server Address)
    self.PreviousPacketString = PacketString

    As I was falling asleep last night, I thought "what if the image on the screen to be displayed has not changed? Why send a network packet at all?"

    I added a simple check to the display function. Because this function is in the class, all games make use of it now (currently two supported).

    I saw a HUGE performance gain, 500% roughly.


  10. datagod's Avatar



    I hooked a third screen up tonight no problem at all. all I had to do what's initialize it as a object plug-in and IP address and port number and I just work. didn't seem to slow down the main computer at all. now the little world I'm playing with here is three screens wide so it works perfectly doesn't have to scroll anymore. it will scroll up and down because it's actually two worlds I mean two screens high.
    I'm using text-to-speech here so pardon my odd spelling mistakes.


    the third Raspberry Pi is powered by a Raspberry Pi zero w. so that is about $10 computer and has built in Wi-Fi Bluetooth. it runs at 1 gigahertz. it has 450 megabytes of RAM. it's actually faster than the Raspberry Pi a that I have been using as the first or I mean the second monitor I have more eggs than any other computer because they're very sturdy and they give me lots of power. I was surprised to find out that the zeros actually run faster. they take less power than run faster doing problem is you need adapters to plug into the USB ports cuz they're all micro USB ports even the HDMI port is is mini so you need adapters all over the place. But it's a nice trade-off. I mean come on $10 for a computer.
    I have such an assortment of parts lying around I'm going to be able to have a 6-unit display soon. this is great. my next upgrade will be to have them wired into their own dedicated Network. maybe not wired probably wireless. But this works right now. That's reading
Join us