简体   繁体   English

使用C在linux中读取arduino串行

[英]Reading arduino serial in linux using C

I want to read serial from arduino.我想从 arduino 读取串行。 I use this code :我使用这个代码:

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <sys/ioctl.h>
int main(){
    char data[1024];
    char dev[] = "/dev/ttyACM1";
    int fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY);
    fcntl(fd, F_SETFL, FNDELAY);
    struct termios options;
    tcgetattr(fd, &options);
    cfsetispeed(&options, B9600);
    cfsetospeed(&options, B9600);
    options.c_cflag |= CS8;
    options.c_cflag |= CS8;
    options.c_cflag &= ~CRTSCTS;
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    tcsetattr(fd, TCSANOW, &options);
    ioctl(fd, TCFLSH, 2);
    while(1){
        read(fd, data, sizeof(data));
        printf(data);
    }
    //write(fd, data, sizeof(data));
}

My arduino runs very simple sketch :我的 arduino 运行非常简单的草图:

int x; 
void setup() {
  Serial.begin(9600);
}
void loop() {
  Serial.println("DO YOU HEAR ME ??");
  delay(1000);
}

and output of this combinatin is that :这个组合的输出是:

??OU HEAR ME ??
DO YOU HEAR ME ??
DO YOU HEAR ME ??
A¹­þ
??OU HEAR ME ??
DO YOU HEAR ME ??
DO YOU HEAR ME ??
A¹­þ
??OU HEAR ME ??
DO YOU HEAR ME ??
DO YOU HEAR ME ??

My question is how to make order out of chaos.我的问题是如何从混乱中恢复秩序。 I found that this issue occurs when buffer ends and new one begins(bigger buffer less junk data) but I can't have a infinite buffer.我发现当缓冲区结束并开始新的缓冲区时会出现此问题(更大的缓冲区减少垃圾数据),但我不能拥有无限缓冲区。 Also there is a lot of junk when it reads for the first time.. Is there a way to sync it or something ?第一次读取时也有很多垃圾..有没有办法同步它或其他什么?

(Also I am not native English sorry for any mistakes.) (另外,我不是英语母语,如有任何错误,请见谅。)

I found answer to my own problem.我找到了我自己问题的答案。 I used this time c++ to organize it in class (very poor one because it doesn't handle any errors and doesn't use c++ in the most..) Here is the code :这次我用 c++ 在课堂上组织它(非常糟糕,因为它不处理任何错误,并且在大多数情况下不使用 c++。)这是代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>

#include <cstring>
#include <iostream>
//Here I define some vars 
#define BAUDRATE B9600
#define MODEMDEVICE "/dev/ttyACM0"
#define _POSIX_SOURCE 1

class serial{
public:
serial(){
    fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
    if (fd <0) {perror(MODEMDEVICE); exit(-1); } 
    // Improvement No. 1 I save old setting and clean the new one 
    tcgetattr(fd,&oldtio);
    bzero(&newtio, sizeof(newtio));

    // Here I set all the flags to vars at once
    newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
    newtio.c_iflag = IGNPAR | ICRNL;
    newtio.c_oflag = 0;
    newtio.c_lflag = ICANON;
    //here I set some new flags..
    newtio.c_cc[VINTR]    = 0;     /* Ctrl-c */
    newtio.c_cc[VQUIT]    = 0;     /* Ctrl-\ */
    newtio.c_cc[VERASE]   = 0;     /* del */
    newtio.c_cc[VKILL]    = 0;     /* @ */
    newtio.c_cc[VEOF]     = 4;     /* Ctrl-d */
    newtio.c_cc[VTIME]    = 0;     /* inter-character timer unused */
    newtio.c_cc[VMIN]     = 1;     /* blocking read until 1 character  arrives */
    newtio.c_cc[VSWTC]    = 0;     /* '\0' */
    newtio.c_cc[VSTART]   = 0;     /* Ctrl-q */
    newtio.c_cc[VSTOP]    = 0;     /* Ctrl-s */
    newtio.c_cc[VSUSP]    = 0;     /* Ctrl-z */
    newtio.c_cc[VEOL]     = 0;     /* '\0' */
    newtio.c_cc[VREPRINT] = 0;     /* Ctrl-r */
    newtio.c_cc[VDISCARD] = 0;     /* Ctrl-u */
    newtio.c_cc[VWERASE]  = 0;     /* Ctrl-w */
    newtio.c_cc[VLNEXT]   = 0;     /* Ctrl-v */
    newtio.c_cc[VEOL2]    = 0;     /* '\0' */
    // and I finally save the settings 
    tcflush(fd, TCIFLUSH);
    tcsetattr(fd,TCSANOW,&newtio);
}
~serial(){
    close(fd);
}

    std::string sread(){
        res = read(fd,buf,255);
        buf[res]=0;
        return buf;
    }
    void swrite(const char* input){
        write(fd,input,std::strlen(input));
    }
private:
    int fd,c,res;
    struct termios oldtio,newtio;
    char buf[255];
};


int main(){
    serial s;
    s.swrite("Light");
    std::string buf = s.sread();
    std::cout << buf;
}

This is more of a ripoff from "Serial programming HOW TO" : http://tldp.org/HOWTO/Serial-Programming-HOWTO/ (form the example code..)这更像是“串行编程HOW TO”的剽窃: http : //tldp.org/HOWTO/Serial-Programming-HOWTO/ (形成示例代码..)

And here is the new poor arduino code :这是新的糟糕的 arduino 代码:

int x; 
String buff;
int lpin = A0;
int tpin = A1;
int data;
void setup() {
  Serial.begin(9600);
  pinMode(lpin,INPUT);
  pinMode(tpin,INPUT);
}
void loop() {
  if(Serial.available() == 1)
  {
    buff = Serial.readString();
    if(buff == "Light"){
      data = analogRead(lpin);
      Serial.print(data);
      Serial.print("\n");
    }else if(buff == "Temp"){
      data = analogRead(tpin);
      Serial.print(data);
      Serial.print("\n");
    }else{
      Serial.print("Something went wrong !");
      Serial.print("\n");
    }
  }
  delay(1);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM