Bogusław Kempny

Raspberry Pi OS shutdown

Autor adres Polski
About HC-SR04 LCD Camera fork() Short Message Service strfry() GPIO pulses Keypad Gate GPIO PWM SG90 RFID Graphologist Time and attendance Shutdown Temperature ....

Raspberry Pi is a great computer, but sometimes it lacks the ability to easily shutdown the operating system.
We do not always have the ability to log in, for example, via ssh and issue a shutdown command or similar. We can only perform a brutal power off.

The solution that I used in our Mini Time And Attendance system may be helpful.

The centrally located button is used to switch between ingoing and outgoing recording, however, if you hold it for longer, 5 seconds (as in the video above), the shutdown procedure will start.
The processes important to us will be completed (in this case, the process of attendance registering, testing the sobriety of employees, opening the door), the operating system will start shutting down, and after 10 seconds the display backlight will be turned off.

Unfortunately, the power will not be turned off, it would require additional hardware, but the correct shutdown of the operating system is a valuable thing.

Sample program called reset.c , must be compiled with the WiringPI library, using the following command:

cc reset.c -o reset  -lwiringPi

This time the display was connected via the I2C bus, contrary to what I described in the LCD.

Thanks to the small, inexpensive HW-061 module

instead of 8 wires connecting the display to the Raspberry, we only need 4 (including power and ground).
Also, our display becomes much more noise resistant.

In the near future, I will explain how to connect such a display via the I2C bus. For now, to understand the software functionality, I suggest taking a look at the MiniT&A diagram .

Well, now how it works.

We will not discuss I2C display control procedures, but only the main operating system shutdown procedure:

We connect this pin with the astable switch to the GND pin of the Raspberry:

#define WEWY 25 // connect reset switch to this pin and GND
We will mask the signals, so we will need a mask of them:
static sigset_t   signal_mask;  /* signals to block         */

void main (argc, argv) int argc; char *argv[]; { .......
We initiate wiringPi, program the WEWY pin to the input and force logical one on it by activating the pull-up resistor:

// check wiringPi setup
if (wiringPiSetup() == -1)

// set reset pin to input, activate pull-up resistor
pinMode (WEWY , INPUT) ;
pullUpDnControl(WEWY, PUD_UP);

Now, in an infinite loop, every 200 milliseconds we check the state of the WEWY pin. If we press the switch, a logical zero will appear on it.

int state;
int count;

while (TRUE)
We check if the switch was pressed for 6 seconds (30 x 200 mS):
   if (state == 0) // WEWY pin connected to GND
     for(count=30;count>0;count--)  //WEWY pin connected to GND for 6 seconds
       if(state == 1) break;
Here we find ourselves after 6 seconds of continuously pressed the switch:
     if (state == 0)
Now we can kill the process (or several processes) that we want to finish correctly:
       system("killall pomiar");  // terminate a process
We initiate cooperation with the I2C display and display the system shutdown message:
//**** initiate LCD Display
    fdlcd = wiringPiI2CSetup(I2C_ADDR);
    lcd_init(); // setup LCD
    lcdLoc (0, 0) ; // set cursor at line 0, column 0
    typeln ("Closing the system") ; // display some info on LCD
Now we mask the signals so that the operating system does not terminate our process prematurely:
//*****  mask signals to avoid premature closure of our process

    sigemptyset (&signal_mask);
    sigaddset (&signal_mask, SIGINT);
    sigaddset (&signal_mask, SIGTERM);
    sigaddset (&signal_mask, SIGHUP);
    sigprocmask(SIG_BLOCK, &signal_mask, NULL);
We wait 900 milliseconds (this is not needed) and start shutting down the system:

    system("shutdown -h now"); // begin shutdown procedure
After 10 seconds (in practice, usually a shorter time is enough, about 6 seconds), we turn off the backlight of the LCD display and finish our process.
//**** wait 10 seconds
    sleep_time = 10;
    while (sleep_time > 0)
      sleep_time = sleep (sleep_time);
// *** turn off LCD backlight
    lcd_backlight = 0x00;
    typeln (" ") ;

You can power off the Raspberry.