uart to send data host pc receive display is not the same

Dear all, I use tx1 development board uart, send “ char buf [10] = {0,1,2,3,4,5,6,7,8,9} ”, but the host of the serial display " FD FB F9 F7 F5 F3 F1 EF ED 00 "
1 fd = open("/dev/ttyS0",O_RDWR | O_NOCTTY)
2 baud rate :9600 8N1
3 write(fd,buf,sizeof(buf))
why?

Which physical connector are you using? Have you verified the baud rate is correct and matching at both sides of the UART? Are you using hardware (CTS/RTS) flow control? How long are the wires…are these discrete wires or shielded cable? If discrete wires, are they twisted pair or parallel?

Regardless of those above answers one suggestion on testing is to use loopback. Most of the time you have two serial ports which need to match each other…and serial ports are not capable of being queried…only their drivers can be queried. So you can make all kinds of settings and not know it failed even if the driver cooperated (drivers send settings to UARTs…UARTs don’t always inform drivers of success or failure, it is a blind assumption). When you use loopback you limit the problem to a single UART without the requirement of success on two UARTs at once.

For loopback you would tie the TX and RX pins of a single UART together…the UART is essentially talking to itself. For flow control you can also tie CTS and RTS together if using hardware flow control, but this may just complicate the purpose of loopback testing.

When in loopback a serial console program (e.g., minicom, gtkterm) will allow you to type on the keyboard…if it echos back, then you have a valid setting. If no echo occurs, or if the echo is corrupt, then you know your serial console program does not use the settings the port is using. In some cases your serial console program may be able to actually adjust UART mode (versus settings the serial console program is assuming), but mostly you just want to find a setting which works, and then test your program with those settings. Find a setting which works, alter your program as needed for those settings…validate those settings match at each side of the serial port connection (both Jetson and host or program).

If you are using the serial port on connector J17 you should know it is electrically routed to the camera module as well, so for that connector you may want to remove the camera during any testing. This particular port is by default 3.3V (TTL) logic level as well, so a 1.8V cable will not work (at least it won’t work correctly), and higher voltages may actually cause damage.

use jetson tx1 for J21(pin8,pin9,pin10).no hardware flow control,use DuPont line。now the baudrate is 115200。
The procedure is as follows:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<termios.h>
#include<string.h>

int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
struct termios newtio,oldtio;
if ( tcgetattr( fd,&oldtio) != 0) {
perror(“SetupSerial 1”);
return -1;
}
bzero( &newtio, sizeof( newtio ) );
newtio.c_cflag |= CLOCAL | CREAD;
newtio.c_cflag &= ~CSIZE;
switch( nBits )
{
case 7:
newtio.c_cflag |= CS7;
break;
case 8:
newtio.c_cflag |= CS8;
break;
}

 switch( nEvent )
 {
 case 'O':
  newtio.c_cflag |= PARENB; 
  newtio.c_cflag |= PARODD;  
  newtio.c_iflag |= (INPCK | ISTRIP); 
  break;
 case 'E':
  newtio.c_iflag |= (INPCK | ISTRIP);
  newtio.c_cflag |= PARENB;
  newtio.c_cflag &= ~PARODD;
  break;
 case 'N':
  newtio.c_cflag &= ~PARENB;
  break;
 }

 switch( nSpeed )
 {
 case 2400:
  cfsetispeed(&newtio, B2400);
  cfsetospeed(&newtio, B2400);
  break;
 case 4800:
  cfsetispeed(&newtio, B4800);
  cfsetospeed(&newtio, B4800);
  break;
 case 9600:
  cfsetispeed(&newtio, B9600);
  cfsetospeed(&newtio, B9600);
  break;
 case 115200:
  cfsetispeed(&newtio, B115200);
  cfsetospeed(&newtio, B115200);
  break;
 case 460800:
  cfsetispeed(&newtio, B460800);
  cfsetospeed(&newtio, B460800);
  break;
 default:
  cfsetispeed(&newtio, B9600);
  cfsetospeed(&newtio, B9600);
  break;
 }

 if( nStop == 1 )
  newtio.c_cflag &=  ~CSTOPB; 
 else if ( nStop == 2 )
 newtio.c_cflag |=  CSTOPB;

 newtio.c_cc[VTIME]  = 0; 
 newtio.c_cc[VMIN] = 0; 
 tcflush(fd,TCIFLUSH); 
 if((tcsetattr(fd,TCSANOW,&newtio))!=0) 
 {
  perror("com set error");
  return -1;
 }
 printf("set done!\n\r");
 return 0;

}

int main(void)
{
int fd1,nset,ret;
//int nread;
//char buf[100]={“test com data!..\n”};
char buf[10]={0,1,2,3,4,5,6,7,8,9};
//char buf1[10];
fd1 = open( “/dev/ttyS0”, O_RDWR | O_NOCTTY);
if (fd1 == -1){
printf(“no such /dev/ttyS0 exist\n”);
exit(1);
}

 printf("open  ttyS0 success!!\n");
 nset = set_opt(fd1, 115200, 8, 'N', 1);
 if (nset == -1)
  exit(1);
printf("SET  ttyS0 success!!\n");
 printf("enter the loop!!\n");

 while (1)

 {
  // memset(buf1, 0, sizeof(buf1));
   ret = write(fd1, buf, 10);
   if( ret > 0){
      printf("write success!  wait data receive\n");
   }
/*
nread = read(fd1, buf1, 10);
if(nread > 0){
 printf("redatad: nread = %s\n\n\r", buf1);
}

*/
   sleep(1);
 }

close(fd1);

return 0;
}

J21 pins are set up as serial console. Whatever you send is essentially going to a console, and what you get back is what the console does to repond to that. U-Boot and the Linux kernel do normally have this set to 115200 8N1. Are you trying to use this as something other than serial console?

thank you,I have solved the problem.i would like to ask how i will start the qt procedures automatically start the program.

The unity desktop has an autostart feature (as do most Linux desktops) if you want to start something upon GUI login. There are also several ways to automatically start a non-GUI program regardless of login. If you want to start a GUI program without a user login, then it gets complicated. What are your requirements, and what is an example use-case of how you see the application starting up?

No GUI is only serial output data program built with qt, I can open the tx1 through the host of the serial terminal to see the output data to know whether the program has started. ------ boot automatically start the serial output data program, has been sending data.The purpose is to boot automatically run this program, do not have to do anything。

This would probably be simplest by adding as a bash script line in “/etc/rc.local”. If the program must run as a particular user you might start it with “/usr/bin/sudo -u <some_user_name> <some_program_name>” (otherwise just add the program name there by full path).