Guest User

Raspi3B Power Switch Code

a guest
Apr 20th, 2017
538
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.15 KB | None | 0 0
  1. /*
  2.         Raspi3B Power Control Pin Raspbian Jessie
  3.         Bilgus -- 2017 CC-BY-SA 3.0
  4.         Requires WiringPI http://wiringpi.com/
  5.  
  6.         Compiling:
  7.         gcc -o powerctl_pin powerctl_pin.c -l wiringPi && chmod +x powerctl_pin &&
  8.         sudo cp powerctl_pin /bin/
  9.  
  10.         Install:
  11.         sudo /bin/powerctl_pin 21 install
  12.        
  13.         Uninstall:
  14.         sudo /bin/powerctl_pin 21 uninstall
  15.  
  16.         Shutdown:
  17.         sudo /bin/powerctl_pin 21 poweroff
  18.  
  19.  
  20.         /bin/powerctl_pin Broadcom_pin#, mode
  21.         Valid Modes: poweroff, poweron, install, uninstall
  22.         Works with mosfet latch switch
  23.         https://easyeda.com/Bilgus/New_Project-4ce1316bb1f6402985f8d1c4f196448d
  24.         Original Circuit:
  25.         http://www.mosaic-industries.com/embedded-systems/microcontroller-projects
  26.         /raspberry-pi/on-off-power-controller
  27. */
  28.  
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <syslog.h>
  32. #include <signal.h> //sigterm, sigint()
  33. #include "wiringPi.h"
  34. #define WIRINGPI_CODES 999 /* enable error checking on setup */
  35.  
  36. #define POWEROFF_SVC "PwrCtl_Pin.service"
  37. #define POWEROFF_SVC_PATH "/lib/systemd/system/"POWEROFF_SVC
  38. #define REQUIRES "shutdown.target umount.target final.target poweroff.target"
  39. #define AFTER "shutdown.target umount.target final.target"
  40. #define BEFORE "systemd-poweroff.service"
  41. #define WANTEDBY "poweroff.target"
  42. #define POWERINT_SVC "PwrCtl_Pin-Interrupt.service"
  43. #define POWERINT_SVC_PATH "/lib/systemd/system/"POWERINT_SVC
  44.  
  45. static void poweroff_ISR_INIT(int pin);
  46. static int g_pin = 0;
  47.  
  48.         /* enables pullup - unneeded to hold latch */
  49.         static void poweron_pin(int pin)
  50.         {
  51.                 pullUpDnControl(pin, PUD_UP);
  52.                 pinMode(pin, INPUT);
  53.         }
  54.  
  55.         /* pulls pin low in short loop to turn power off */
  56.         static void poweroff_pin(int pin)
  57.         {
  58.                 pullUpDnControl(pin, PUD_OFF);
  59.                 int c;
  60.                 for(c=0;c<20;c++)
  61.                 {
  62.                         //pinMode(pin, INPUT);
  63.                         //pullUpDnControl(pin, PUD_DOWN);
  64.                         digitalWrite(pin,LOW);
  65.                         pinMode(pin, OUTPUT);
  66.                         digitalWrite(pin,LOW);
  67.                         delay(500);
  68.                 }
  69.         }
  70.        
  71.         /* ISR Called when pin goes from high to low debounce checks that still low */
  72.         static void poweroff_ISR(void)
  73.         {
  74.                 delay(100);
  75.                 if (digitalRead(g_pin) == LOW) /* pin debounce */
  76.                 {
  77.                         openlog ("Poweroff ISR", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
  78.                         syslog (LOG_NOTICE, "ISR Triggered - Shutdown -h now");
  79.                         closelog();
  80.                         system("shutdown -h now");
  81.                         exit(0);
  82.                 }
  83.                 else
  84.                         poweroff_ISR_INIT(g_pin);
  85.         }
  86.  
  87.         /* signal handler recieves shutdown signals */
  88.         static void signal_handler(int signal_0)
  89.         {
  90.                 if (signal_0 == SIGINT || signal_0 == SIGTERM || signal_0 == SIGSTOP)
  91.                 exit(0);
  92.         }
  93.  
  94.         /* Initialize Poweroff ISR handler */
  95.         static void poweroff_ISR_INIT(int pin)
  96.         {
  97.                 g_pin = pin;
  98.                 pinMode(pin, INPUT);
  99.                 pullUpDnControl(pin, PUD_UP);
  100.                 wiringPiISR(pin, INT_EDGE_FALLING, &poweroff_ISR);
  101.                 while(1)
  102.                 {
  103.                         delay(100);
  104.                         ;;
  105.                 }
  106.         }
  107.  
  108.         /* creates service daemons */
  109.         static void install(int pin, char *prog_path)
  110.         {
  111.                 FILE *f = fopen(POWEROFF_SVC_PATH, "w");
  112.                 if (f == NULL)
  113.                 {
  114.                         fprintf(stderr, "Error opening file! %s\n", POWEROFF_SVC_PATH);
  115.                         exit(-6);
  116.                 }
  117.                 fprintf(f, "# POWER CONTROL PIN SERVICE \n# %s\n\n", prog_path);
  118.                 fprintf(f, "[Unit]\nDescription=PowerCtl_Pin pulls GPIO pin %i LOW\n", pin);
  119.                 fprintf(f, "DefaultDependencies=no\n");
  120.                 fprintf(f, "Requires=%s\n", REQUIRES);
  121.                 fprintf(f, "After=%s\nBefore=%s\n\n", AFTER, BEFORE);
  122.                 fprintf(f, "[Service]\nType=oneshot\n");
  123.                 fprintf(f, "ExecStart=%s %i poweroff\n\n", prog_path, pin);
  124.                 fprintf(f, "[Install]\nWantedBy=%s\n\n", WANTEDBY);
  125.                 fclose(f);
  126.                 printf("Service file created: %s\n", POWEROFF_SVC_PATH);
  127.                 system("systemctl enable " POWEROFF_SVC);
  128.  
  129.                 FILE *f1 = fopen(POWERINT_SVC_PATH, "w");
  130.                 if (f1 == NULL)
  131.                 {
  132.                         fprintf(stderr, "Error opening file! %s\n", POWERINT_SVC_PATH);
  133.                         exit(-7);
  134.                 }
  135.                 fprintf(f1, "# POWER CONTROL PIN INTERRUPT SERVICE \n");
  136.                 fprintf(f1, "# %s\n\n", prog_path);
  137.                 fprintf(f1, "[Unit]\nDescription=PowerCtl_Pin Interrupt watches GPIO ");
  138.                 fprintf(f1, "for pin %i LOW calls shutdown now\n", pin);
  139.                 fprintf(f1, "DefaultDependencies=no\n");
  140.                 fprintf(f1, "After=network.target\n\n");
  141.                 fprintf(f1, "[Service]\nType=simple\n");
  142.                 fprintf(f1, "ExecStart=%s %i interrupt &\n", prog_path, pin);
  143.                 fprintf(f1, "TimeoutSec=0\nRestart=always\n\n");
  144.                 fprintf(f1, "[Install]\nWantedBy=multi-user.target\n\n");
  145.                 fclose(f1);
  146.                 printf("\n\rService file created: %s\n", POWERINT_SVC_PATH);
  147.                 system("systemctl enable " POWERINT_SVC);
  148.                 printf("Attempting to start: %s\n\r", POWERINT_SVC_PATH);
  149.                 system("systemctl start " POWERINT_SVC);
  150.         }/*install*/
  151.  
  152.         /* disables/stops service daemons */
  153.          static void uninstall(int pin, char *prog_path)
  154.         {
  155.                 system("systemctl disable " POWEROFF_SVC);
  156.                 printf("Service file still exists: %s\n\n", POWEROFF_SVC_PATH);
  157.  
  158.                 system("systemctl stop " POWERINT_SVC);
  159.                 system("systemctl disable " POWERINT_SVC);
  160.                 printf("Service file still exists: %s\n", POWERINT_SVC_PATH);
  161.         }
  162.  
  163.  
  164.         int main(int argc, char **argv)
  165.         {
  166.                 int pin = 0;
  167.                 if (geteuid() != 0)
  168.                 {
  169.                         fprintf (stderr, "You need to be root to run this program. (sudo?)\n") ;
  170.                         exit(-1);
  171.                 }
  172.                 putenv("WIRINGPI_CODES=WhOkNoWs??");
  173.                 if (wiringPiSetupGpio() != 0) /* change to wiringPiSetup() for WiringPi Pins*/
  174.                 {
  175.                         fprintf(stderr, "wiringPiSetup error\n");
  176.                         exit(-2);
  177.                 }
  178.  
  179.                 if(argc < 3)
  180.                 {
  181.                         fprintf (stderr, "not enough args poweroff_pin(brcm_pin# mode)\n") ;
  182.                         fprintf (stderr, "Valid Mode [power[off/on], interrupt, install, uninstall]])\n") ;
  183.                         exit(-3);
  184.                 }
  185.                 else if (sscanf (argv[1],"%i", &pin) != 1)
  186.                 {
  187.                         fprintf (stderr, "invalid pin number,  poweroff_pin(brcm_pin# mode) ");
  188.                         fprintf (stderr, "Valid Mode [power[off/on], interrupt, install, uninstall]])\n") ;
  189.                         exit(-4);
  190.                 }
  191.                 else if(strncmp(argv[2],"interrupt",10) == 0)
  192.                 {
  193.                         openlog (argv[0], LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
  194.                         syslog (LOG_NOTICE, "%s - interrupt mode pin = %s", argv[0], argv[1]);
  195.                         closelog();
  196.  
  197.                         if (signal(SIGINT, signal_handler) == SIG_ERR)
  198.                         {
  199.                                 fprintf(stderr, "Unable to register signal handler\n");
  200.                                 exit(-5);
  201.                         }
  202.                         poweroff_ISR_INIT(pin);
  203.                 }
  204.                 else if(strncmp(argv[2],"poweroff",10) == 0)
  205.                 {
  206.                         poweroff_pin(pin);
  207.                 }
  208.                 else if(strncmp(argv[2],"install",10) == 0)
  209.                 {
  210.                         openlog (argv[0], LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
  211.                         syslog (LOG_NOTICE, "%s - install pin = %s", argv[0], argv[1]);
  212.                         closelog();
  213.                         install(pin, argv[0]);
  214.                 }
  215.                 else if(strncmp(argv[2],"uninstall",10) == 0)
  216.                 {
  217.                         openlog (argv[0], LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
  218.                         syslog (LOG_NOTICE, "%s - uninstall pin = %s", argv[0], argv[1]);
  219.                         closelog();
  220.                         uninstall(pin, argv[0]);
  221.                 }
  222.                 else
  223.                 {
  224.                         poweron_pin(pin);
  225.                 }
  226.         return 0;
  227.         }/*main*/
Advertisement
Add Comment
Please, Sign In to add comment