You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mainclass.cpp 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include "mainclass.hh"
  2. #include <iostream>
  3. #include <libgen.h>
  4. #include <sysexits.h>
  5. #include <climits>
  6. #include <getopt.h>
  7. #include <unistd.h>
  8. #include <pifacedigital.h>
  9. int MainClass::current_device_ = -1;
  10. MainClass::MainClass(int argc, char* argv[])
  11. : argc_(argc)
  12. , argv_(argv)
  13. {
  14. }
  15. int MainClass::usage()
  16. {
  17. std::cerr << "Usage: " << basename(argv_[0]) << std::endl <<
  18. " [--device DEVICE|--device=DEVICE|-e DEVICE]" << std::endl <<
  19. " [--up OUTPUT|--up=OUTPUT|-u OUTPUT]" << std::endl <<
  20. " [--down OUTPUT|--down=OUTPUT|-d OUTPUT]" << std::endl <<
  21. " [--read INPUT|--read=INPUT|-r INPUT]" << std::endl <<
  22. " [--sleep MS|--sleep=MS|-s MS]" << std::endl <<
  23. " [--help|-h]" << std::endl <<
  24. " [--version|-v]" << std::endl;
  25. std::cerr << std::endl << "Controls the output pins and read pins of a PiFace digital IO."
  26. << std::endl << std::endl;
  27. std::cerr << "--device \tSwitch to the provided device."
  28. << std::endl << "--up \t\tEnable the provided ouput pin."
  29. << std::endl << "--down \t\tDisable the provided output pin."
  30. << std::endl << "--read \t\tRead and print the provided input pin."
  31. << std::endl << "--sleep \tSleep for the provided amount of milliseconds."
  32. << std::endl << "--help \t\tDisplay this message."
  33. << std::endl << "--version \tDisplay version."
  34. << std::endl << std::endl;
  35. std::cerr << "OUTPUT \t: The output pin to enable/disable. 0 <= OUTPUT <= 7."
  36. << std::endl << "INPUT \t: The input pin to read. 0 <= INPUT <= 7."
  37. << std::endl << "MS \t: The number of milliseconds to sleep. 0 <= MS <= "
  38. << UINT_MAX << "."
  39. << std::endl << "DEVICE \t: The device number. Default is 0. "
  40. "0 <= DEVICE <= 4." << std::endl;
  41. return EX_USAGE;
  42. }
  43. bool MainClass::bad_value_()
  44. {
  45. extern int optind;
  46. extern char* optarg;
  47. std::cerr << "Bad value " << optarg <<
  48. " for option " << argv_[optind - 2] << std::endl << std::endl;
  49. return false;
  50. }
  51. bool MainClass::build_actions_()
  52. {
  53. option opts[] = {
  54. {"device", 1, 0, 'e'},
  55. {"up", 1, 0, 'u'},
  56. {"down", 1, 0, 'd'},
  57. {"read", 1, 0, 'r'},
  58. {"sleep", 1, 0, 's'},
  59. {"help", 0, 0, 'h'},
  60. {"version", 0, 0, 'v'},
  61. {0, 0, 0, 0}
  62. };
  63. int opt;
  64. extern int optind;
  65. extern char* optarg;
  66. char* endptr;
  67. while ((opt = getopt_long(argc_, argv_, "e:u:d:r:s:hv", opts, 0)) != -1)
  68. {
  69. long int arg = optarg ? strtol(optarg, &endptr, 10) : 0;
  70. if (arg < 0)
  71. return bad_value_();
  72. if (opt == 'e')
  73. {
  74. if (arg > 4)
  75. return bad_value_();
  76. actions_.push_back([arg]() -> bool
  77. {
  78. pifacedigital_close(get_current_device());
  79. return set_current_device(arg);
  80. });
  81. }
  82. else if (opt == 'u' || opt == 'd')
  83. {
  84. if (arg > 7)
  85. return bad_value_();
  86. actions_.push_back([arg, opt]() -> bool
  87. {
  88. if (get_current_device() == -1 &&
  89. !set_current_device(0))
  90. return false;
  91. std::cout << "Setting pin " << arg << " " <<
  92. (opt == 'u' ? "up" : "down") << std::endl;
  93. pifacedigital_write_bit(opt == 'u', arg, OUTPUT,
  94. get_current_device());
  95. return true;
  96. });
  97. }
  98. else if (opt == 'r')
  99. {
  100. if (arg > 7)
  101. return bad_value_();
  102. actions_.push_back([arg, opt]() -> bool
  103. {
  104. if (get_current_device() == -1 &&
  105. !set_current_device(0))
  106. return false;
  107. uint8_t status = pifacedigital_read_bit(arg, INPUT, get_current_device());
  108. std::cout << "Pin " << arg << " value: " <<
  109. (int) status << std::endl;
  110. return true;
  111. });
  112. }
  113. else if (opt == 's')
  114. {
  115. if (arg > INT_MAX)
  116. return bad_value_();
  117. actions_.push_back([arg]() -> bool
  118. {
  119. std::cout << "Sleeping " << (arg * 1000) << " ms" << std::endl;
  120. usleep(arg * 1000);
  121. return true;
  122. });
  123. }
  124. else if (opt == 'v')
  125. {
  126. std::cout << "camotion-piface 1.1" << std::endl;
  127. actions_.clear();
  128. return true;
  129. }
  130. else if (opt == 'h')
  131. {
  132. usage();
  133. actions_.clear();
  134. return true;
  135. }
  136. else
  137. return false;
  138. }
  139. return optind == argc_;
  140. }
  141. int MainClass::execute()
  142. {
  143. if (argc_ == 1 || !build_actions_())
  144. return usage();
  145. for (auto f : actions_)
  146. if (!f())
  147. return 1;
  148. return 0;
  149. }
  150. int MainClass::get_current_device()
  151. {
  152. return current_device_;
  153. }
  154. bool MainClass::set_current_device(int c)
  155. {
  156. std::cout << "Switching to device " << c << std::endl;
  157. if (pifacedigital_open((current_device_ = c)) == -1)
  158. {
  159. std::cerr << std::endl;
  160. return false;
  161. }
  162. return true;
  163. }