Stuck in opening serial port - c

I have this code for a comunication between pc-arduino with xbee.
The problem is that when I execute this, the program seems to be freezed and doesn't receive nothing from arduino, I don't know why is this happening, but one time the program was showing in the 'terminal' the message that I want to show to see if the communication is happening: 'line:....'
But now isn't communicating.
Are any errors in the code, or why is this happening?
#include <stdio.h> // standard input / output functions
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <termios.h> // POSIX terminal control definitions
#include <math.h>
#define XBEE "/dev/ttyUSB0"
#define BAUDRATE B9600
double average(int data[],int elem);
double desviation(double m, int data[],int elem);
void normalize(double data[],int elem);
void store(double data[],int ex);
int main(int argc,char** argv)
{
struct termios tio;
struct termios stdio;
struct termios old_stdio;
struct termios options;
int data[262142];
int tty_fd = open(XBEE , O_RDWR | O_NOCTTY | O_NDELAY);
again:
cfsetospeed(&tio,BAUDRATE);
cfsetispeed(&tio,BAUDRATE); // baudrate is declarated above
tcsetattr(tty_fd,TCSANOW,&tio);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// write(tty_fd,&c,'1');
char o='o';
char a='a';
FILE *f;
char line[100];
f = fopen("/dev/ttyUSB0", "r+");
while(line[0]!='o'){
fgets(line,10,f);
printf("line: %s\n",line);
}
while(line[0]=='o'){
fputc(a,f);
fgets(line,10,f);
printf("line: %s\n",line);
}
int count=0;
int pos=0;
//----------------------
while(1){
printf("dentro: %c\n",line[0]);
int num;
char number[3];
if(line[0]!=' '){
number[count]=line[0];
if(count>3){
count=0;
}
else{
count=count+1;
}
}
if(line[0]==' '){
count=0;
sscanf(number,"%d",&num);
printf("%d\n",num);
data[pos]=num;
}
if(line[0]=='\n'){
printf("\n\nAll the data have been received");
double av=average(data,262142);
double desv=desviation(av,data,262142);
double data2[262142];
int i;
for (i = 0; i < num; i++)
{
data2[i]=(data[i]-av)/desv;
}
normalize(data2,262142);
char ex;
int aux;
printf("It was steps? y/n\n");
scanf ("%c",&ex);
if(ex=='y'){
aux=1;
}
else{
aux=0;
}
store(data2,aux);
fputc(o,f);
line[0]='0';
while(line[0]!='o'){
fgets(line,10,f);
}
break;
}
write(tty_fd,&o,1);
line[0]='0';
while(line[0]!='o'){
fgets(line,10,f);
}
line[0]='x';
while(line[0]=='x'){
fgets(line,10,f);
}
}
goto again;
close(tty_fd);
tcsetattr(STDOUT_FILENO,TCSANOW,&old_stdio);
return EXIT_SUCCESS;
}
postdata: I can't use the API mode, need to do this on c.
Update
I have done all you have said to me. Still not working, the debugger is stuck in the first fgets (line 30).
#include <stdio.h> // standard input / output functions
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <termios.h> // POSIX terminal control definitions
#include <math.h>
#define XBEE "/dev/ttyUSB0"
#define BAUDRATE B9600
double average(int data[],int elem);
double desviation(double m, int data[],int elem);
void normalize(double data[],int elem);
void store(double data[],int ex);
int main(int argc,char** argv)
{
int data[262142];
char o='o';
char a='a';
char line[100];
FILE *f;
again:
f = fopen("/dev/ttyUSB0", "r+");
if (f == NULL) {
printf("Error opening the port\n");
}
while(line[0]!='o'){
fgets(line,10,f);
printf("line: %s\n",line);
}
while(line[0]=='o'){
fputc(a,f);
fgets(line,10,f);
printf("line: %s\n",line);
}
int count=0;
int pos=0;
//----------------------
while(1){
printf("dentro: %c\n",line[0]);
int num;
char number[3];
if(line[0]!=' '){
number[count]=line[0];
if(count>3){
count=0;
}
else{
count=count+1;
}
}
if(line[0]==' '){
count=0;
sscanf(number,"%d",&num);
printf("%d\n",num);
data[pos]=num;
}
if(line[0]=='\n'){
printf("\n\nAll the data have been received");
double av=average(data,262142);
double desv=desviation(av,data,262142);
double data2[262142];
int i;
for (i = 0; i < num; i++)
{
data2[i]=(data[i]-av)/desv;
}
normalize(data2,262142);
char ex;
int aux;
printf("It was steps? y/n\n");
scanf ("%c",&ex);
if(ex=='y'){
aux=1;
}
else{
aux=0;
}
store(data2,aux);
fputc(o,f);
line[0]='0';
while(line[0]!='o'){
fgets(line,10,f);
}
break;
}
fputc(o,f);
line[0]='0';
while(line[0]!='o'){
fgets(line,10,f);
}
line[0]='x';
while(line[0]=='x'){
fgets(line,10,f);
}
}
goto again;
fclose(f);
return EXIT_SUCCESS;
}
double average(int data[],int elem){
int i=0;
int sum=0;
for (i = 0; i < elem; i++){
sum+=data[i];
}
return sum/elem;
}
double desviation(double m, int data[],int elem){
int i=0;
int j=0;
double dif=0.0;
for (i = 0; i < elem; i++){
dif=pow(data[i]-m,2);
}
return sqrt(dif/(18000-1));
}
void normalize(double data[],int elem){
int i,j;
double biggest;
double lowest;
double aux;
biggest = 0.0;
lowest = 9999999999999999.999;
for (i = 0; i < elem; i++){
if(data[i]>biggest){
biggest=data[i];
}
if(data[i]<lowest){
lowest=data[i];
}
}
if (abs(biggest)>abs(lowest)){
aux=abs(biggest);}
else{
aux=abs(lowest);}
for (i = 0; i < elem; i++){
data[i]=data[i]/aux;
}
}
void store(double data[],int ex){
FILE *out;
out=fopen("training.data","r");
char line[262142];
fgets(line,262142,out);
char *values;
values=strtok(line," ");
int val;
sscanf(&values[0],"%d",&val);
FILE *out2;
out2=fopen("trainingAux.data","w");
fprintf(out2,"%d 262142 1\n",val+1);
while(fgets(line,262142,out)!=NULL){
fprintf(out2,"%s",line);
}
int i = 0;
for(i;i<262141;i++){
fprintf(out2,"%lf ", data[i]);
}
fprintf(out2,"%lf\n", data[i+1]);
fprintf(out2,"%d\n",ex);
fclose(out2);
fclose(out);
out=fopen("training.data","w");
out2=fopen("trainingAux.data","r");
while(fgets(line,262142,out2)!=NULL){
fprintf(out,"%s",line);
}
fclose(out);
fclose(out2);
}

There are some ways to figure out what's happening when communicating via serial.
First of all, why are you using 'fopen' right after using 'open' to the same path (/dev/ttyUSB0)?
When you use a handle to estabilish communication like 'tty_fd' you have to be sure that this handle was created sucessfully, you can try:
if ( (tty_fd = open(XBEE , O_RDWR | O_NOCTTY | O_NDELAY)) == -1 ){
IfTraceAvaliable("Error while opening");
return -1;
}
In addition, you may be trying to set some attributes on termios struct, like:
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
But after it, you aren't applying it to your connection, like:
ioctl(tty_fd, TCSETA, &options);
Remember you can also test ioctl == 0, if its not equal, than it means you couldn't set it properly.
[Edit]
Since you're using open(), you can use read() function to retrieve the answer from arduino, instead of using fgets or fread, that can be an alternative.

Related

Serial monitor implementation segmentation fault

I have made a code to read the serialprint from an Arduino UNO and wish to use that to move the cursor in Linux Ubuntu 17.02. The code runs fine whenever it is run for 1 iteration.
My Arduino will print a code of the format
[0-1],xcord,ycord**
The star is padded so that the string is of length 12
xcord and ycord take values in between 0 and 1023
These values come from a joystick I wish I could be more specific on name or type of said joystick but it is not written on it any where
Moreover I doubt the problem has anything to do with my Arduino side but rather on my c side
Any help will be appreciated
#define _BSD_SOURC
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <string.h>
#include<unistd.h>
struct cord
{
int sw;
int x_axis;
int y_axis;
};
void mouseMove(struct cord s1)
{
Display *displayMain = XOpenDisplay(NULL);
if(displayMain == NULL)
{
fprintf(stderr, "Errore nell'apertura del Display !!!\n");
exit(EXIT_FAILURE);
}
//XWarpPointer(displayMain, None, None, 0, 0, 0, 0, s1.x_axis, s1.y_axis);
XCloseDisplay(displayMain);
}
struct cord decode(char *buffer)
{
struct cord s1;
s1.sw=buffer[0]-'0';
int i=2;
s1.x_axis=0;
s1.y_axis=0;
while(buffer[i]!=',')
{
s1.x_axis=s1.x_axis*10+(buffer[i]-'0');
i++;
}
i++;
while(buffer[i]!='*'||buffer[i]=='\0')
{
s1.y_axis=s1.y_axis*10+(buffer[i]-'0');
i++;
}
s1.x_axis=-s1.x_axis+497;
s1.y_axis=s1.y_axis-497;
//printf("%d %d %d\n",s1.sw,s1.x_axis/50,s1.y_axis/50);
return s1;
}
char* arread(int fd)
{
ssize_t n;
char* buf=(char *)malloc(128*sizeof(char));
n = read(fd, buf, 128);
buf[n]='\0';
//printf("%zd bytes got read...\n", n);
//printf("\n%s\n", buf);
return buf;
}
int main()
{
int fd;
char *portname = "/dev/ttyACM1";
if((fd = open(portname, O_RDWR | O_NOCTTY))==-1)
{
close(fd);
printf("error in opening Port");
}
else
{
struct termios toptions;
if(tcgetattr(fd, &toptions)==0)
{
if(cfsetispeed(&toptions, B9600)==0)
{
if(cfsetospeed(&toptions, B9600)==0)
{
toptions.c_cflag &= (unsigned int)~PARENB;
toptions.c_cflag &= (unsigned int)~CSTOPB;
toptions.c_cflag &= (unsigned int)~CSIZE;
toptions.c_cflag |= (unsigned int)CS8;
toptions.c_cflag &= (unsigned int)~CRTSCTS;
toptions.c_cflag |= (unsigned int)CREAD | (unsigned int)CLOCAL;
toptions.c_iflag &= (unsigned int)~(IXON | IXOFF | IXANY);
toptions.c_lflag &= (unsigned int)~(ICANON | ECHO | ECHOE | ISIG);
toptions.c_oflag &= (unsigned int)~OPOST;
toptions.c_cc[VMIN] = 12;
toptions.c_cc[VTIME] = 0;
if(tcsetattr(fd, TCSANOW, &toptions)==0)
{
//int i=0;
//while(i<5)
//{
mouseMove(decode(arread(fd)));
//i++;
//}
}
else
printf("error 4");
}
else
printf("error 3");
}
else printf("error 2");
}
else
printf("error 1");
}
}
This is the updated code i no longer get the error of segmentation fault however i keep on getting junk values as output . Also i dont know how it is printing as i blocked every printf that could do it.
For the value of the buffer this is the arduino code I used
const int SW_pin = 2; // digital pin connected to switch output
const int X_pin = 5; // analog pin connected to X output
const int Y_pin = 4; // analog pin connected to Y output
char buffer[12];
int x,n;
void setup()
{
pinMode(SW_pin, INPUT);
digitalWrite(SW_pin, HIGH);
Serial.begin(9600);
}
void loop()
{
n=sprintf(buffer,"%d,%d,%d",digitalRead(SW_pin),analogRead(X_pin),analogRead(Y_pin));
for(x=n;x<12;x++)
buffer[x]='*';
buffer[12]='\0';
Serial.println(buffer);
delay(500);
}
Finally the code worked thanks a lot to #user3629249
#define _BSD_SOURC
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <string.h>
#include<unistd.h>
struct cord
{
int sw;
int x_axis;
int y_axis;
};
void mouseMove(struct cord* s1)
{
Display *displayMain = XOpenDisplay(NULL);
if(displayMain == NULL)
{
fprintf(stderr, "Errore nell'apertura del Display !!!\n");
exit(EXIT_FAILURE);
}
//XWarpPointer(displayMain, None, None, 0, 0, 0, 0, s1.x_axis, s1.y_axis);
XCloseDisplay(displayMain);
}
struct cord* decode(char *buffer)
{
struct cord* s1 = malloc(sizeof(struct cord));
s1->sw=0;
s1->x_axis=0;
s1->y_axis=0;
if(strcmp(buffer,"error")!=1)
{
s1->sw=buffer[0]-'0';
int i=2;
while(buffer[i]!=',')
{
s1->x_axis=s1->x_axis*10+(buffer[i]-'0');
i++;
}
i++;
while(buffer[i]!='*'||buffer[i]=='\0')
{
s1->y_axis=s1->y_axis*10+(buffer[i]-'0');
i++;
}
s1->x_axis=-s1->x_axis+497;
s1->y_axis=s1->y_axis-497;
//printf("%d %d %d\n",s1.sw,s1.x_axis/50,s1.y_axis/50);
}
return s1;
}
char* arread(int fd)
{
ssize_t n,n1;
char* buf=(char *)malloc(128*sizeof(char));
char*ch=(char *)malloc(sizeof(char));
while(ch[0]!='\n')
{
n1=read(fd,ch,1);
}
n = read(fd, buf, 12);
buf[n]='\0';
printf("\n%zd\n", n);
printf("%s\n", buf);
if(n>0)
{
return buf;
}
else
{
printf("error");
return "error";
}
int main()
{
int fd;
char *portname = "/dev/ttyACM0";
fd = open(portname, O_RDWR | O_NOCTTY);
if(fd==-1)
{
close(fd);
printf("erip");
}
else
{
struct termios toptions;
if(tcgetattr(fd, &toptions)==0)
{
if(cfsetispeed(&toptions, B9600)==0)
{
if(cfsetospeed(&toptions, B9600)==0)
{
toptions.c_cflag &= (unsigned int)~PARENB;
toptions.c_cflag &= (unsigned int)~CSTOPB;
toptions.c_cflag &= (unsigned int)~CSIZE;
toptions.c_cflag |= (unsigned int)CS8;
toptions.c_cflag &= (unsigned int)~CRTSCTS;
toptions.c_cflag |= (unsigned int)CREAD | (unsigned int)CLOCAL;
toptions.c_iflag &= (unsigned int)~(IXON | IXOFF | IXANY);
toptions.c_lflag &= (unsigned int)~(ICANON | ECHO | ECHOE | ISIG);
toptions.c_oflag &= (unsigned int)~OPOST;
toptions.c_cc[VMIN] = 12;
toptions.c_cc[VTIME] = 0;
if(tcsetattr(fd, TCSANOW, &toptions)==0)
{
//int i=0;
//while(i<5)
//{
mouseMove(decode(arread(fd)));
//i++;
//}
}
else
printf("error 4");
}
else
printf("error 3");
}
else printf("error 2");
}
else
printf("error 1");
}
}
In the end the part that was causing all the errors was the read function. I originally used carelessly without thinking what the serial monitor is actually printing right now and so i got junk values . However after a ch searching for a '\n' it worked like a charm

Reading GPS data from Serial Port Ubuntu

I'm trying to read the GPS data from a serial port, at the moment i can read the data. But im trying to get only the data from "$GPRMC" line only.
I have this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/ioctl.h>
int main(int argc, char** argv) {
int sfd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
if (sfd == -1) {
printf("Error no is : %d\n", errno);
printf("Error description is : %s\n", strerror(errno));
return (-1);
};
struct termios options;
tcgetattr(sfd, &options);
cfsetspeed(&options, B9600);
cfmakeraw(&options);
//options.c_cc[VTIME]=1;
//options.c_cc[VMIN]=100;
//tcflush(sfd, TCIFLUSH);
tcsetattr(sfd, TCSANOW, &options);
usleep(100000);
char serialBuffer[500];
int bytes;
int count;
ioctl(sfd, FIONREAD, &bytes);
int i =0;
char *ret;
char *sepa;
char sepa2[500];
int compare;
for(;;){
if(bytes!=0){
count = read(sfd, serialBuffer, sizeof(serialBuffer));
}
if (count == -1){
printf("ERROR");
break;
}
else if(count == 0){
printf("NODATA");
break;
}
else{
serialBuffer[count] = '\0';
//strcpy(serialBuffer2, serialBuffer);
//printf("%s,", serialBuffer);
sepa = strtok(serialBuffer, "\n");
while(sepa != NULL){
//printf("%s", sepa);
//strcpy(serialBuffer2, sepa);
sepa = strtok(NULL, "\n");
ret = strstr(sepa, "$GPRMC");
if (NULL != ret) {
printf("The substring is: %s\n", ret);
}
}
}
}
close(sfd);
return (EXIT_SUCCESS);
}
This script is always returning me "Segmentation Faul(Core Dumped)", and i dont know why. Im new at c, can any one help me on this?
Thanks

I got a big trouble with BeagleboneBlack Uart

My beagleboneblack(let's call it "BBB") run 3.8.13-bone47, and I have been haunted by a bug for 2 weeks.
My problem is :when my BBB gets a string,my BBB will send the same string to another terminal.
For example:My laptop with a Uart2USB bridge sent a string "asd",then BBB will got "asd".But meanwhile, BBB would send "asd" to my laptop.And all of Uart module on BBB(Uart1,Uart2,Uart4) did the same thing.
By the way,I tried to avoid this bug by using two Uart(one for TX,another one for RX).Fortunately,I did it,but I still want to know the reason and the solution.
Here is my Uart.c,Uart.h and test.c:
/*====================Uart.c================*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/time.h>
#include <string.h>
#include "Uart.h"
#define TRUE 1
#define FALSE -1
int fd_uart;
void set_speed(void)
{
int i;
int status;
int speed_arr = B38400;
struct termios Opt;
tcgetattr(fd_uart,&Opt);
tcflush(fd_uart, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr);
cfsetospeed(&Opt, speed_arr);
status = tcsetattr(fd_uart, TCSANOW, &Opt);
if(status != 0)
perror("tcsetattr fd1");
}
int set_Parity(void)
{
struct termios options;
if( tcgetattr( fd_uart,&options)!= 0)
{
perror("SetupSerial 1");
return(FALSE);
}
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_iflag &= ~INPCK; /* Enable parity checking */
options.c_iflag &= ~(ICRNL|IGNCR);
options.c_lflag &= ~(ICANON );
options.c_cflag &= ~CSTOPB;
options.c_iflag |= INPCK;
options.c_cc[VTIME] = 150; // 15 seconds
options.c_cc[VMIN] = 0;
tcflush(fd_uart,TCIFLUSH); /* Update the options and do it NOW */
if(tcsetattr(fd_uart,TCSANOW,&options) != 0)
{
perror("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
void initUart(int argc, char **argv)
{
char devname_head[10] = "/dev/";
char dev_name[20];
if(argc < 2)
{
printf("Please input './test_uart ttyOx'\n");
exit(1);
} else {
strcpy(dev_name, devname_head);
strcat(dev_name, argv[1]);
fd_uart = open(dev_name, O_RDWR);
if(fd_uart < 0)
{
perror("error to open /dev/ttyOx\n");
exit(1);
} else if (fd_uart == 0) {
printf("Can't Open Serial Port!\n");
exit(0);
} else {
//Setup
set_speed(); //baud:38400
if (set_Parity() == FALSE) //8,1,n
{
printf("Set Parity Error\n");
exit(1);
}
}
}
}
void writeUartString(char *buf)
{
if ( write(fd_uart,buf,strlen(buf)) < 0)
{
printf("write error\n");
}
}
void writeUartMsg(char *buf,int num)
{
if ( write(fd_uart,buf,num) < 0)
{
printf("write error\n");
}
}
int readUart(char *buf)
{
int num = 0, i = 0;
num = read(fd_uart,buf,sizeof(buf));
if(num < 0){
printf("read error\n");
}
return num;
}
void closeUart(void)
{
close(fd_uart);
}
/*======================================================*/
/*==================Uart.h===================*/
#ifndef UART_H
#define UART_H
void set_speed(void);
int set_Parity(void);
void initUart(int argc, char **argv);
void writeUartString(char *buf);
void writeUartMsg(char *buf,int num);
void closeUart(void);
extern int fd_uart;
#endif
/*=======================================*/
/*================test.c=================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Uart.h"
int main(int argc, char **argv)
{
int i = 0,temp = 0;
char buf[64] = {0};
initUart(argc,argv);
while(1){
writeUartString("waiting\n");
printf("waiting\n");
memset(buf,0,64);
temp = readUart(buf);
printf("readUart's return value = %d\n",temp);
if (temp > 0){
printf("get something\n");
printf("%s\n",buf);
}
sleep(1);
}
return 0;
}
/*====================================*/
Did somebody get this situation too?
You left echoing enableed with
options.c_lflag &= ~(ICANON );
Change it, at least, to
options.c_lflag &= ~(ICANON | ECHO );
With you are left at their original state all flags, rather then except that ICANON.

Low Level IO with Crypt

I am trying to compare a encrypted string that is taken from each line of a file to AAAA-ZZZZ until it finds its match of the password. I am guaranteed that the user password is of 4 characters. What I am trying to do is take in the file using LowLevel IO and output to a new file with the decrypted passwords of each line. I am not the best at C programming yet so please be gentle. I need direction on how to create an array or list going from AAAA all the way to ZZZZ and then comparing each to the decrypted version of the file line.
How to decrypt the file line by line and save it to a char []
How to compare each line to another char [] until password is found
For Example:
if the line is $1$6gMKIopE$I.zkP2EvrXHDmApzYoV.B. and the next line is $1$pkMKIcvE$WQfqzTNmcQr7fqsNq7K2p0. Assuming the resulting password after decryption is ABSZ and TAZE the new file will result it ABSZ on the first line and TAZE for the second line.
This is what I have so far:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void pdie(const char *);
void die(const char *);
#define BUFFER_SIZE 1024
int main(void)
{
char *pass;
int rfd;
int wfd;
char buffer[BUFFER_SIZE];
char *bp;
int bufferChars;
int writtenChars;
if ((rfd = open("pass.txt", O_RDONLY, 0)) < 0)
pdie("Open failed");
if ((wfd = open("passout.txt", O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0)
pdie("Open failed");
while (1)
{
if ((bufferChars = read(rfd, buffer, BUFFER_SIZE)) > 0)
{
printf("%s", buffer);
bp = buffer;
pass = crypt(getpass(all(4,4,'a','z')), *bp);
printf(pass);
while (bufferChars > 0)
{
if ((writtenChars = write(wfd, bp, bufferChars)) < 0)
pdie("Write failed");
bufferChars -= writtenChars;
bp += writtenChars;
}
}
else if (bufferChars == 0)
break;
else
pdie("Read failed");
}
close(rfd);
close(wfd);
return 0;
}
void pdie(const char *mesg) {
perror(mesg);
exit(1);
}
void die(const char *mesg) {
fputs(mesg, stderr);
fputc('\n', stderr);
exit(1);
}
int inc(char *c,char begin, char end){
if(c[0]==0) return 0;
if(c[0] == end){ // This make the algorithm to stop at char 'f'
c[0]=begin; // but you can put any other char
return inc(c+sizeof(char), begin, end);
}
c[0]++;
return 1;
}
int all(int a, int n,char begin, char end){
int i,j;
char *c = malloc((n+1)*sizeof(char));
for(i=a;i<=n;i++){
for(j=0;j<i;j++) c[j]=begin;
c[i]=0;
do {
printf("%s\n",c);
} while(inc(c,begin,end));
}
free(c);
}
here is the file:
$1$6gMKIopE$I.zkP2EvrXHDmApzYoV.B.
$1$pkMKIcvE$WQfqzTNmcQr7fqsNq7K2p0
$1$0lMKIuvE$7mOnlu6RZ/cUFRBidK7PK.

non blocking "Key pressed" test in C

I'm looking for a pretty simple thing:
I want to test if a key was pressed. any key.
If not, the program should continue its business.
So it must be a "non blocking" call.
I guess this question is probably equivalent to checking if the keyboard buffer has anything into it.
I guess such a function must exist in C for that, but I can't quite find it yet. All standard functions I find are "blocking" type, waiting for a key to be pressed before answering.
Note - I'm planning to use it for a Windows console program.
In windows you can use '_kbhit()' in conio.h
It is a non-standard function and may not be available on other platforms.
I know this is a bit old but here is some Linux code that works
kbhit.h:
#ifndef KBHIT_H__
#define KBHIT_H__
void init_keyboard(void);
void close_keyboard(void);
int kbhit(void);
int readch(void);
#endif
kbhit.c:
#include "kbhit.h"
#include <termios.h>
#include <unistd.h> // for read()
static struct termios initial_settings, new_settings;
static int peek_character = -1;
void init_keyboard(void)
{
tcgetattr(0,&initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new_settings);
}
void close_keyboard(void)
{
tcsetattr(0, TCSANOW, &initial_settings);
}
int kbhit(void)
{
unsigned char ch;
int nread;
if (peek_character != -1) return 1;
new_settings.c_cc[VMIN]=0;
tcsetattr(0, TCSANOW, &new_settings);
nread = read(0,&ch,1);
new_settings.c_cc[VMIN]=1;
tcsetattr(0, TCSANOW, &new_settings);
if(nread == 1)
{
peek_character = ch;
return 1;
}
return 0;
}
int readch(void)
{
char ch;
if(peek_character != -1)
{
ch = peek_character;
peek_character = -1;
return ch;
}
read(0,&ch,1);
return ch;
}
main.c:
#include "kbhit.h"
#define Esc 27
int main(void)
{
init_keyboard(); // for kbhit usage
do {
if(kbhit())
{
ch = tolower(readch());
if(ch == Esc || ch == 'q') break;
if(ch=='s') GetNewTimerValue(TIMER_1);
if(ch=='f') GetNewTimerValue(TIMER_2);
if(ch=='l') {rotateFields();}
}
usleep(330000);
} while(1);
close_keyboard();
return 0;
}

Resources