1 2 Previous Next 15 Replies Latest reply on May 3, 2016 4:44 AM by andsto

    Serial problem with edison

    freshbirdtww

      can anyone give a example about edison's serial programming(in yocto)?i can't receive the data from ttyMFD1.

        • 2. Re: Serial problem with edison
          freshbirdtww

          Thx for your help,but i try the method mentiond by https://communities.intel.com/message/255427?_ga=1.193552685.1687049730.1416555854#255427 but it can't work either.

          can you test my code?thx.

          #include<stdio.h>

          #include<fcntl.h>

          #include<errno.h>

          #include<unistd.h>

          #include<termios.h>

          #include<sys/select.h>

          #define BAUDRATE 115200

          #define DEVICE "/dev/ttyMFD1"

          int serial_read(int fd, char *str, unsigned int len, unsigned int timeout)

          {

              fd_set rfds;

              struct timeval tv;

              int ret;               

              int sret;             

              int readlen = 0;    

              char *ptr;

           

              ptr = str;           

           

              FD_ZERO(&rfds);        

              FD_SET(fd, &rfds);    

           

           

              tv.tv_sec = timeout / 1000;

              tv.tv_usec = (timeout % 1000) * 1000;

           

           

              while(readlen < len)

              {

                  sret = select(fd + 1, &rfds, NULL, NULL, &tv);

           

                  if(sret == -1)

                  {

                      perror("select:");

                      break;

                  }

                  else if(sret > 0)

                  {

                      ret = read(fd, ptr, 1);

                      printf("sec: %d, usec: %d\n", tv.tv_sec, tv.tv_usec);

                      if(ret <= -1)

                      {

                          perror("read err:");

                          break;

                      }

           

                      else if(ret == 0)

                      {

                          break;

                      }

           

                      readlen += ret;

                      ptr += ret;

                  }

                  else

                  {

                      printf("timeout! \n");

                      break;

                  }

           

              }

           

              return readlen;

          }

           

          /* OpenPort:Open Serial port1

          * Return the file descriptor on success or -1 on error

          *

          */

          int OpenPort(void)

          {

              int fd;

           

              fd = open(DEVICE, O_RDWR | O_NOCTTY | O_NDELAY);

              if(fd == -1)

              {

                  printf("OpenPort:Unable to open /dev/ttyMFD1");

              }

              else

              {

                  fcntl(fd, F_SETFL, 0);

                  return (fd);

              }

          }

          int main(int argc, char **argv)

          {

              int fd;

              struct termios oldtio, newtio;

              char buf[100] = {};

           

               fd = OpenPort();

               tcgetattr(fd, &oldtio);

               bzero(&newtio, sizeof(newtio));

              

               newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;

               newtio.c_iflag = IGNPAR | ICRNL;

               newtio.c_oflag = 0;

               newtio.c_lflag = ICANON;

               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' */

           

               tcflush(fd, TCIFLUSH);

               tcsetattr(fd, TCSANOW, &newtio);

           

              int n = serial_read(fd, buf, 1, 3000);

           

              //int n = read(fd, buf, 2);

              if(n < 0)

              {

                  fputs("read error", stderr);

              }

              printf("%s\n",buf);

          }

          • 3. Re: Serial problem with edison
            deium

            Unfortunately, due to personal deadlines this week, I can not test at the moment.  I shouldn't comment without testing the code.

            David_J_Hunt's procedure is needed to initialize the pinmodes/directions before ttyMFD1 usage.

            • 4. Re: Serial problem with edison
              freshbirdtww

              thx for your attention,i will try it again.and if you have time to test the code,it's grateful.

              • 5. Re: Serial problem with edison
                DiegoV_Intel

                Hi freshbirdtww,

                 

                I will try to test the Serial communication. As soon as I get some results I will post them here. Also I will post them in the other thread you started: How to receive data from 0RX?.

                 

                Regards,

                Diego.

                • 6. Re: Serial problem with edison
                  DiegoV_Intel

                  Hi freshbirdtww,

                   

                  I've just post my reply to your other thread: Re: How to receive data from 0RX? . I will re-write the reply here too:

                   

                  I have tested the serial communication using the Edison and an Arduino UNO, and I was able to send and received data. The serial port for the pins 0 and 1 in the Arduno Expansion Board is /dev/ttyMFD1, which is the Serial Port 1 in the Edison. Check this thread for more details about the other Serial Ports of Edison: Using Serialx on Edison.

                   

                  To start transmitting, you have to setup the required gpio pins and the baudrate. For the baudrate, I used 9600. You can check what is the current baudrate of the /dev/ttyMFD1 port with the following command in Linux terminal:

                   

                  stty -F /dev/ttyMFD1 -a
                  

                   

                  And you can modify the baudrate with the following command:

                   

                  stty -F /dev/ttyMFD1 9600  # Replace "9600" with the baudrate you need
                  

                   

                  Then, for setting up the gpio pins required for send and received data with the /dev/ttyMFD1 port, run the following commands in Linux terminal:

                   

                  # TRI_STATE_ALL buffer
                  echo -n "214" > /sys/class/gpio/export
                  # Pin 0 - Rx
                  echo -n "130" > /sys/class/gpio/export # rx (input)
                  echo -n "248" > /sys/class/gpio/export # output enable
                  echo -n "216" > /sys/class/gpio/export # pullup enable
                  #Pin 1 - TX
                  echo -n "131" > /sys/class/gpio/export # tx (output)
                  echo -n "249" > /sys/class/gpio/export # output enable
                  echo -n "217" > /sys/class/gpio/export # pullup enable
                  
                  echo low > /sys/class/gpio/gpio214/direction # Set the TRI_STATE_ALL to low before doing any changes
                  
                  echo low > /sys/class/gpio/gpio248/direction
                  echo in > /sys/class/gpio/gpio216/direction
                  
                  echo mode1 > /sys/kernel/debug/gpio_debug/gpio130/current_pinmux # mode1 is used to set the UART interface in Edison
                  echo in > /sys/class/gpio/gpio130/direction
                  
                  echo high > /sys/class/gpio/gpio249/direction
                  echo in > /sys/class/gpio/gpio217/direction
                  
                  echo mode1 > /sys/kernel/debug/gpio_debug/gpio131/current_pinmux # mode1 is used to set the UART interface in Edison
                  echo out > /sys/class/gpio/gpio131/direction
                  
                  echo high > /sys/class/gpio/gpio214/direction # Set the TRI_STATE_ALL to high after the changes are applied
                  

                   

                  And that's it. Now in order to send data through the port use the following command:

                   

                  echo [data] > /dev/ttyMFD1 # Replace "[data]" with the data you want to send
                  

                   

                  And for display the data received use the following command:

                   

                  cat /dev/ttyMFD1
                  

                   

                  One important thing is that the data sent is in ASCII code, so if you want to send the letter "a" for example, you will receive the number "97 " which correspond to the letter "a" in ASCII code. I hope this be useful for you.

                   

                  Regards,

                  Diego.

                  • 7. Re: Serial problem with edison
                    Nicobari

                    Hi DiegoV_Intel

                    I am trying to setup Intel Edison Serial in C++ code as follows

                     

                    mraa::Uart* GPSserial = new mraa::Uart("/dev/ttyMFD1");
                    
                    if (GPSserial == NULL || GPSserial->setBaudRate(115200) != MRAA_SUCCESS
                                || GPSserial->setMode(8, MRAA_UART_PARITY_NONE, 1) != MRAA_SUCCESS
                                || GPSserial->setFlowcontrol(false, false) != MRAA_SUCCESS) {
                    
                            std::cout<<"Error while setting up UART1"<<std::endl;
                    }
                    
                    
                        }
                    
                    
                    

                     

                    When I ran the code, it seems like

                    GPSserial ->setMode(8, MRAA_UART_PARITY_NONE, 1)

                    is returning 5 which is and I double checked that GPSserial is not NULL

                    MRAA_ERROR_INVALID_HANDLE

                     

                    I then followed your advice and when I tried doing

                     

                    echo -n "214" > /sys/class/gpio/export
                    
                    

                     

                    I got

                    sh: echo: write error: No such device
                    
                    

                     

                    and other commands give me device busy error. Do you have any Idea what might be wrong?

                     

                    Thanks,

                    TM

                    • 8. Re: Serial problem with edison
                      kalot

                      hi,

                      i followed you serial setup cmd code and wrote them in  a bash file ,but when i run the .sh file it output some messages like

                      "./init.sh: line[some line number]: echo: write error: Device or resource busy". Did you know what wrong with it? Thx.

                      • 9. Re: Serial problem with edison
                        DiegoV_Intel

                        Hello,

                         

                        Nicobari: The message "sh: echo: write error: No such device" you see when you try to export the gpio214 is because you are not using the Arduino Expansion Board. The gpio214 is a tri-state buffer that should be LOW prior to make any change in the muxes, but it is only available in the Arduino Expansion Board. If you are using the Mini-Breakout Board you will get the error message above because there is no such a tri-state buffer in it. You can skip that line and continue with the rest of the configuration.

                         

                        kalot and Nicobari: The message about "Device or resource busy" appears when you try to export a gpio that is already exported. There is no problem there; the gpio is already exported so if you get that message you can ignore it and continue with the next commands.

                         

                        Regards,

                        Diego.

                        • 10. Re: Serial problem with edison
                          arfoll

                          Use mraa::Uart(0) and not the device path. Using the device path causes a raw access to be made so no uart initialisation will be done. Using the numbered syntax will cause a full initialisation to be done by mraa. Also make sure you're on the latest git master HEAD as uart code is very new which is why it hasn't made it to the official releases yet.

                          • 11. Re: Serial problem with edison
                            kalot

                            hi, arfoll

                                 i have downloaded the mraa and build  it. But, how can i use it on my code .  It's wrong when i compile the test code.

                                 The code copied from mraa test folder is:

                            #include "stdio.h"

                            //! [Interesting]

                            #include "mraa.h"

                             

                             

                            int

                            main(int argc, char** argv)

                            {

                                mraa_uart_context uart;

                                uart = mraa_uart_init(0);

                             

                             

                                if (uart == NULL) {

                                    fprintf(stdout, "UART failed to setup\n");

                                }

                             

                             

                                mraa_deinit();

                                return 0;

                            }

                             

                            and then i used " gcc -o serialtest serialtest.c" but, it go error.

                            The error msg is:

                            serialtest.c:(.text+0x11): undefined reference to `mraa_uart_init'

                            serialtest.c:(.text+0x46): undefined reference to `mraa_deinit'

                             

                            it means that my code can't find the library.

                             

                            so, what should i do more next when i have built the library mraa on my edison so that i can use the api directly?

                            thx.

                            • 12. Re: Serial problem with edison
                              arfoll

                              You need to tell the linker to link against mraa, it's a dynamic library. Use:

                               

                              gcc -o serialtest serialtest.c -lmraa


                              Ideally you'd use pkg-config to find the linker flags something like

                              gcc -o mybinary mysource `pkg-config --libs mraa`g


                              If you compiled your own version make sure that it's been installed in /usr not /usr/local which is the default. The docs in docs/building.md should provide you with all the necessary info.

                              • 13. Re: Serial problem with edison
                                kalot

                                Thanks for you answer arfoll. i add the option "-lmraa" and it compiled successfully. But, we i run the binary file, i get the wrong message "libmraa.so.0: cannot open shared object file: No such file or directory".  How can i handle with  it? thx.

                                • 14. Re: Serial problem with edison
                                  arfoll

                                  That's odd if your linker can find mraa whilst compiling it should do the same at runtime... can you post the output of the following?

                                   

                                  ldd mybinary

                                  ls -l /usr/lib | grep mraa

                                  opkg files libmraa0

                                   

                                  Did you compile your own version of mraa?

                                  1 2 Previous Next