title: Sending files over serial port
body: <p>I need some help sending a file over a serial connection. I have two RS232 to USB cables, and I am testing out my code by using one to send data, and the other to receive it. I have them both physically connected to each other.</p>
  
  <p>So I wrote some code adapted from a few sources, and I can successfully transfer a series of characters. One program receives the data, the other sends it. I have these two open in two separate terminals. Find the two blocks of code below:</p>
  
  <p><strong>serialout.c</strong></p>
  
  <pre><code>#include &lt;stdio.h&gt;   /* Standard input/output definitions */
  #include &lt;string.h&gt;  /* String function definitions */
  #include &lt;unistd.h&gt;  /* UNIX standard function definitions */
  #include &lt;fcntl.h&gt;   /* File control definitions */
  #include &lt;errno.h&gt;   /* Error number definitions */
  #include &lt;termios.h&gt; /* POSIX terminal control definitions */
  
  int main()
      {
              //writing
              int writeport = open_port("/dev/ttyUSB0");
  
              char str[] = "hello how are you?";
              int n = write(writeport, str, strlen(str));
              if (n &lt; 0)
                      fputs("write() of bytes failed!\n", stderr);
  
              //closing ports
              close(writeport);
      }
  
      int open_port(char str[])
  {
      int fd = open(str, O_RDWR | O_NOCTTY | O_NONBLOCK); // ?? NDELAY or NONBLOCK?
  
    if (fd == -1)
    {
                      perror("open_port: Unable to open /dev/ttyS0 - ");
    }
    else
                      fcntl(fd, F_SETFL, 0);
  
        struct termios options;
        tcgetattr(fd, &amp;options); //this gets the current options set for the port
  
        // setting the options
  
        cfsetispeed(&amp;options, B9600); //input baudrate
        cfsetospeed(&amp;options, B9600); // output baudrate
        options.c_cflag |= (CLOCAL | CREAD); // ?? enable receicer and set local mode
        //options.c_cflag &amp;= ~CSIZE; /* mask the character size bits */
        options.c_cflag |= CS8;    /* select 8 data bits */
        options.c_lflag &amp;= ~(ICANON | ECHO | ECHOE | ISIG); // choosing raw input
        options.c_iflag &amp;= ~INPCK; // disable parity check
        options.c_iflag &amp;= ~(IXON | IXOFF | IXANY); // disable software flow control
        options.c_oflag |= OPOST; // ?? choosing processed output
        options.c_cc[VMIN] = 0; // Wait until x bytes read (blocks!)
        options.c_cc[VTIME] = 0; // Wait x * 0.1s for input (unblocks!)
  
        // settings for no parity bit
        options.c_cflag &amp;= ~PARENB;
        options.c_cflag &amp;= ~CSTOPB;
        options.c_cflag &amp;= ~CSIZE;
        options.c_cflag |= CS8;
  
        tcsetattr(fd, TCSANOW, &amp;options); //set the new options ... TCSANOW specifies all option changes to occur immediately
  
    return (fd);
  }
  </code></pre>
  
  <p><strong>serialin.c</strong></p>
  
  <pre><code>#include &lt;stdio.h&gt;   /* Standard input/output definitions */
  #include &lt;string.h&gt;  /* String function definitions */
  #include &lt;unistd.h&gt;  /* UNIX standard function definitions */
  #include &lt;fcntl.h&gt;   /* File control definitions */
  #include &lt;errno.h&gt;   /* Error number definitions */
  #include &lt;termios.h&gt; /* POSIX terminal control definitions */
  
  int main()
  {
      //reading   
      int readport = open_port("/dev/ttyUSB1");
  
      //trying to read one character at a time
      char buff;
      int n = 1;
  
     while (n &gt; 0)
     {
      n = read(readport, &amp;buff, 1);
      printf("%c", buff, buff);
     }
  
      printf("\n");
  
      //closing ports
      close(readport);
  }
  
  int open_port(char str[])
  {
      int fd = open(str, O_RDWR | O_NOCTTY | O_NONBLOCK); // ?? NDELAY or NONBLOCK?
  
    if (fd == -1)
    {
          perror("open_port: Unable to open /dev/ttyS0 - ");
    }
    else
          fcntl(fd, F_SETFL, 0);
  
    struct termios options;
    tcgetattr(fd, &amp;options); //this gets the current options set for the port
  
    // setting the options
  
    cfsetispeed(&amp;options, B9600); //input baudrate
    cfsetospeed(&amp;options, B9600); // output baudrate
    options.c_cflag |= (CLOCAL | CREAD); // ?? enable receicer and set local mode
    //options.c_cflag &amp;= ~CSIZE; /* mask the character size bits */
    options.c_cflag |= CS8;    /* select 8 data bits */
    options.c_lflag &amp;= ~(ICANON | ECHO | ECHOE | ISIG); // choosing raw input
    options.c_iflag &amp;= ~INPCK; // disable parity check
    options.c_iflag &amp;= ~(IXON | IXOFF | IXANY); // disable software flow control
    options.c_oflag |= OPOST; // ?? choosing processed output
    options.c_cc[VMIN] = 0; // Wait until x bytes read (blocks!)
    options.c_cc[VTIME] = 0; // Wait x * 0.1s for input (unblocks!)
  
    // settings for no parity bit
    options.c_cflag &amp;= ~PARENB;
    options.c_cflag &amp;= ~CSTOPB;
    options.c_cflag &amp;= ~CSIZE;
    options.c_cflag |= CS8;
  
    tcsetattr(fd, TCSANOW, &amp;options); //set the new options ... TCSANOW specifies all option changes to occur immediately
  
    return (fd);
  }
  </code></pre>
  
  <p>So what I'd like to do is send a file. For example, a jpeg file. Is there some way to convert it to bytecode and reassemble it as a jpeg? I have searched around but have found little relevant information unfortunately - maybe I'm searching the wrong terms.</p>
  
  <p>Even better would be to send the files after they are zipped. Ultimately, I am using gzip to zip jpeg files, then send them over the serial connection. Thanks everyone!</p>