I am wanting to write a C program to work with my eZ430 Chronos watch, which uses a COM port. I got some help the other night from Jonimus, Tari, and (sorry) my brain forgets who else. Anyways, I remember Kerm saying that he already had code that did most of this (working with them in general), so I figured I would post here so he would post it Smile For what it's worth, here is the code that I was able to get, but it doesn't work right now.
Code:
#include <stdio.h>
#include <termios.h>
#include <unistd.h>

FILE* OpenPort( void );

int main(int argc, char* argv[]) {
   char startAccessPoint[] = { 'B', 0xFF, 0x07, 0x03 };
   char accDataRequest[] = { 'B', 0xFF, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00 };
   char recvBuf[10];
   int length;
   struct termios options;
   FILE* ser = OpenPort();
   int fd = fileno(ser);
      printf("Port opened\n");
   fwrite(startAccessPoint, 1, 4, ser); // Start access point
      printf("Access point started\n");
   
   // Set options
   tcgetattr(fd, &options);
   cfsetispeed(&options, B115200);
   cfsetospeed(&options, B115200);
      printf("Settings... set\n");
   while( 1 ) {
         printf("in while(1) loop\n");
      fwrite(accDataRequest, 1, 8, ser); // Request data
      length = fread(recvBuf, 1, 7, ser);
         printf("x:%d y:%d z:%d\n",recvBuf[2], recvBuf[1], recvBuf[0]); // x:128 y:64 z:200
         printf("\tdatatype:%d\n",recvBuf[3]); // datatype:2
   }
   
   fclose(ser);
   return 0;
}

FILE* OpenPort( void ) {
   FILE* fp; // File descriptor
   
   fp = fopen("/dev/ttyACM0", "r+b");
   if( fp < 0 ) {
      perror("Could not open port");
   } else {
      //fcntl(fp, F_SETFL, 0);
   }
   
   return fp;
}
Most of the data was taken from various websites, I'll try to find them all:
http://chemicaloliver.net/arduino/graphing-ti-ez430-chronos-watch-data-in-linux/ (Copy paste)
http://pastebin.com/fde255fd (from 1)
http://www.easysw.com/~mike/serial/serial.html (Which I switched from, but most of the code was taken from examples there)

Edit: chemicaLOLiver got caught in the filter Razz
_player1537 wrote:

Code:
   // Set options
   tcgetattr(fd, &options);
   cfsetispeed(&options, B115200);
   cfsetospeed(&options, B115200);
      printf("Settings... set\n");

Wrong comments are worse than no comments. You never actually set the baud rate on the hardware, just in your termios struct.

(possibly) fixed:

Code:
    tcgetattr(fd, &options);
    cfsetispeed(&options, B115200);
    cfsetospeed(&options, B115200);
    tcsetattr(fd, TCSANOW, &options);


You should also fix your tabs. I can tell what was copy/pasted from the varying indentation levels and styles (some <tab> characters, some spaces). Not a huge issue, but it's annoying when trying to read the code.
Unfortunately, that still doesn't seem to work for me, though I see why I should have set the options after editing them. Also, regarding the tabs, those were for my reading purposes because it was getting hard for me to read between the printf functions I was using for debugging. I'm probably still going to play with the styling for printf() functions because I'd probably just use them as debugging statements for now. And for the comments, is this any better?
Code:
   tcgetattr(fd, &options); // Get termios struct
   cfsetispeed(&options, B115200); // Set baud rate (input)
   cfsetospeed(&options, B115200); // Set baud rate (output)
   tcsetattr(fd, TCSANOW, &options); // Set termios struct for port
Better, but a bit verbose. With the new call to tcsetattr, the old one-line comment was fine. It was just bad because you claimed to set it but didn't actually.
First, are you running this on Windows or Linux? Under Windows, there are some annoying things you need to do to properly configure the serial port. Assuming it's Linux, then we save a lot of trouble. I'm very concerned that you don't set parity and stop bits anywhere, only bitrate, and you don't bother with flow control toggling at all.
Under Linux, that's why I am using /dev/ttyXXX. Would you mind explaining why I would need to set parity and stop bits, and how I would do so?
_player1537 wrote:
Under Linux, that's why I am using /dev/ttyXXX. Would you mind explaining why I would need to set parity and stop bits, and how I would do so?
Good point about the /dev/ttyXXX stuff; I should have spotted that myself. Smile As a random example, here's some code extracted from the gCnClient source code:


Code:
      tcgetattr(hSerial,&oldtio); /* save current serial port settings */
      bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
      newtio.c_cflag = B115200 | CS8 | CLOCAL | CREAD ;//|CRTSCTS;// |
      newtio.c_iflag = ~(IGNBRK | BRKINT | ICRNL | INLCR | ISTRIP | IXON);
      newtio.c_oflag = ~(OCRNL | ONLCR | ONLRET | ONOCR | OFILL |
                     OPOST);
      newtio.c_lflag = ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
      newtio.c_cc[VMIN] = 0;
      newtio.c_cc[VTIME] = 0;
      cfsetispeed(&newtio,B115200);
      cfsetospeed(&newtio, B115200);
      tcflush(hSerial, TCIFLUSH);
      tcsetattr(hSerial,TCSANOW,&newtio);
This page will blow your mind: http://pubs.opengroup.org/onlinepubs/007908799/xbd/termios.html

(OK, it probably won't, but it goes into a LOT of detail about how the tty/termios stuff works)

The parity and stop bits stuff is all controlled by the c_cflag member of struct termios (so modify options.c_cflag to set or clear options). See the section titled "Control Modes" in that page above.

To set parity I would do something like this:

Code:

  options.c_cflag |= PARENB; // parity enable
  options.c_cflag |= PARODD; // odd parity
  options.c_cflag &= ~PARODD; // even parity (only this one or the previous one)


To set two stop bits, do something like this:

Code:

  options.c_cflag |= CSTOPB; // set two stop bits
  options.c_cflag &= ~CSTOPB; // set one stop bit


Of course, you'll have to figure out what set of serial control modes your device needs to communicate with the computer. The default control modes might work fine, which means you don't have to set or clear any of them.

EDIT: Kerm replied while I was writing this post. You can also follow his example code, which combines control modes into one line.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement