简体   繁体   中英

Reading arduino serial in linux using C

I want to read serial from 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 :

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 :

#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..)

And here is the new poor arduino code :

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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