https://www.elektroda.pl/rtvforum/topic3214509.html
dobre:
W miarę sprawdzony jest STN1110 (zwany przez nich ELM327 v2) od Viaken
Na Beagle Bone Black obsugiwany przez RS
na BBB pdf
obsuga RS232 w linux C
http://xanthium.in/Serial-Port-Programming-on-Linux
sprawdzanie który tty to RS:
$ dmesg | grep tty
ELM
ELM327 instaluje się w Linuksie jako RS323
/dev/ttyUSB#
Emulacja podłączonego ELM w linuxie
$ apt-get install obdgpslogger
uruchom:
$ obdsim
mozna to odczytać:
$ screen /dev/ttyUSB# 38400 (albo bez prędkości)
$ screen /dev/pts/1 (dla emulacji obdsim)
instalacja screen
sudo apt install screen
polecenia po nawiązaniu komunikacji:
>AT L1 # enable line feed
OK
> AT I # information
ELM327 v1.4
>AT @1 # device description
OBDII to RS232 Interpreter
> AT DP # current protocol
AUTO
> AT RV # car is obviously not connected, no voltage on OBDII port
0.0V
lista polecen AT:
https://www.elmelectronics.com/wp-content/uploads/2016/07/AT_Command_Table.pdf
http://www.obdtester.com/elm-usb-commands
>0100
41 FF ...
lista polecen OBDII PIDS
https://en.wikipedia.org/wiki/OBD-II_PIDs
https://python-obd.readthedocs.io/en/latest/Command%20Tables/
Kod
Działający przykład oparty o komunikację z RS232, odczytujący z emulowanego OBD
przeliczający zwrocone wartosci hex na int.
#include <stdio.h> #include <fcntl.h> /* File Control Definitions */ #include <termios.h> /* POSIX Terminal Control Definitions */ #include <unistd.h> /* UNIX Standard Definitions */ #include <errno.h> /* ERROR Number Definitions */ #include <stdlib.h> //strtol do zamiany char na hex void main(void) { /*------------------------------- Ask for data to write to serial port ------------------*/ printf("Podaj kod PID 4 cyfry np 0100: "); char tempp[6]; fgets(tempp,6,stdin); printf("\n"); tempp[4]='\n'; tempp[5]='\0'; int fd;/*File Descriptor*/ printf("\n +----------------------------------+"); printf("\n | Serial Port read & write |"); printf("\n +----------------------------------+"); /*------------------------------- Opening the Serial Port -------------------------------*/ /* Change /dev/ttyUSB0 to the one corresponding to your system */ fd = open("/dev/pts/1",O_RDWR | O_NOCTTY | O_SYNC); /* ttyUSB0 is the FT232 based USB2SERIAL Converter */ /* O_RDWR - Read/Write access to serial port */ /* O_NOCTTY - No terminal will control the process */ /* bez 3 parametru (read) - Open in blocking mode,read will wait */ //write dodany 3 parametr(o_sync byl probnie dodany przezemnie) /* O_NDELAY -Non Blocking Mode,Does not care about- */ /* -the status of DCD line,Open() returns immediatly */ if(fd == -1) /* Error Checking */ printf("\n Error! in Opening tty "); else printf("\n tty Opened Successfully "); /*---------- Setting the Attributes of the serial port using termios structure --------- */ struct termios SerialPortSettings; /* Create the structure */ tcgetattr(fd, &SerialPortSettings); /* Get the current attributes of the Serial port */ /* Setting the Baud rate */ cfsetispeed(&SerialPortSettings,B38400); /* Set Read Speed */ cfsetospeed(&SerialPortSettings,B38400); /* Set Write Speed */ /* 8N1 Mode */ SerialPortSettings.c_cflag &= ~PARENB; /* Disables the Parity Enable bit(PARENB),So No Parity */ SerialPortSettings.c_cflag &= ~CSTOPB; /* CSTOPB = 2 Stop bits,here it is cleared so 1 Stop bit */ SerialPortSettings.c_cflag &= ~CSIZE; /* Clears the mask for setting the data size */ SerialPortSettings.c_cflag |= CS8; /* Set the data bits = 8 */ SerialPortSettings.c_cflag &= ~CRTSCTS; /* No Hardware flow Control */ SerialPortSettings.c_cflag |= CREAD | CLOCAL; /* Enable receiver,Ignore Modem Control lines */ SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY); /* Disable XON/XOFF flow control both i/p and o/p */ SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* Non Cannonical mode */ SerialPortSettings.c_oflag &= ~OPOST;/*No Output Processing*/ /* Setting Time outs no Blocking for writing*/ SerialPortSettings.c_cc[VMIN] = 1; /* nr signs to Read */ SerialPortSettings.c_cc[VTIME] = 1; // 0.1 seconds read timeout if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0) /* Set the attributes to the termios structure*/ printf("\n ERROR ! in Setting attributes"); else printf("\n BaudRate = 38400 \n StopBits = 1 \n Parity = none"); /*------------------------------- Write data to serial port -----------------------------*/ char write_buffer[6]; for(int i=0;i<6;i++) //="0100\n"; /* Buffer containing characters to write into port */ write_buffer[i]=tempp[i]; int bytes_written = 0; /* Value for storing the number of bytes written to the port */ bytes_written = write(fd,write_buffer,sizeof(write_buffer)-1);/* use write() to send data to port */ printf("\n %s written to tty",write_buffer); printf("\n %d Bytes written to tty", bytes_written); printf("\n +----------------------------------+\n\n"); //usleep (1); // sleep enough to transmit the 4 plus // receive 15: approx 100 uS per char transmit tcdrain(fd); //delay for output /*------------------------------- Read data from serial port -----------------------------*/ /* Setting Time outs - Blocking for reading*/ // SerialPortSettings.c_cc[VMIN] = 10; // Read at least 10 characters // SerialPortSettings.c_cc[VTIME] = 0; // Wait indefinetly //if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0) // Set the attributes to the termios structure // printf("\n ERROR ! in Setting attributes"); //else // printf("\n BaudRate = 38400 \n StopBits = 1 \n Parity = none"); tcflush(fd, TCIFLUSH); /* Discards old data in the rx buffer */ char read_buffer[20]; /* Buffer to store the data received */ int bytes_read = 0; /* Number of bytes read by the read() system call */ int licz=3; do{ char read_buf[20]; /* Buffer to store the data received */ int bytes_r = 0; /* Number of bytes read by the read() system call */ bytes_r = read(fd,&read_buf,19); /* Read the data */ //printf("\n Bytes Rxed przed pt %d:", bytes_r); /* Print the number of bytes read */ for(int i=0;i<bytes_r;i++) /*printing only the received characters*/ { // printf("%c",read_buf[i]); read_buffer[i]=read_buf[i]; } bytes_read=bytes_r; }while(licz--); printf("\n Bytes Rxed za petla %d:\n ", bytes_read); /* Print the number of bytes read */ for(int i=0;i<bytes_read;i++) /*printing only the received characters*/ printf("%c",read_buffer[i]); read_buffer[bytes_read]='\0'; printf(" "); char A[3]; A[0]=read_buffer[0]; A[1]=read_buffer[1]; A[2]='\0'; int a=(int)strtol(A,NULL,16); printf("pierwsza =: %d\n",a); printf("\n +----------------------------------+\n\n\n"); close(fd); /* Close the serial port */ }
korzystanie z libftdi
https://codeseekah.com/2012/02/22/elm327-to-rs232-in-linux/
instalacja biblioteki do kodu
sudo apt-get install libftdi libftdi-dev
sprawdzanie:
apt-cache policy libffi-dev
mozna dodac:
sudo apt-get install build-essential
dokumentacja dla libftdi
https://www.intra2net.com/en/developer/libftdi/documentation/group__libftdi.html
kod (nie działa):
#include <stdio.h> #include <ftdi.h> #include <string.h> int main(int argc, char * argv[]) { struct ftdi_context ftdic; /* FTDI context */ /* line properties */ enum ftdi_bits_type bits = BITS_8; // 8 data bits enum ftdi_stopbits_type sbit = STOP_BIT_1; // 1 stop bit enum ftdi_parity_type parity = NONE; // no parity enum ftdi_break_type lineend = BREAK_OFF; int ret; unsigned short modem_status = 0; unsigned char * tx; unsigned char * rx; int i,j; /* general purpose indices */ if ((tx = malloc(128)) == NULL || (rx = malloc(128)) == NULL) { fprintf(stderr, "Error: could not allocate memory\n"); return EXIT_FAILURE; } if (ftdi_init(&ftdic) < 0) { fprintf(stderr, "Error: could not initialize FTDI\n"); return EXIT_FAILURE; } if ((ret = ftdi_usb_open(&ftdic, 0x0403, 0x6001)) < 0) { fprintf(stderr, "unable to open ftdi device: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); return EXIT_FAILURE; } if ((ret = ftdi_usb_reset(&ftdic)) < 0) { fprintf(stderr, "unable to reset ftdi device: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); return EXIT_FAILURE; } if ((ret = ftdi_usb_purge_buffers(&ftdic)) < 0) { fprintf(stderr, "unable to purge buffers on ftdi device: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); return EXIT_FAILURE; } if ((ret = ftdi_set_baudrate(&ftdic, 38400)) < 0) { fprintf(stderr, "unable to set ftdi device baud rate: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); return EXIT_FAILURE; } if ((ret = ftdi_set_line_property2(&ftdic, bits, sbit, parity, lineend)) < 0) { fprintf(stderr, "unable to set ftdi device properties: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); return EXIT_FAILURE; } ftdi_poll_modem_status(&ftdic, &modem_status); printf("R232 status: 0x%x\n", modem_status); memcpy(tx, "AT E0\r", 6); /* turn echoing off */ if (ftdi_write_data(&ftdic, tx, sizeof(unsigned char) * 6) < 0) { fprintf(stderr, "unable to send ftdi device data: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); return EXIT_FAILURE; } while (1) { j = 0; while ( ( ret = getchar() ) != 0x0a && j < 128) tx[j++] = ret; if (!j) continue; tx[j++] = 0x0d; /* end */ ret = 0; ftdi_usb_purge_tx_buffer(&ftdic); ftdi_usb_purge_rx_buffer(&ftdic); for (i = 0; i < j; i++) { ret += ftdi_write_data(&ftdic, tx+i, sizeof(unsigned char) * 1); } printf("Written %d bytes of data: ", ret); for (i = 0; i < ret; i++) printf("0x%x ", tx[i]); printf("\n"); while (1) { ret = ftdi_read_data(&ftdic, rx, 128); if (ret > 0) { printf("Read %d bytes of data\n", ret); ret -= 3; /* remove > prompt */ printf("\tDATA: "); for (i = 0; i < ret; i++) printf("0x%x ",rx[i]); printf("\n\t("); for (i = 0; i < ret; i++) printf("%c",rx[i]); printf(")\n"); break; } else if (ret < 0) { fprintf(stderr, "unable to read from ftdi device: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); return EXIT_FAILURE; } } } if ((ret = ftdi_usb_close(&ftdic)) < 0) { fprintf(stderr, "unable to close ftdi device: %d (%s)\n", ret, ftdi_get_error_string(&ftdic)); return EXIT_FAILURE; } ftdi_deinit(&ftdic); free(tx); free(rx); return EXIT_SUCCESS; }
kompilowanie:
gcc -Wall -ggdb -lftdi kodelm327toRS.c -o obd