12 Replies Latest reply on Apr 13, 2020 10:39 AM by celcius1

    My Retropie Portable Build

    celcius1

      Hey Guys,

       

      I've decided to discuss my Retropie Handheld build, I would love feedback if it is constructive, now I had a 7" RPi touchscreen lying around, and decided to build it into a Retropie portable, now power requirements, had to be considered, now Powerboost chargers from adafruit wont cut it with the current feed needed for the RPi 3B+, so for the Power source, I'm using 4 LiPo cells, with a capacity of 4000mAh, wired as two packs, so i have two packs with an output voltage of 7.2v and then in parallel so I have a battery capacity of 8000mAh.  I also cant use Adafruit stuff as there are no local stockists of the modules here in Adelaide.

       

      But with the charging circuit I've modified one I found for charging 4 cells that uses an ATMega328P, the changes I'm making is for charging 2 cells even though I'm using 4, I am assuming I can treat the two packs of two cells as two cells to the circuit.  The other change is to add a means to switch from battery power to PSU when it is plugged in for charging. and load share between the pi and battery, the power from the PSU or battery then goes into a Buck Converter, (https://www.altronics.com.au/p/z6334-dc-dc-buck-module-3-40v-input/), so I can give the Pi and screen upto 2.5A at 5v.  Also I'll be adding a means to the battery charging circuit if a low battery condition is detected, so that it can signal the RPi to shutdown if the voltage drops below a set threshold.

       

      Now the reason for building my own charging interface is because here in Australia we don't have much in the way of standard modules, even ones with the power requirements of the RPi 3B+, plus I prefer a bigger handheld screen.

       

      This is the reference I am using for building my own version of the charging circuit https://www.microfarad.de/li-charger/ this site is quite informative, and will help in customising this circuit for my requirements.

       

      For the buttons I am going to use a basic key matrix, and take a page from the TBHS project where they did this, as its a good proven method of input.

       

      The batteries I am using https://www.altronics.com.au/p/s4761-26650-lithium-ion-3.6V-4000mah-rechargeable-battery/

      Controller I am using for charging https://www.altronics.com.au/p/z6222-sparkfun-dev-11113-pro-mini-328-5v-16mhz/

      Plugpack for External power and Charging https://www.altronics.com.au/p/m8936b-powertran-12v-dc-2a-fixed-2.1mm-tip-appliance-plugpack/

       

      I value constructive feedback of my project.

       

      I also forgot to add, once I get the handheld working, I'm going to look at expanding it so I can plug 2600 cartridges directly into it, as I have been working on a 2600 cartridge interface. running into a few hurdles, so focusing on something a little easier

       

      Regards

       

      Paul

       

      P.S. I'm umming and rring about actually recording this on video and doing a video of project.

        • Re: My Retropie Portable Build
          celcius1

          After speaking with my battery supplier, I've decided to go with 18650 Li-Ion cells, with 3 cells per bank, giving a battery voltage of 10.8V and battery life of approx 7hrs. as when the handheld is on battery it will draw approx 1.5amps per hour at a max draw of 2.5Amps at 5V, but this design change has meant that I'll have to change PSU type to a 15V PSU this is good as it provides a total of 2.4Amps which means if the unit was at max power draw, just under 1A will be draw by the Pi whilst on PSU and the remaining 1.4Amps are utilised for charging, and when the Pi is off the charging circuit will use the entire current range to charge the battery faster but I will implement a current sensing on the build so the charging circuit will draw the maximum current possible when available and in use.

           

          PSU I am now going with https://www.altronics.com.au/p/m89345-powertran-15v-dc-2.4a-2.1mm-fixed-tip-positive-appliance-plugpack/

           

          on top of this the battery technician I spoke to told me to focus on the battery conditioning part of the circuit too, to maximise cell life.

           

          Another design consideration, is i'll connect the UART from the arduino to the RPi so I can monitor the battery condition but also have a path to update the firmware on the charge controller easily.  For now I'll use it as a firmware update path, and use a digital output on the arduino to the GPIO to trigger a safe shutdown when the battery voltage reads as a low battery.

          • Re: My Retropie Portable Build
            celcius1

            It's been awhile since working on this, I've made a few changes since I originally started.

             

            Change 1 I'm using a different 7inch screen, that is driven by a HDMI and usb for power and Touch https://www.altronics.com.au/p/z6514-7-inches-lcd-touchscreen-800x480-for-raspberry-pi/

            Change 2 I've switched to a RPi Zero, its taking up room in my drawer bought it over a year ago , and have yet to use it, so decided on using it in my retro pie portable.

             

            For my button input, I'm using a button matrix designed using the 74HC595 shift register which will allow me to use 4 GPIO to read a number of buttons, thanks to the 595's ability to stack an extra 8 bit shift register and add more input.  I'm going to use 4 shift registers to give me up to 32 button inputs, but the problem I have is trying to assign the key matrix, I was thinking of writing a *.c file like this https://github.com/annem/ADXL362_RaspPi/blob/master/ADXL362_RaspPi.c obviously mine will be spec'd for the shift registers.  But how would I go about building this into a keyboard driver, so I can use a key matrix assignment that Ben heck used on the retro pie build he did in episode 322 and 328.  I'm still relatively new to writing low level code on the RPi but I'd appreciate the help if it comes.

             

            Now the reason why I choose to go with 32 inputs, on my key input device on my hand held I'll only connect approx 12 to 16 inputs, I'm also building a desktop Retro Pie and wanted to make sure I could have the one driver for doing both single and two player control connections.

             

            So the way I have designed the button matrix is as follows, a single bit is loaded on to the shift register, and then is shifted through the entire 32 outputs, each of the outputs is connected to the MOSI line of the SPI bus, if a button is pressed, a logic 1 is sent to the input on the bus at that specific position.  So multiple buttons can be registered, so when the button matrix is read into the pi it is a 32bit number.

             

            Then all I need to do is figure out how to analyse the number most likely via a lookup table or something to confirm which button is pressed, I assume this data analysis is done within the driver.

             

            But I need to try and work out an appropriate polling period, as I'm looking to use a SPI clock of 6.25Mhz which would give me a clock pulse of interval of 160ns, so no where near the lower limit of 25ns for the clock input to register valid data (lowest limit is 20ns want to have a buffer).  But what would be an appropriate poll time, 1 millisecond?  I'd appreciate input on this.  If my math is correct, with a clock pulse of 160ns, and approximately 36 clock cycles to read the input states, that means I need  6 microseconds to read the data in, then I have to decide on a wait period and do another read.

             

            As a friend of mine told me polling is better and easier to debug, versus using an interrupt.  And also cause my method of input is similar to a NES controller, they used a polling method to read the shift register data, so that appears to be the best method to read the button states.

             

            I'll post a partial schematic of the button matrix in due course.

            • Re: My Retropie Portable Build
              celcius1

              Also with the battery component,  I've done more research, and are working on integrating a battery balancing system in the charging circuit, and have decided to go with a 18v battery pack as when I did further math the figures looked better to have a 14v pack over a 7v pack as the buck converter would run at a much higher efficiency rate, and get better run time from the batteries, but it is much easier with the charger design, and the battery balancing system will be easier to manage.  I just need to ensure I can drop up to 1amp per cell when the balancing circuit kicks in.

              • Re: My Retropie Portable Build
                shabaz

                Hi Paul,

                 

                Connecting parallel/series batteries can be high-risk, you've not mentioned if the latest battery pack is self-assembled. The original one you mentioned was not (the one that was going to be 4 x 18650 cells in parallel and series, and it stores a huge amount of energy).

                A far safer method, and lower-energy (the display and Pi combined consume about 1A at 5V, so 4 x 4AH LiPo cells is excessive) is to use a ready-made smaller battery pack. You'll get >90% efficiency with a two-cell LiPo and DC-DC conversion to 5V, no need for an 18V pack, if everything is running at 5V.

                  • Re: My Retropie Portable Build
                    celcius1

                    Hi Shabaz,

                     

                    The battery packs are being professionally made of 4 cells each behind each hand hold, total of 8 cells, at 14.8v, they will have to sets of wires on it one for pack connection and the other for BMS connection, the reason I am keeping the pack at a high size, is that eventually I'll want to use it to run a 7 inch screen with a RPi 4, as I'm designing this into a single PCB to suit all RPi's, I'm trying to create a single PCB solution depending on the hardware used.  But I am getting the packs custom made, but they do require connection to a BMS.

                  • Re: My Retropie Portable Build
                    celcius1

                    So I have got most the schematic drawn up for the button matrix, I still have a number of items to put on the schematic most importantly a logic level shifter as the shift registers are logic level 5v devices along with the inverter.

                     

                    But a description of the circuit function.

                     

                    The matrix is polled approx every 1 to 5 milliseconds, With the SPI bus set to run on a 6.25MHz clock,  The SPI input is expecting a 32bit binary value, these 32 bits represent the buttons.

                     

                    Once a read starts chip enable 0 is activated turning on the shift registers, firstly a single bit is loaded into the shift register, then Chip enable 1 is activated, to connect the register clock to the SPI clock to start clocking through the buttons.

                     

                    As the clock cycles through the button matrix, the inverter facilitates the output of the data on the shift registers output lines on the falling edge of the clock, as the clock cycles the data through the registers if a button is pressed it sends a logic 1 to the SPI bus, to indicate a button that has been pressed, once a cycle is complete, this 32 bit value can be analysed to see which buttons have been pressed

                     

                    once this is in memory it can then be analysed to see which buttons have been pressed by means of a lookup table.

                     

                    The reason for a 6.25MHz clock is the speed of the chips being used, the shift registers cant operate much faster, but in saying that I could easily use a slower clock as at 6.25MHz clock I can do a full matrix read in approx 6 to 7 microseconds

                     

                    I would like some feedback to know if this design is sound, and then I'll have to spend time working out the code on how to read the matrix, and how to assign the lookup table

                    Key Matrix Schematic

                      • Re: My Retropie Portable Build
                        shabaz

                        Hi Paul,

                        There are other ways to design keyboard circuits that reduce the need for so many parts, you've got 37 parts here not including the buttons. These can be reduced to 2 parts, like two MCP23017 chips, and they are available in through-hole and surface-mount versions.

                         

                        I've not tried it for a games system, so you'd have to experiment to rule it in or out, but I think if you software-enable pull-ups and configure the MCP chips to be all inputs, then you can configure it to signal via interrupt when any switch input changes. No need to do so much scanning basically.

                         

                        Anyway, regardless of what you go with, it is best to prototype a bit of this (e.g. on a breadboard) before creating a PCB, i.e. by PCB creation stage there should be near-100% confidence that worst-case nothing other than one or two 'bodge' wires may be necessary to get the prototype working. Not all of it needs to be prototyped, but at least some buttons and a few of the chips.

                        Each chip should have a 100nF capacitor across the supply rails, as close to the chip as possible, this may also be indicated in the datasheets for the ICs. Also, the Pi is a 3.3V logic device, it's a bit dangerous to run the circuit shown above from 5V. Although it could be level-converted, it is better to power off the 3.3V rail provided you don't draw too much current (which a keyboard driver circuit shouldn't anyway). Also, for U5, 74LS366, the 74HC would be used instead (LS isn't suitable for 3.3V operation).

                        2 of 2 people found this helpful
                          • Re: My Retropie Portable Build
                            celcius1

                            Hi Shabaz,

                             

                            Thanks for the suggestion I'll make a change to my schematic, I'm reading up on the chip now, trying to find the SPI commands, as I've started coding the source file to read the button states, but you know of anyone with programming experience that might be able to help me ensure my code is correct, and enable it is a pre-configured key mapping?

                             

                            Attached is the code I have worked out so far, still needs work be aware its currently written for my current schematic

                             

                            I read up on the chip, It’s a lot more difficult to program SPI commands have way too much overhead, but another option I have is it use a 74HC166 which is a proper input chip, but the reasoning behind my design is the ability to source parts, not easy to do here in Australia

                             

                            Regards

                            Paul

                            #include <bcm2835.h>
                            #include <stdio.h>
                            
                            int main(int argc, char **argv)
                            {
                                
                                if (!bcm2835_init())
                                    return 1;
                                    
                                const int start_poll = 0x01;                                  // Initial Byte sent to Shift Register to do button read by setting Qa in the shift register to logic high
                                char button_state[]= {0x00, 0x00, 0x00, 0x00];                  // 32 bit 4 byte array to store the button states
                                
                                    
                                bcm2835_spi_begin();
                                bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);      // Set Byte Transfer Read Order
                                bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);                   // Default Transfer Mode
                                bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_64);    // Clock set to RPi 2 to 3.90625MHz or on RPi 3 to 6.25 MHz
                                
                                    
                                bcm2835_spi_chipSelect(BCM2835_SPI_CS0);                      // Enable Shift Registers Only
                                bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);      // Set Shift Register Enable Polarity to Active Low
                                bcm2835_spi_transfer(start_poll);                              // Set First Shift Register Qa Output to Logic High
                                bcm2835_spi_chipSelect(BCM2835_SPI_CS1);                      // Select All devices and Register Clock 
                                bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS1, LOW);      // Set Chip Enable Polarity to Active Low
                                bcm2835_spi_transfern(button_state, sizeof(button_state));    // Read the button Status
                                
                                
                                bcm2835_spi_end();
                                return 0;
                            }
                            
                              • Re: My Retropie Portable Build
                                shabaz

                                Hi Paul,

                                 

                                I've not coded using the library you're using or for this device, so cannot help much here.

                                It may be instead worthwhile using a GPIO library (such as wiringPi or some other one, I don't know what's recommended these days for Pi), otherwise you'll need to modify and retest bits of code if you change Pi variant.

                                Another suggestion is using a logic analyzer (some are low-cost, search for 'salae logic' for instance) when coding for hardware like this.

                                  • Re: My Retropie Portable Build
                                    celcius1

                                    Hi Shabaz,

                                     

                                    I Redesigned my Key Matrix, and re wrote my code.  I'm using 74HC165 now, which are proper input shift registers or PISO registers, don't need to use protection diodes on the pins, and the IC's are 3.3v logic level.

                                     

                                    New Key Matrix

                                    Now below is my code to communicate with the shift registers using wiringPi, but what concerns me it does not tell me if the Chip Select is in Active Low or Active High mode, when it accesses the SPI bus.  I can always test this when my chips arrive had to buy a tube of 50 of them from RS Components and got some breakout boards so I can easily breadboard the IC's as they are an SOIC package.  But if WiringPi cant use the SPI bus correctly, cause of the simple nature of the shift registers I could manually shift the data in but this is alot of coding work to do this, and I prefer not to go down this path.

                                     

                                    #include <wiringPi.h>
                                    #include <wiringPiSPI.h>
                                    #include <stdio.h>
                                    
                                    int main(void)
                                    {
                                        
                                        char button_state[]= {0x00, 0x00, 0x00, 0x00];                  // 32 bit 4 byte array to store the button states
                                        int i;
                                                
                                        wiringPiSetup();                                            // Initialise Wiring Pi
                                        wiringPiSPISetup (0, 3000000);                                // Initialise Wiring Pi SPI interface With 3MHz clock
                                        pinMode (26, OUTPUT);                                        // Setup Parallel Load pin as Output
                                        
                                        digitalWrite (26, LOW);                                        // Pull Parallel Load Pin to Logic Low to load data
                                        delayMicroseconds (1);                                        // Wait one Microsecond for data to stabilise
                                        digitalWrite (26, HIGH);                                    // Pull Parallel Load Pin to Logic High to load data into serial register
                                        
                                        wiringPiSPIDataRW (0, button_state, sizeof(button_state));    // Read data from Shift Registers with SPI of a 32bit value
                                            
                                        for (i = 0; i < 3; i++)
                                        {
                                            printf(button_state[i], "\n");
                                        }
                                    }
                                    
                                    
                                    

                                     

                                    for the moment the code only just prints out the contents of the array, but eventually I need to find out how to map this data to a device tree overlay that references specific assigned keyboard buttons.

                                     

                                    Regards

                                    Paul

                                    1 of 1 people found this helpful
                                      • Re: My Retropie Portable Build
                                        shabaz

                                        Hi Paul,

                                        Each input that is connected to a switch needs a resistor (in your case a pull-down resistor, such as a 10 k resistor) otherwise each input is floating until a switch is pressed.

                                        Is the requirement to have the Chip select be normally low, and then to go high when accessing the chips? If so, you could wire it to any other pin on the Pi and manually set it. Or, just permanently wire it high if that works for your circuit (I have not checked). Also, 100nF capacitors are needed.

                                        Use what you're most comfortable with, I just personally feel using a library like wiringPi is far reduced coding (and more reliable) compared to trying to access BCM.. registers manually.

                                        Also, no matter how confident you are, I'd suggest just buying a few of the ICs and trying it out, rather than buying a tube of 50 if there's a risk your design may change and use a different device. ebay Australia (I would not normally suggest ebay, but if you're struggling to obtain fewer quantities from a distributor) has them in single quantity: https://www.ebay.com.au/itm/74HC165-8-bit-parallel-in-out-Shift-Register-IC/254545886099?epid=1963682493&hash=item3b441d…

                                        2 of 2 people found this helpful
                                          • Re: My Retropie Portable Build
                                            celcius1

                                            The Clock Enable is Active Low, and when it is pulled low starts clocking the data out serially on the rising edge of pulse.

                                             

                                            And I have investigated manually clocking out the data using the GPIO and not the SPI protocol, but it adds a lot more to the code, which I can do, but SPI can read the data in approx 6 microseconds whereas if I code it manually and ensure the slowest delay time of one microsecond per data read I’m looking at approx 40 microseconds to read the data but in thinking that thru, it’s still a short space of time, but I still need to poll the registers.

                                             

                                            Also if I increase the component count again, I can use shotky diodes to tie, all the input lines to a single GPIO pin looking for a button push, and essentially give me an interrupt. But prevent the other lines from being affected.  As much as I could interface a standard row and column approach, I want to keep the amount of GPIO I use to a minimum if I need more in future if I use the same 32 button input hardware.

                                             

                                            ill do a bit more work, and clean up the schematic and I’ll also write the code that handles the data scan manually using wiringpi


                                            i Didn’t mind buying the tube and the IC is a standard one for adding in more inputs, so don’t worry I’ll end up using them. And the tube only cost me $25

                                             

                                            its late here I’ll do it during the day, bed time for me

                                             

                                            Regards

                                            Paul