|
/* |
|
$ gcc -O6 -Wall -pedantic -Wextra -o dead-man_button dead-man_button.c -lpigpio -lrt -lpthread |
|
$ |
|
|
|
Usage: |
|
$ sudo killall pigpiod |
|
$ sudo ./dead-man_button |
|
$ |
|
*/ |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <strings.h> |
|
#include <unistd.h> |
|
#include <stdint.h> |
|
#include <assert.h> |
|
#include <sys/types.h> |
|
#include <sys/socket.h> |
|
#include <netinet/in.h> |
|
#include <sys/select.h> |
|
|
|
#include <pigpio.h> |
|
|
|
#define gpioLeftFwd 25 // 27 |
|
#define gpioLeftRew 9 // 22 |
|
#define gpioLeftPwm 24 // 23 |
|
#define gpioRghtFwd 23 // 25 |
|
#define gpioRghtRew 17 // 9 |
|
#define gpioRghtPwm 18 // 10 |
|
|
|
int sockfd, nfd; |
|
|
|
void emergency_stop(int loc) |
|
{ |
|
// simple version; later "high speed small area" |
|
fprintf(stderr, "emergency stop (%d)\n", loc); |
|
gpioWrite(gpioLeftFwd, 0); |
|
gpioWrite(gpioLeftRew, 0); |
|
gpioPWM(gpioLeftPwm, 0); |
|
gpioWrite(gpioRghtFwd, 0); |
|
gpioWrite(gpioRghtRew, 0); |
|
gpioPWM(gpioRghtPwm, 0); |
|
gpioTerminate(); |
|
close(nfd); |
|
close(sockfd); |
|
exit(1); |
|
} |
|
|
|
int main(int argc, char *argv[]) |
|
{ |
|
uint8_t buf[8]; |
|
fd_set set; |
|
socklen_t clilen; |
|
struct sockaddr_in serv_addr, cli_addr; |
|
int port = (argc>1) ? atoi(argv[1]) : 1337; |
|
|
|
assert(gpioInitialise()>=0); |
|
|
|
gpioSetMode(gpioLeftFwd, PI_OUTPUT); |
|
gpioSetMode(gpioLeftRew, PI_OUTPUT); |
|
gpioSetMode(gpioRghtFwd, PI_OUTPUT); |
|
gpioSetMode(gpioRghtRew, PI_OUTPUT); |
|
|
|
gpioWrite(gpioLeftFwd, 0); |
|
gpioWrite(gpioLeftRew, 0); |
|
gpioPWM(gpioLeftPwm, 0); |
|
gpioWrite(gpioRghtFwd, 0); |
|
gpioWrite(gpioRghtRew, 0); |
|
gpioPWM(gpioRghtPwm, 0); |
|
|
|
assert( (sockfd = socket(AF_INET, SOCK_STREAM, 0) ) >= 0); |
|
bzero((char *) &serv_addr, sizeof(serv_addr)); |
|
serv_addr.sin_family = AF_INET; |
|
serv_addr.sin_addr.s_addr = INADDR_ANY; |
|
serv_addr.sin_port = htons(port); |
|
assert( bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) >= 0); |
|
listen(sockfd,5); |
|
clilen = sizeof(cli_addr); |
|
nfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); |
|
assert(nfd >= 0); |
|
|
|
FD_ZERO(&set); FD_SET(nfd, &set); |
|
|
|
read(nfd, buf, 1); |
|
|
|
bzero((char *) buf, sizeof(buf)); |
|
|
|
while (1) |
|
{ |
|
// fprintf(stderr, "."); |
|
struct timeval timeout1={.tv_sec=0, .tv_usec=500000}; |
|
if (select(nfd + 1, &set, NULL, NULL, &timeout1) <= 0) emergency_stop(1); |
|
if (read(nfd, buf, 1 ) < 1) emergency_stop(2); |
|
struct timeval timeout2={.tv_sec=0, .tv_usec=500000}; |
|
if (select(nfd + 1, &set, NULL, NULL, &timeout2) <= 0) emergency_stop(3); |
|
if (read(nfd, buf+4, 1 ) < 1) emergency_stop(4); |
|
|
|
gpioWrite(gpioLeftFwd, buf[4] >= 112); |
|
gpioWrite(gpioLeftRew, buf[4] < 112); |
|
gpioWrite(gpioRghtFwd, buf[0] >= 112); |
|
gpioWrite(gpioRghtRew, buf[0] < 112); |
|
gpioPWM(gpioLeftPwm, (buf[4] < 112) ? 255-(255/112.0)*buf[4] : (255/143.0)*buf[4]-255); |
|
gpioPWM(gpioRghtPwm, (buf[0] < 112) ? 255-(255/112.0)*buf[0] : (255/143.0)*buf[0]-255); |
|
} |
|
|
|
gpioTerminate(); |
|
|
|
return 0; |
|
} |