Thursday, February 27, 2020

Raspberry Pi Power Switch (Open Source!)

Introduction

This project will describe how to create a power switch for your Raspberry Pi (any version) that safely shuts your R-Pi down with the press of a button and then cut power to the R-Pi. Then, to start the R-Pi back up again, press another button right next to it. Pretty cool, right?

It should be stated that this is not my original idea or design, and I would like to attribute the original creator of the circuit but sadly I can not find their blog anymore. However, I do have a picture that I saved from the blog, which I'll display below. Whoever you are, thank you for creating the original design! You are awesome!

The original circuit diagram.

The purpose of recreating the circuit and blog post is that I've made some improvements to the project overall. In light of the fact that this idea was not my own, I will be open sourcing everything, including all circuit diagrams and PCB designs. Feel free to download them, edit them, and make them your own!

A quick warning about this project is that I have tested this circuit with my own R-Pi with a prototype board I threw together myself and it works perfectly fine, but I have not actually tested the finalized PCB produced by EasyEDA yet, so I have no idea whether it works for sure or not (I'm fairly certain it will work, but I can't guarantee that it will work, so use at your own risk!). Once I order the PCB and test it myself, I will come back and update this post.

The Circuit

Another reason for recreating the circuit diagram was that the original image was very small and a little pixelated, so I have provided a much larger image for download that is easier to see.

The new circuit diagram.

As you can see, I have used the software called EasyEDA to design this diagram (and the PCB as well). The files will be available in EasyEDA source code, as a PNG image, and a PDF file. The Gerber file and other files will be available as well, but I'll get into that later.

Now, I am certainly no expert at laying out a circuit diagram (or PCB layout, as you'll see later), so I apologize if it's a little strange looking. It's a fairly simple circuit; one tactile switch, when pressed, turns on the relay that supplies the 5 volts for the R-Pi and simultaneously starts charging up the capacitor that keeps the relay engaged. When the second tactile switch is pressed, it begins discharging the capacitor as well as sending a 3.3 volt logic level signal to the R-Pi that lets the Pi know it should begin shutting down. The capacitor stays charged for long enough that the R-Pi is able to shut down safely before the cap runs out of charge and switches the relay off. This is an oversimplification of exactly how the circuit works (I really didn't mention the role the transistors play), but it's enough to get a basic understanding.

From here, you can certainly solder everything together on a prototype board and begin using it with your R-Pi, however if you are interested in the PCB, continue reading to the next section. If not, skip ahead to "The Code" section.

Downloads


The Board

The PCB design was not really planned out in any specific way, and I kind of just laid it out how I thought it looked good to me. You can see a 3D preview of it below.

The old 3D preview of the unpopulated PCB with no screw holes.

As I forgot to include screw holes for mounting (Doh!) I'll be coming back and updating this image and everything else later. I've decided to leave up the original design without screw holes is case anybody wants it, however the new design is shown below with screw holes. I don't really like the way it looks with the screw holes, especially because of all the negative space on the top and bottom of the board, but oh well. Both versions of all files are available.

The new 3D preview, with the screw holes.

The board is designed to take 5 volt power in from a micro-B USB socket, which both powers the circuit and the R-Pi. The output is a standard female USB connector that the R-Pi plugs into. To interface with the R-Pi, there is a 1x2 header pin that can be used to connect to the Pi with jumper wires or something similar. When you build this yourself, you can choose to leave out the header altogether and solder wires directly to the board.

The PCB layout in EasyEDA showing the front traces (red), the rear traces (blue), the pads (gray), and the silk screen (yellow).

Above is an image of the PCB being laid out in EasyEDA, which I'm not sure if you'll find useful, but I decided to include it anyways. One reason I included this image is to mention that I did not route these traces myself, I used the autorouter. I know, I know!! Blasphemy! However, it appears to have done the job well enough for this PCB. If something looks incorrect or janky to you, don't blame me, blame EasyEDA's autorouter! (I would like to hear about how the traces could be better routed in the comments, this is my first PCB ever!)

A word about the parts I based this design on: I used generic parts suggested by EasyEDA. That means that the materials listed in the BOM (bill of materials) can be substituted with any compatible parts from any supplier. For example, the transistor listed in the BOM is the 2N3904 PNP transistor, but you could just as well use a 2222A PNP transistor in its place. Just make sure that the substitute part is compatible!

Anyways, everything you might need for this board is below, including the Gerber file.

Downloads


The Code

The code has also been adapted and rewritten from the original, but I don't have the original code unfortunately. This code was written in Node.js (of course, what else would I write it in?), but if you have the skills you can adapt this code to any language that can interface with the R-Pi's GPIO pins. Without further ado, here's the code below.

var Gpio = require('pigpio').Gpio;
var exec = require("child_process").exec;

var input = new Gpio(4, {
 mode: Gpio.INPUT,
 pullUpDown: Gpio.PUD_DOWN,
 edge: Gpio.FALLING_EDGE
});

var output = new Gpio(2, {mode: Gpio.OUTPUT});
output.digitalWrite(1);

input.on('interrupt', (level) => {
 exec('sudo shutdown -h now', (error, stdout, stderr) => {
  if (error) {
   console.error(`exec error: ${error}`);
   return;
  }
  console.log('Shutting down now!');
 });
});

You'll notice that my implementation runs on Wiring-Pi, which sadly is no longer supported. I will definitely be updating the code soon to work with pigpio as it's more or less just as capable as Wiring-Pi, and it's still supported. The code above has been updated and works with pigpio! A link for instructions for installing pigpio are here. Another thing to mention is that this code only works with the R-Pi 2, 3, and 4. For the R-Pi 1, Zero, and Zero W you'll need to change the shorthand function notation inside of the exec() function to the regular function syntax (the reason for this is the older and smaller R-Pi's processor only allows them to run an older version of Node.js that does not support shorthand function notation).

You may need to edit the code if you decide to use different pins than I chose to use, which are pin 11 GPIO04 for the input on the R-Pi and pin 13 GPIO02 for the output on the R-Pi.

Once you have downloaded the code and its dependencies (Wiring-Pi) to your R-Pi, all you need to do is make the script run at startup, by adding the following line to a new line in your rc.local file:

sudo node /path/to/softshut.js &

Next up, it's time to put it all together.

Downloads


Putting it All Together

Once you have your board soldered and put together, it is time to hook it up to your Raspberry Pi. Plug in the micro-B USB cable from your power adapter to the input on the board, then plug in another USB cable from the output to your R-Pi power input. Next, connect the pin on the board labeled "Input" to the R-Pi GPIO pin that will be acting as the output in the script, and then connect the pin labeled "Output" to the R-Pi's pin that will be accepting an input.

Now, press the "On" button and see if it boots up! You will hear the relay click the instant you press the on button. Wait for the R-Pi to fully boot, then try pressing the "Off" button. If the Pi does not immediately start its shutdown sequence, then you've got a problem! If this is the case, enter the shutdown command to your R-Pi as quickly as you can, as the capacitor will have started draining and the relay will switch off the power to your R-Pi soon. Something is wrong with either your script not starting up correctly, or maybe the pins are assigned incorrectly, or something along those lines. You'll need to do some troubleshooting to figure out exactly what went wrong!

Conclusion

All in all this is a very useful addition to just about any Raspberry Pi project, especially with projects that are battery powered! I really wish something like this was built into the R-Pi already, but it makes sense why it wasn't included when you consider the fact that the Raspberry Pi was engineered to be as cheap as possible.

Like I said, I will be coming back and updating/refining this post as I go, but I wanted to publish it as soon as possible, just to get it out into people's hands.

This project will also be available on GitHub once it is finalized, so stayed tuned!

Sunday, February 19, 2017

A Nice Surprise (And a Simple Plugin)

A Nice Surprise

So I was looking through my meager list of repositories on GitHub today and I noticed my Printer jQuery plugin had some new traffic from a page I hadn't seen before, which is kind of unusual since the project is a few years old now. It was from a website called CodeGeekz. I decided to take a look at the source page and to my surprise my plugin made it into a list of "8 Best jQuery Print Page Plugins". Nice!

However, upon closer inspection of the list, I realized that every other plugin in the list is for actually printing out a page or a section of a page whereas my plugin is more like a content slider with a quirky name. Oops! Someone didn't do their homework I see. Still, it's nice to have my work featured somewhere new and I very much appreciate it.

My plugin was also featured on a website known as jQueryRain back in October of 2014 which you can check out here. That was also nice to see. Thanks for the shares!

For those of you who don't know what my Printer plugin is, you're in luck! I'm going to detail it in the next section.

A Simple Plugin

So the plugin is pretty simple. As is stated in the read me file on the GitHub project page "Printer is an open source AJAX style page loading jQuery plugin that retrieves the URL from each hyperlink in the sidebar on the fly upon being clicked. It can also function as a rudimentary slideshow (but keep in mind this plugin does not cache any resources, i.e. Printer will make a new AJAX request on each new slide)."

There you have it, a pretty simple plugin to load new content into the page AJAXically (is that a word?) with simple animations. To code something like this wouldn't take very long, I admit, but it was supposed to have some other features as well that I still haven't gotten around to adding. Sigh. It was also kind of a "Hello World" project for me as it was my very first project I put up on GitHub.

A demo of it is available here, and if you like it, go ahead and use it on whatever project you want to. It's free after all!

As always, thanks for reading. Questions about how the plugin works or how to set it up can be posted here. Errors and pull requests on GitHub are welcome as well.

Friday, February 19, 2016

New Node.js module - PiDisplay

UPDATE: This module needs to be rewritten using pigpio as Wiring-Pi is no longer supported! I will be getting to this soon.

Sorry

I know it has been a long time since I have posted. I have been meaning to post Part 2 to the Raspberry Pi camera server that I had blogged about earlier, and I promise that will be completed soon. However, I have been working on many projects and websites since then and I haven't had much time to post. Anyways, with that said, here's something unrelated to the aforementioned camera server which I hope will be useful to at least some of you.

So What is it?

My new project is about a new Node.js module that I have developed. It is controller software that is used to display numbers and some letters on a 2 digit, 7 segment LED display which is attached to the Raspberry Pi. If you would like to see a demo of it, view my Github repository or my NPM package.

Installation

Installation is super simple (assuming you have NPM installed). All you need to do is navigate to your project directory via the command line and execute this command:

npm install pi-display
 Viola! Now you have PiDisplay installed! Now onto...

How do I Use it?

You can find a usage example in the two aforementioned links in the "So What is it?" section. You'll definitely want to read through the readme file in either of the two links as there is some crucial information that I am leaving out of this blog for brevity's sake. It includes information on how to wire up the display and how to reassign the pins if you do not use the same pins as I did. Anyways, I shall give a brief example of how to program the display in this blog post.

test.js

// Don't forget the extra parentheses to call the constructor function! 
var piDisplay = require("pi-display")();
 
// Displays E7 on the LED display. 
piDisplay.displayChars("E7");
 
// Displays 85. 
piDisplay.displayChars(85);
 
// Scrolls the given string across the display. It looks more natural to scroll 
// if you have spaces at either end of the string, but they are not mandatory. 
// The second argument is the milliseconds to display each character. 
piDisplay.scrollChars(" HI HELLO 1234567890 ", 400);

So as you can see, you must require() the package, then immediately after call it's constructor function. You may pass two arguments to the constructor function, ledPins and cathodePins. For information on how to format these objects, please see the documentation on either the NPM module description or the Github readme file.

Next, we use the displayChars() method. This method accepts one argument, chars. chars is a string or number not more than two characters in length. This method displays the argument that is passed to it on the LED display, assuming that the string or number is acceptable. The next line does the same thing, but instead of passing a string to the method, a number is passed. An important note about displayChars() is that it keeps Node.js running as long as the method is executing. To stop the execution of displayChars(), execute the method clearDisplay().

Lastly, the method scrollChars() scrolls a string (first argument) across the LED display, one characters at a time. Only certain letters are allowed; again, see the NPM module description or the Github readme file for more information on which letters are allowed. The second argument is the speed at which to display each individual character on the display (in milliseconds).

That's All Folks

So now you know how to use my PiDisplay module. If I have left any bugs or errors in the code, don't hesitate to submit an Issue to my Github repository. And if you have any feature requests or want to contribute, submit a Pull Request on Github.

Thanks for reading! You can also post questions on this page of course!

Tuesday, May 5, 2015

Stream the Raspberry Pi Camera Module from Node.js to an img Tag in the Browser, Part 1 - The Server (Updated)

Update 1
Update 2

Preface

So, I know this is a pretty specific use case, but it was something I really wanted to be able to do for an open source project I'm working on. The VLC Web Plugin used to be able to handle receiving video from the VLC program on the Raspberry Pi, but Google decided that the VLC Web Plugin was insecure and barred it from appearing in Chrome any longer (and I expect other browser developers to do the same). Out of necessity, I came up with a different solution. I thought I would separate this topic out into it's own post because my project is pretty far from being done and I thought this could be useful to someone now without having to wait.