• Power Button

    Radomir Dopieralski4 days ago 0 comments

    Independently from hacking the LiFePO4 power module, I decided to try and make a small module with a soft power button on it — the same I linked two logs ago. I will use a thin PCB, so that it can be inserted between shields.

    The schematic is based on several designs from various forums — I'm not smart enough to figure it out myself. Pressing the button switches the power on and latches it. Subsequent pressing of the button does noting, except pulling the GPIO4 down to let the Raspberry Pi know that we want to shut down. A long press (or pulling the GPIO4 low) forces it off.

    It's a little bit more complex than I'm comfortable with, but we will see how well it works.

  • Honey, I Shrunk Our LiFePO4

    Radomir Dopieralski5 days ago 6 comments

    Both the new PCB and the #LiFePO4wered/Pi arrived while I was away, so I can now get back to hacking. But what is this? It's too long for the the Raspberry Pi Zero, as it was originally designed for the Raspberry Pi B, which is a little bit longer. But fear not, I anticipated that problem and ordered a smaller LiFePO4 battery, that should be just the right size. Now it's just a matter of replacement of the battery basket:

    I guess I will need to cut that PCB a little bit too. Oh well. I also removed the female headers from the power module, in order to solder it flat on top of the hat. Unfortunately, there is one pesky SMD resistor getting in the way there, so it won't be completely flat.

    In other news, I'm really happy with the through-hole buttons, they are much easier to solder and fit in that tight space -- although I didn't find color ones.

    I still need to get a display for this -- either order another one, or desolder one from the first prototype.

  • Power

    Radomir Dopieralski07/04/2017 at 20:43 0 comments

    The ZeroLiPO module doesn't work very well with this power-hungry display. Adding a big capacitor across the power helped somewhat, but you can still see problems when the display has a lot of white to show.

    For now I'm just powering the whole thing from a 1S LiPO battery directly, without any boost converter or other circuit. That works well, due to reasons described in this project log, and I'm actually quite happy with this. However, there is no overdischarge protection, and I need to manually switch the power off after the raspberry pi shuts down – there should be a better way to do it.

    So I started looking around for a ready module for that – what can I say, I'm lazy – and was quite surprised that I couldn't find anything like that. OK, fine, I will just have to build my own. I looked around a bit for similar projects to steal from, and found this one: http://www.mosaic-industries.com/embedded-systems/microcontroller-projects/raspberry-pi/on-off-power-controller – it's a very nice schematic, and it only uses one GPIO pin to both signal the pi to shutdown, and see when it finished. I might still make this, because it's generally useful, but for now I have a better idea.

    That project log I linked, it's for a project that exactly fits my needs. And that project is available to buy on Tindie. It's a battery, a charger, a touch pad button for switching it on and off, and I2C for battery monitoring and low power shutdown. It does everything I need. I will probably try to put a smaller battery in it, so that it fits the size of the pi zero better, but that's it.

  • Let's do it Right

    Radomir Dopieralski06/25/2017 at 15:49 0 comments

      After a bit of research and experimenting, I can now conclude that my initial PCB design has a number of flaws, namely:

      1. I'm choose the only pin that can't be used as button when SPI is enabled, BCM7, for the UP button.
      2. I choose the pin that LiPO Zero module uses for signalling shutdown for the L1 button.
      3. I power the OLED from the regulated 3.3V, instead of the 5V power.
      4. I drive the mini-speakers directly from the PWM pins (with low-pass filters), without any amplifier.
      5. I didn't include a footprint for an ON/OFF switch.
      6. I placed one of the audio circuits right under the display's power coil.
      7. I arranged the SMD buttons in such a way, that they have to be soldered manually in a certain order.

      I decided to fix those flaws in a second revision of the PCB, and in also to add an EEPROM chip that will store the pin configuration and the device tree overlays necessary to use this board. In other words, I'm turning this into a proper HAT.

      Here's the second version of the PCB so far:

      You can see that I moved the audio filters, so that they are together, and there is a header for their output -- that's where the amplifier board will go. There are no footprints for the speakers -- they will also go on the amplifier board. There is a resistor next to the L2 button, because the BCM6 pin can go high on the old Raspberry Pi versions during the boot, and we don't want to have a short when the user happens to be holding that button down. There is an EEPROM chip with its pull-up resistors for I2C, as specified in the HAT design guide. Oh, and I switched to using through-hole buttons, because they actually use less space on the board, and will be easier to solder.

      I also took the time to actually draw a proper schematic:

      Then I wrote the overlay file for this board, which goes something like this:

      /dts-v1/;
      /plugin/;
      
      / {
          compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";
      
          fragment@0 {
              target = <&gpio>;
              __overlay__ {
                  pinctrl-names = "default";
                  pinctrl-0 = <&pwm_audio_pins>;
      
                  pwm_audio_pins: pwm_audio_pins {
                      brcm,pins = <12 13>;   // gpio no ('BCM' number)
                      brcm,function = <4 4>; // 0:in, 1:out, 2: alt5, 3: alt4, 4: alt0, 5: alt1, 6: alt2, 7: alt3
                      brcm,pull = <0 0>;     // 2:up 1:down 0:none
                  };
                  keypad_pins: keypad_pins {
                      brcm,pins =     <20 26 21 19  5 23 18 17 16  6 22 27>;
                      brcm,function = < 0  0  0  0  0  0  0  0  0  0  0  0>; // in
                      brcm,pull =     < 2  2  2  2  2  2  2  2  2  2  2  2>; // up
                  };
                  oled_pins: oled_pins {
                      brcm,pins = <24 25>;
                      brcm,function = <1 1>;
                      brcm,pull = <0 0>;
                  };
              };
          };
      
          fragment@1 {
              target = <&soc>;
              __overlay__ {
                  keypad: keypad {
                      compatible = "gpio-keys";
                      pinctrl-names = "default";
                      pinctrl-0 = <&keypad_pins>;
                      #address-cells = <1>;
                      #size-cells = <0>;
      
                      button@20 {
                          label = "up";
                          linux,code = <103>; // KEY_UP
                          gpios = <&gpio 20 1>;
                      };
                      button@26 {
                          label = "down";
                          linux,code = <108>; // KEY_DOWN
                          gpios = <&gpio 26 1>;
                      };
                      button@21 {
                          label = "left";
                          linux,code = <105>; // KEY_LEFT
                          gpios = <&gpio 21 1>;
                      };
                      button@19 {
                          label = "right";
                          linux,code = <106>; // KEY_RIGHT
                          gpios = <&gpio 19 1>;
                      };
                      button@5 {
                          label = "X";
                          linux,code = <45>; // KEY_X
                          gpios = <&gpio 5 1>;
                      };
                      button@23 {
                          label = "Z";
                          linux,code = <44>; // KEY_Z
                          gpios = <&gpio 23 1>;
                      };
                      button@18 {
                          label = "R1";
                          linux,code = <30>; // KEY_A
                          gpios = <&gpio 18 1>;
                      };
                      button@17 {
                          label = "R2";
                          linux,code = <31>; // KEY_S
                          gpios = <&gpio 17 1>;
                      };
                      button@16 {
                          label = "L1";
                          linux,code = <32>; // KEY_D
                          gpios = <&gpio 16 1>;
                      };
                      button@6 {
                          label = "L2";
                          linux,code = <33>; // KEY_F
                          gpios = <&gpio 6 1>;
                      };
                      button@22 {
                          label = "start";
                          linux,code = <28>; // KEY_ENTER
                          gpios = <&gpio 22 1>;
                      };
                      button@27 {
                          label = "select";
                          linux,code = <57>; // KEY_SPACE
                          gpios = <&gpio 27 1>;
                      };
                  };
              };
          };
      
      
          fragment@2 {
              target = <&spi0>;
              __overlay__ {
                  status = "okay";
                  #address-cells = <1>;
                  #size-cells = <0>;
      
                  spidev@0{
                      status = "disabled";
                  };
                  spidev@1{
                      status = "disabled";
                  };
                  oled_display: oled_display@0{
                      compatible = "ssd,fb_ssd1351";
       status = "okay";
      ...
    Read more »

  • Audio

    Radomir Dopieralski06/23/2017 at 22:21 0 comments

    Leaving the struggles with device tree overlays on the side for a moment, I decided to try and get the audio to work. When designing the board, I followed instructions by Adafruit on how to get PWM Audio on the Pi Zero. Except that instead of headphones I have two tiny SMD speakers in there.

    Of course the device tree method didn't work -- results in a Segmentation Fault as soon as audio is used. Poking around a bit, I found this tutorial that lets you do it by only editing the config.txt, without your own overlay, and this worked: https://www.raspberrypi.org/forums/viewtopic.php?f=38&t=168084

    Of course, without an amplifier I expect the sound to be very quiet. It is in fact barely audible. What's worse, the noise from the display, and the noise from the display signal induced in the speaker, are orders of magnitude louder!

    I think I will either need an amplifier module for this, or just give up on the sound. For now I ordered an amplifier and will see how it will work.

  • Power Problems Solved

    Radomir Dopieralski06/23/2017 at 16:59 0 comments

    A quick PCB surgery, and I cut the trace from near the pin 1 of the pi connector from display's vcc, and connected that to the nearby 5V connector that I left there for power. That solved the weird behavior of the display and the restarts, but it's still making chirping noises. The images below show the changes:

    In other news, I managed to move the whole configuration of the display into an overlay, and also got the keys work with gpio-keys driver -- except one of the fire buttons, which uses gpio 7, and which is a second CS pin for the SPI controller. The SPI driver just won't give that pin up.

    I already started designing second version of the PCB that would use other pins -- tested working -- but I'm still not entirely sure if I'm going to be ordering that. De-soldering this display now would be a little tricky without hot air. I guess it all depends on whether there are more mistakes to be found in the audio system, which I didn't test yet.

    I'm also still thinking about bet option for powering this. Right now I'm leaning towards a flat lipo sandwitched between the two boards, because that would be small, but it's really getting hot in there, so I'm not sure.

  • Display Power Problems

    Radomir Dopieralski06/23/2017 at 00:05 4 comments

    As I'm getting more of it to work and testing with Pico8, I'm starting to see that I have a serious problem with the display. As soon as there are white vertical lines on it, it starts making high-pitched noises and do "tv noise" for some frames, and then the whole Raspberry Pi hangs.

    Looking at the schematic, I think I made a big mistake connecting the display's power to pi's 3.3V pin. Sure, the display can run both on 3.3V and 5V, and since there is no communication from the display to the pi, there is no problem with voltage incompatibility. I suspect that this display takes a bit too much juice for the pi's regulator.

    The solution? I will try to un-solder the VCC pin of the display, and use a wire to connect it to the 5V pins. We will see how that works. One downside is that won't look so good anymore.

    If that doesn't help, there is one more possibility -- the display drivers in the kernel may be simply buggy, sending to the display some weird commands that trip it up.

  • Buttons

    Radomir Dopieralski06/22/2017 at 22:39 0 comments

    Pretty much every GPIO pin not used for the display or audio is used for the buttons. I decided to make it simple and just use a separate pin for every button. The list looks like this:

    • UP 20
    • DOWN 26
    • LEFT 16
    • RIGHT 6
    • A 23
    • B 7
    • L1 12
    • L2 5
    • R1 4
    • R2 17
    • START 22
    • SELECT 27

    In addition, pins 13 and 18 are used for audio, and pins 8, 10, 11, 24, 25 are used by the display. I didn't plan the pins for the keys too much -- I just connected whatever was closest to the physical button. That means that, for example, L1 is using the same pin as the ZeroLiPO module uses to signal shutdown... but I think I can move that.

    In any case, initially I planned to use Adafruit's RetroGame daemon that constantly polls the pins and then generates keypress events. But someone on the #raspberrypi channel on Freenode suggested that I can use Device Tree Overlays instead. I got interested and decided to try it.

    As with all the Linux Kernel stuff, there is practically no documentation, you have to read the source code. Fortunately I found a pretty nice example for configuring a GPIO keyboard. I tested it on a few of my keys, and it worked great! Awesome, that was easier than expected! I quickly added the rest of my keys to the overlay file, compiled it and restarted, expecting it to work. Of course it didn't. Checking dmesg let me see error messages suggesting that the kernel driver can't claim pins 7 and 20, because they are being used by the SPI peripheral. Of course I can't disable SPI, because that's how my display is connected. But I'm not using all those pins. How can I tell the driver that?

    After a few hours of searching the Internet, trawling through source files, trying various things, etc. I finally realized that I'm wasting my time. I just deleted all this overlay nonsense, installed the Adafruit demon, configured it quickly and that's it. Somehow the demon doesn't have any problems with any pins being used by something else.

    But there is one more thing I learned, which might make me re-thing the pin mapping and actually try to get this to work. Apparently Pi HATs can have on them a small EEPROM memory chip, to which we can record the overlays that this shield needs. That means that with a little work (and fixing some bugs in the kernel, I'm sure), it would be possible to build a shield that would require no manual configuration: just connect it switch it on, and it just works. That would be great, *if* it worked.

  • Display

    Radomir Dopieralski06/22/2017 at 11:55 0 comments

    The display is a 128×128 1.5" RGB OLED module, with a SSD1351 chip that communicates with the Pi over the SPI interface. I'm using the fbtft Linux driver for driving it, together with fbcp utility to copy the framebuffers. I have rotated the display 90° to make it fit with the dimensions of the Pi Zero better -- it only sticks a few millimeters on either side. Since this is an OLED, and not an LCD, the viewing angles are excellent and don't really change with the display's orientation.

    I'm using a module and not a bare display, even though I'm making a custom PCB. That's because the OLED display needs quite a lot of components, including a voltage boost, and I'm not trusting myself to get all that right. It's also because I already have the module.

    The size of this display, while a bit small, is perfect for the pico8 fantasy game console.

  • Jumping on the Bandwagon

    Radomir Dopieralski06/22/2017 at 11:42 0 comments

    Everybody and their dog seem to be making retro handheld consoles out of the pi zero, so I decided it's time to join the party. This one is mostly inspired by the #Pi0CKET-tiny project -- but I didn't have the cool rocker, and I wanted to try a horizontal orientation. I also used an OLED screen in place of a TFT, because of better viewing angles. Oh, and instead of the joystick I used standard buttons. But otherwise it's very similar.

    I started by testing the screen. I simply connected it to the SPI port and followed the instructions from #Pi0CKET-tiny about configuring it. Except I used the "pioled" for the display driver name. I stumbled upon the same bug with rotated display, and I solved it in the same way -- when that gets fixed, we can both remove the hacks.

    Once I knew the display works, I became confident enough about all the rest to design and order the PCB.

    It's basically just the screen connections, the low-pass filters for the speakers, and all the rest of pins are connected to the buttons. And yes, I got a bit wild with the holes. Sue me.