Имам USB към сериен адаптер, свързан към /dev/ttyUSB0
, който се свързва към ротационен етап. Мога да комуникирам с този етап на ротация, като просто изпратя ASCII команди през серийния порт. т.е. да поискате текущата позиция на този етап на въртене просто:
- в прозорец 1:
echo -e "1tp\r" > /dev/ttyUSB
- в прозорец 2:
cat /dev/ttyUSB
, който връща текущата позиция: "1TP-0.00000"
Сега искам да мога да правя точно това при определен тригер в C програма.
Прегледах този удивителен архив и намерих няколко примера за това как може да се направи. Например
- как да отваряте, четете и пишете от сериен порт порт в C
- Четене/запис на сериен порт на Linux C
- Тест за обратна връзка/дуплекс на сериен порт, в Bash или ° С? (замяна на процес)
Така че въз основа на тях написах този много грозен код, за да опитам просто да напиша "1tp\r" на серийния порт и след това да прочета върнатата стойност (позицията на етапа на въртене) обратно. Ето кода по-долу.
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
int main(int argc, char *argv[])
{
char line[1024];
int chkin;
int chkout;
char input[1024];
char msg[1024];
char serport[24];
// argv[1] - serial port
sprintf(serport, "%s", argv[1]);
int file= open(serport, O_RDWR | O_NOCTTY | O_NDELAY);
printf("file descriptor: %d\n",file);
if (file == 0)
{
sprintf(msg, "open_port: Unable to open %s.\n", serport);
perror(msg);
}
else
fcntl(file, F_SETFL, FNDELAY); //fcntl(file, F_SETFL, 0);
while (1)
{
usleep (1000000);
// printf("enter input data:\n");
//scanf("%s",&input[0]);
// printf("You entered %s\n",&input);
//input= "1tp\r";
chkin = write(file,"1tp\r",5);
printf("chkin: %d\n",chkin);
if (chkin<0)
{
printf("cannot write to port\n");
}
fcntl(file, F_SETFL, FNDELAY);
//chkin=read(file,line,sizeof line);
usleep (100000);
//while ((chkin=read(file,line,sizeof line))>=0)
//printf("chkin: %d\n",chkin);
chkout = read(file, line ,sizeof line);
//{
if (chkout<0)
{
printf("cannot read from port\n");
}
else
{
printf("bytes: %d, line=%s\n",chkout, line);
}
//}
/*CODE TO EXIT THE LOOP GOES HERE*/
if (input[0] == 'q') break;
}
close(file);
return 0;
}
Е, не става. Когато го стартирам като: ./sertest /dev/ttyUSB0
, просто получавам грешката "cannot read from port"
. В действителност проблемът изглежда е, че низът "1tp\r"
не изглежда да се записва на серийния порт. Освен това, след като приключа с това, настройките на серийния порт изглежда са объркани, защото изобщо не мога да комуникирам със сцената чрез прости терминални команди и трябва да нулирам серийния порт с помощта на minicom.
Трябва също да отбележа, че знам, че мога успешно да прочета нещо от серийния порт с втората част от този код, защото успях да изпратя низа "1tp\r"
с терминална команда и просто прочетох изхода на етапа със съответния кодов фрагмент в примера по-долу.
И така, ще оценя някои приноси за това как успешно да напиша този прост низ "1tp\r"
(или подобен) на серийния порт и да го заменя с четене на серийния порт.
Не съм програмист, така че се извинявам предварително за лошия стил на частта от код тук.
\r
е един знак, въпреки че изглежда като два. По-конкретно\r
е връщане на каретка, шестнадесетична стойност 0x0D. - person user3386109   schedule 22.07.2015echo
може да добавя безвъзмезден символ за подаване на ред в края на съобщението. Ако случаят е такъв, кодът трябва да изпраща"1tp\r\n"
, което всъщност е 5 знака. - person user3386109   schedule 22.07.2015perror
веднага след извикването наwrite
, за да ви даде по-точна индикация каква е грешката. - person kaylum   schedule 22.07.2015errno
. Проверихте ли дали имате разрешение за писане? - person Iharob Al Asimi   schedule 22.07.2015perror()
опитайте товаfprintf(stderr, "error(%d): %s\n", errno, strerror(errno));
. вместо това трябва да включитеerrno.h
- person Iharob Al Asimi   schedule 22.07.2015