dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: code for UART comm from Pi to Arduino hangs up

Sat Jun 08, 2019 11:10 am

AFAIK the Arduino code is fail-safe now, because Serial.readStringUntil() now covers all timeouts and buffers.
what would be the failsafe Raspi code?
Until now, it still always hangs up after a couple of seconds, either with or without extra Raspi timeouts.

(code updated for debug reasons,
i0 now is incremented in each Arduino loop
and i2 is now incremented in each Raspi loop)

Arduino code:

Code: Select all

// Arduino Serial to Raspi USB

// history:
// 0705  debug value (i2) from Raspi
// 0704  Serial.readStringUntil(), debug value (i0) from Arduino
// 0703  simple msg str 
// 0702  fixes
// 0701  Serial.read delimiters
// 0700   
// 0101  ported for RPi USB
//
// 0009  
// 0008  analog aX=analogRead(AX) (X=0...11), syntax "&AX=%ld",aX
// 0007  pin-loop, 6x out-pins OUTn(I/O/pwm), &_ALLPINS_=0 when BCB-close
// 0006  output pins DPINn
// 0003  send/receive strings
// 0002  receiving strings, pattern: &varname1=value1;
// 0001  receiving simple Serial char 

// ver 0705

const uint32_t UARTclock = 115200;

int32_t i0=0,i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0,i8=0,i9=0;          // int (general)



String  inputString="";

#define TOKLEN 30
#define MSGLEN 1024
char    mbuf[MSGLEN];  // cstring msg buffer
char    cval[TOKLEN];  // number as cstring


//==================================================================
// string tools
//==================================================================

int16_t  strstrpos(const char * haystack, const char * needle)   // find 1st occurance of substr in str
{
   const char *p = strstr(haystack, needle);
   if (p) return static_cast<int16_t>(p-haystack);
   return -1;   // Not found = -1.
}


char * cstringarg( const char* haystack, const char* vname, char* sarg ) {
   int i=0, pos=-1;
   unsigned char  ch=0xff;
   const char*  kini = "&";       // start of varname: '&'
   const char*  kin2 = "?";       // start of varname: '?'
   const char*  kequ = "=";       // end of varname, start of argument: '='
   
   const int    NLEN=30;
   char  needle[NLEN] = "";       // complete pattern:  &varname=abc1234


   strcpy(sarg,"");
   strcpy(needle, kini);
   strcat(needle, vname);
   strcat(needle, kequ);
   pos = strstrpos(haystack, needle); 
   if(pos==-1) {
      needle[0]=kin2[0];
      pos = strstrpos(haystack, needle);
      if(pos==-1) return sarg;
   }
   pos=pos+strlen(vname)+2; // start of value = kini+vname+kequ   
   while( (ch!='&')&&(ch!='\0') ) {
      ch=haystack[pos+i];    
      if( (ch=='&')||(ch==';')||(ch=='\0') ||(ch=='\n')
        ||(i+pos>=(int)strlen(haystack))||(i>NLEN-2) ) {
           sarg[i]='\0';
           return sarg;
      }       
      if( (ch!='&') ) {
          sarg[i]=ch;          
          i++;       
      }      
   } 
   return sarg;
}


//==================================================================
// setup
//==================================================================
void setup() {
  Serial.begin(UARTclock);
  
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  
  i0=0;
  i1=1;
  i2=-22;
  i3=33;
  i4=-444;
  i5=5555;
  i6= (uint16_t)B10101010*256;
  i6+=(uint16_t)B10101010;

}


//==================================================================
// loop
//==================================================================

void loop() {

  //-------------------------------------------------------------
  // receive
  
  int  n=0;
  char inChar;     

  if(Serial.available()) {  
       inputString=Serial.readStringUntil('\n');    
       inputString.toCharArray(mbuf, min( (int)inputString.length(), MSGLEN-1) );     
  }
    
  //----------------------
  // process mbuf!

  // debug: check for changed i2 by Raspi
  cstringarg(mbuf, "i2", cval); //    
  if(strlen(cval)>0) {          
     i2=(int32_t)atol(cval);
  }
    

  //----------------------    
  inputString="";

  //delay 
  delay(1);
  

  
  //-------------------------------------------------------------
  // send  
  
  //Serial.flush();  // debug: not needed
  
  char formatstr[MSGLEN];
  strcpy(formatstr, "§");
  strcat(formatstr, "&i0=%ld;&i1=%ld;&i2=%ld;&i3=%ld;&i4=%ld;&i5=%ld;&i6=%ld;\n");  
  sprintf(mbuf, formatstr, i0,i1,i2,i3,i4,i5,i6 );      
             
  //for (int i=0; i<strlen(mbuf); i++ ) Serial.print(mbuf[i]);   
  Serial.print(mbuf);     // <~~~~~~~~~~~~~~~ makes no difference if sent byte by byte or in a whole
  
  Serial.flush();         // <~~~~~~~~~~~~~~~ edit: is also not solving that issue!
   
   //delay?
  delay(1);
    
  i0++;

  
}

Raspi code: e.g.

Code: Select all


/*
   UART communication
   send/receive string of tokens
   *     
   Raspberry Pi  master
   ver 0702
 */
 
 /*
  * change log
  * 0702: debug value (i2) from Raspi
  * 0701: Serial Read delimiter, debug value (i0) from Arduino
  * 0700: first adjustments
  * 0669: UART 115200 baud  * 
  * 0667: Arduino via USB = ACM0
  * 
  */


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <math.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <stdint.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include <pthread.h>


#include <wiringPi.h>
#include <wiringSerial.h>

#define  byte  uint8_t

char   uart[128]  =  "/dev/ttyACM0";
int    Serial;
const  uint32_t UARTclock = 115200;

int32_t i0=0,i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0,i8=0,i9=0;          // int (general)
//int32_t i0,i1,i2,i3,i4,i5,i6,i7,i8,i9;     


#define TOKLEN 30
#define MSGLEN 1024
#define iINVALID -29999


std::string  inputString="";
char   cval[TOKLEN];  // number as cstring
char   mbuf[MSGLEN];  // cstring msg buffer






//==================================================================
// string tools
//==================================================================


int16_t  strstrpos(const char * haystack, const char * needle)   // find 1st occurance of substr in str
{
   const char *p = strstr(haystack, needle);
   if (p) return static_cast<int16_t>(p-haystack);
   return -1;   // Not found = -1.
}


char * cstringarg( const char* haystack, const char* vname, char* sarg ) {
   int i=0, pos=-1;
   unsigned char  ch=0xff;
   const char*  kini = "&";       // start of varname: '&'
   const char*  kin2 = "?";       // start of varname: '?'
   const char*  kequ = "=";       // end of varname, start of argument: '='
   
   const int    NLEN=30;
   char  needle[NLEN] = "";       // complete pattern:  &varname=abc1234


   strcpy(sarg,"");
   strcpy(needle, kini);
   strcat(needle, vname);
   strcat(needle, kequ);
   pos = strstrpos(haystack, needle); 
   if(pos==-1) {
      needle[0]=kin2[0];
      pos = strstrpos(haystack, needle);
      if(pos==-1) return sarg;
   }
   pos=pos+strlen(vname)+2; // start of value = kini+vname+kequ   
   while( (ch!='&')&&(ch!='\0') ) {
      ch=haystack[pos+i];    
      if( (ch=='&')||(ch==';')||(ch=='\0') ||(ch=='\n')
        ||(i+pos>=(int)strlen(haystack))||(i>NLEN-2) ) {
           sarg[i]='\0';
           return sarg;
      }       
      if( (ch!='&') ) {
          sarg[i]=ch;          
          i++;       
      }      
   } 
   return sarg;
}



//==================================================================
// serial TCP
//==================================================================


void loop() {
    
  while(1) {  
      
     static bool stringComplete = false;
     
     
     //-------------------------------------------------------------
     // send    
     
     // debug
     i2++;  // change value to send back to Arduino
     
     char formatstr[MSGLEN];     

     // debug, cut-down:
     strcpy(formatstr, "§");
     strcat(formatstr, "&i0=%d;&i1=%d;&i2=%d;&i3=%d;\n");
     sprintf(mbuf, formatstr, i0,i1,i2,i3);
                    
     for(uint8_t i=0; i<strlen(mbuf); i++) {           //
        serialPutchar( Serial, mbuf[i]);               // Send values to the slave       
     }   
      
     
     //delay?
     delay(1); 
   
     
     
     
     //-------------------------------------------------------------
     // receive
     
     int  n=0;
     char inChar;   
     char cstr[TOKLEN];
 
     inputString="";     
     stringComplete = false;     
     
     if (serialDataAvail(Serial)) { 
       while(!stringComplete && n<MSGLEN-1) {    
          if(n==MSGLEN-2) inChar='\n'; // emergency brake
          else  
            inChar = serialGetchar(Serial); 
       
          if(inChar=='\n' || inChar>=' ') inputString += inChar;       
          if (inChar == '\n')  {
            stringComplete = true;
          }
          n++;
       } 
     }
   
     
     if (stringComplete)  {
         
       //inputString.to_str(mbuf, len-1);
       strcpy (mbuf, inputString.c_str() );
   
       fprintf(stderr,"\n"); fprintf(stderr,mbuf); //fprintf(stderr,"\n"); 
   
       
       // cstringarg( char* haystack, char* vname, char* carg )
       // haystack pattern: &varname=1234abc;  delimiters &, \n, \0, EOF 
   
       
       cstringarg(mbuf, "i0", cval); //    
       if(strlen(cval)>0) {          
          sprintf (cstr,  "i0=%d \n", (int32_t)atol(cval));
          fprintf(stderr, cstr);
       }   
       cstringarg(mbuf, "i1", cval); //    
       if(strlen(cval)>0) {          
          sprintf (cstr,  "i1=%d \n", (int32_t)atol(cval));
          fprintf(stderr, cstr);
       }
       cstringarg(mbuf, "i2", cval); //    
       if(strlen(cval)>0) {          
          sprintf (cstr,  "i2=%d \n", (int32_t)atol(cval));
          fprintf(stderr, cstr);
       }
       cstringarg(mbuf, "i3", cval); //    
       if(strlen(cval)>0) {          
          sprintf (cstr,  "i3=%d \n", (int32_t)atol(cval));
          fprintf(stderr, cstr);
       }  
       cstringarg(mbuf, "i4", cval); //    
       if(strlen(cval)>0) {          
          sprintf (cstr,  "i4=%d \n", (int32_t)atol(cval));
          fprintf(stderr, cstr);
       }   
       
       inputString="";
       stringComplete = false;
   
       //delay?
       delay(1);
     }
   
   }     
}




//==================================================================

 
int main() {
     
    printf("initializing..."); printf("\n");
   
    // UART Serial com port
    Serial = serialOpen (uart, UARTclock);   
    printf("starting UART loop..."); printf("\n");   
    
    loop(); 
   
    serialClose( Serial);
    exit(0);
}


output e.g.

Code: Select all

§&i0=17628;&i1=1;&i2=17434;&i3=33;&i4=-444;&i5=5555;&i6=43690;
i0=17628 
i1=1 
i2=17434 
i3=33 
i4=-444 

§&i0=17629;&i1=1;&i2=17435;&i3=33;&i4=-444;&i5=5555;&i6=43690;
i0=17629 
i1=1 
i2=17435 
i3=33 
i4=-444 

§&i0=17630;&i1=1;&i2=17436;&i3=33;&i4=-444;&i5=5555;&i6=43690;
i0=17630 
i1=1 
i2=17436 
i3=33 
i4=-444 

§&i0=17631;&i1=1;&i2=17437;&i3=33;&i4=-444;&i5=5555;&i6=43690;
i0=17631 
i1=1 
i2=17437 
i3=33 
i4=-444 

§&i0=17632;&i1=1;&i2=17438;&i3=33;&i4=-444;&i5=5555;&i6=43690;
i0=17632 
i1=1 
i2=17438 
i3=33 
i4=-444 

§&i0=17633;&i1=1;&i2=17439;&i3=33;&i4=-444;&i5=5555;&i6=43690;
i0=17633 
i1=1 
i2=17439 
i3=33 
i4=-444 

§&i0=17634;&i1=1;&i2=17440;&i3=33;&i4=-444;&i5=5555;&i6=43690;
i0=17634 
i1=1 
i2=17440 
i3=33 
i4=-444 


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! hangs up !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Last edited by dsyleixa123 on Mon Jun 10, 2019 7:49 am, edited 3 times in total.

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: code for UART comm from Pi to Arduino hangs up

Sat Jun 08, 2019 11:11 am

code updated for debug reasons:
i0 now is incremented in each Arduino loop and sent back,
and i2 is now incremented in each Raspi loop and sent back;

all incremets are processed correctly and also received correctly vice versa.
But it still hangs up after a while.

Does anyone have a clever idea?

bzt
Posts: 374
Joined: Sat Oct 14, 2017 9:57 pm

Re: code for UART comm from Pi to Arduino hangs up

Sat Jun 08, 2019 2:49 pm

Hi,

I'm not sure about your problem, but why don't you use termios on RPi side? I have implemented serial communications with it many times to many different UARTs (including microcontrollers and industrial PLCs alike), and it have never failed me, and never lost sync not even over a long period of time (we are speaking of years). Something like:

Code: Select all

#include <termios.h>

/* variables */
struct termios tio;
int fd;

/* open the device file */
fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY);
if(fd < 1 || !isatty(fd)) {
  perror("error opening serial device");
  exit(1);
}

/* initialize connection to 115200 BAUD, 8 data bits, 1 stop bit, no parity check and raw mode (non-line buffered) */
memset(&tio, 0, sizeof(struct termios);
tcgetattr(fd, &tio);
tio.c_cflag = CS8 | CLOCAL | CREAD;
tio.c_iflag = ICRNL | IGNPAR | IGNBRK | BRKINT | IXON;
tio.c_oflag = 0;
tio.c_lflag = FLUSHO;
tio.c_cc[VEOF] = tio.c_cc[VEOL] = tio.c_cc[VTIME] = 0;
tio.c_cc[VMIN] = 1;
cfsetispeed(&tio, B115200);
cfsetospeed(&tio, B115200);
tcsetattr(fd, TCAFLUSH, &tio);

/* now you can read and write from the serial line just as you would from a normal file */
read(fd, &inbuffer, insize);
write(fd, &outbuffer, outsize);
If you want to read from the serial non-blocking, or with a time-out, then you can use "fcntl(O_NONBLOCK)" and "select()" system calls on fd. Here's an example code. This runs on a PC, but don't be alarmed, exactly the same code needed on the RPi because Raspbian is a Linux too. This code is originated from the raspbootcom.cc by Goswin von Brederlow, I have only made minor modifications so that it compiles with gcc instead of g++. It reads the serial port and the stdin at the same time, because it's acting as a terminal. It outputs what it receives, and sends what you type (and therefore it does not block on read() when nothing is received from serial).

Cheers,
bzt

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: code for UART comm from Pi to Arduino hangs up

Sat Jun 08, 2019 3:17 pm

tbh, termios looks far too complicated to me and I don't have any experience or skills using that.
OTOH I thought that wiringPi/wiringSerial actually would work reliably (doesn't it?).
Basically I am using wiringSerial libs because they look sort of Serial()-like from the Arduino Serial() class (even knowing that they are working totally differently though).
As you probably will have seen, my Arduino is attached to one of the Raspi's USB ports ("/dev/ttyACM0"), and the Arduino is using the Serial class for UART communication. The Arduino is also identified and pogrammed by the Arduino IDE through this USB/virtual COM port

But if you could rewrite my Raspi code (currently using wiringSerial) into a compatible, compileable code feat. all my string operations (now instead just using termios via USB "/dev/ttyACM0") then of course I gladly would try!
(PS, as you have probably seen, I am using g++ because of std::string (plus later on for some additional C++ classes)

User avatar
scruss
Posts: 2265
Joined: Sat Jun 09, 2012 12:25 pm
Location: Toronto, ON
Contact: Website

Re: code for UART comm from Pi to Arduino hangs up

Sat Jun 08, 2019 8:27 pm

are you sure it's the Raspberry Pi hanging?

I see you're using a Due. Some Arduinos (from experience, the Leonardo and the Micro) stop processing if the serial buffer gets too full. Put a watchdog in your code to turn the internal LED on and off every few serial commands. If it stops flashing, your Arduino has stopped.

This doesn't seem to affect Arduino Uno, Mega, etc. I have a Due, but it's in another country right now so I can't test it.
‘Remember the Golden Rule of Selling: “Do not resort to violence.”’ — McGlashan.

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: code for UART comm from Pi to Arduino hangs up

Sun Jun 09, 2019 7:41 am

no, I'm using a Mega2560 (AVR), and the Serial class (esp. Serial.readStringUntil() , Serial.available() ) is supposed to manage all the transmissions, buffers, and timeouts correcty:
https://www.arduino.cc/reference/en/lan ... on/serial/
https://www.arduino.cc/reference/en/lan ... ringuntil/

As stated, my Arduino code always worked both from Arduino to Arduino (UART GPIOs RX/TX), and Arduino to Windows PC (Arduino USB to USB/PC, UART widget by Borland C++Builder).
Just for Arduino to Raspi (via USB) it hangs up.

Only at the very start of my attempts, a Due (taken intermediately for comparison, testing, and debugging reasons) was a bit more stable right from the start, but even then also the Due always hung up, a couple of minutes later.

Anyway, my Arduino send-msg string is always far bigger (Arduino send: 1024 bytes) than the UART buffer (64 bytes) both on Arduino and Raspi, and even if the Arduino stops receiving and sending it's not clear why, e.g. if it's because the Raspi don't send or receive either and/or the UART/USB bus is shaky or blocked.
(OTOH, the Rasp send-string is currently always less than 64 bytes, and the Raspi also always reads just until '\n' and disregards the rest)

Nonetheless: the msg string always is of equal size, and it never blocks during the first couple of minutes, so why should this suddenly block then randomly at the 2000th or the 4000th or the 17000th send or receive loop in case it was an Arduino-Serial buffer issue ? And how could it fail for the Arduino, if the Arduino communicates just with the Pi, and never happens from an Arduino to a 2nd Arduino or to a Windows PC?

If you want to check: this is WORKING Arduino-to-PC code, in a version I already also tried (and failed) when communicating to a Pi instead, as published earlier here (see my code examples at the beginning of this topic):
https://github.com/dsyleixa/Borland-Cpp ... 6_RxTx.ino
Note that in this Arduino-PC-version all the msg strings even are much bigger than the cut-down ones for my Raspi attempts!

Arduino code:

Code: Select all

// receive

  while (Serial.available() ) {
    
    char inChar = (char)Serial.read(); 
    inputString += inChar;
    
    if (inChar == '\n')  {
      stringComplete = true;
    }
  }

  if (stringComplete)  {
  inputString.toCharArray(cbuf, MSGLEN-1);
  //
  
  //...
  // send  
  char formatstr[MSGLEN];
  strcpy(formatstr, "&i0=%d;&i1=%d;&i2=%d;&i3=%d;&i4=%d;&i5=%d;&i6=%d;");
  strcat(formatstr, "&f0=%f;&f1=%f;&f2=%f;&f3=%f;&f4=%f;&f5=%f;");
  strcat(formatstr, "&A0=%d;&A1=%d;&A2=%d;&A3=%d;&A4=%d;&A5=%d;&A6=%d;&A7=%d;&A8=%d;&A9=%d;&A10=%d;&A11=%d;");

  sprintf(cbuf, formatstr, i0,i1,i2,i3,i4,i5,i6, f0,f1,f2,f3,f4,f5, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11 );
                 
  Serial.println(cbuf);
   
}
The PC counter part does exactly the same as the Raspi should, and on the PC and vice versa on the Arduino it works like a charm:

Borland C++ PC code, https://github.com/dsyleixa/Borland-Cpp ... /Unit1.cpp :

Code: Select all

void __fastcall TForm1::ComPort1RxChar(TObject *Sender, int Count)
{  
  AnsiString rcvbuf;
  char rcvStr[MSGLEN];
  
  // receive

  ComPort1->ReadStr(rcvbuf, 1024);
   // reads  "Count" Bytes into an ANSI string  (up to 1024, as far as available)  and then copies them to a cstring:
  strcpy(rcvStr, rcvbuf.c_str() );
  //...
  
  // send

  char formatstr[MSGLEN];
  strcpy(formatstr, "&i0=%d;&i1=%d;&i2=%d;&i3=%d;&i4=%d;&i5=%d;&i6=%d;");
  strcat(formatstr, "&f0=%f;&f1=%f;&f2=%f;&f3=%f;&f4=%f;&f5=%f;");
  strcat(formatstr, "&A0=%d;&A1=%d;&A2=%d;&A3=%d;&A4=%d;&A5=%d;&A6=%d;&A7=%d;&A8=%d;&A9=%d;&A10=%d;&A11=%d;");

  sprintf(cbuf, formatstr, i0,i1,i2,i3,i4,i5,i6, f0,f1,f2,f3,f4,f5, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11 );
  Serial.println(cbuf);
}
But if anybody has a better code,then I will gladly try it, either for the Pi or for the Arduino!

bzt
Posts: 374
Joined: Sat Oct 14, 2017 9:57 pm

Re: code for UART comm from Pi to Arduino hangs up

Sun Jun 09, 2019 12:23 pm

dsyleixa123 wrote:
Sat Jun 08, 2019 3:17 pm
tbh, termios looks far too complicated to me and I don't have any experience or skills using that.
It is not complicated. Looks weird, I give you that, that's why I gave you an example. You open a file, you use some 10-12 lines of magic on the fd, and there you go.
dsyleixa123 wrote:
Sat Jun 08, 2019 3:17 pm
OTOH I thought that wiringPi/wiringSerial actually would work reliably (doesn't it?).
I don't know. All I know, you have reliability issues, and the only way to solve that is to replace the components one by one until you locate which one is faulty (software and hardware components both included). There's no other guaranteed working method that I know of.
dsyleixa123 wrote:
Sat Jun 08, 2019 3:17 pm
As you probably will have seen, my Arduino is attached to one of the Raspi's USB ports ("/dev/ttyACM0"), and the Arduino is using the Serial class for UART communication. The Arduino is also identified and pogrammed by the Arduino IDE through this USB/virtual COM port
Why don't you use RPi's own UART? Either PL011 or MniAUX? Just a guess. One less component is always better. (But you may need a signal level converter which is still simpler than USB, it can't loose sync).
dsyleixa123 wrote:
Sat Jun 08, 2019 3:17 pm
But if you could rewrite my Raspi code (currently using wiringSerial) into a compatible, compileable code feat. all my string operations (now instead just using termios via USB "/dev/ttyACM0") then of course I gladly would try!
Sorry, no one can do that, except for you. I gave you an example and there are literally hundreds of termios examples on the net.
dsyleixa123 wrote:
Sat Jun 08, 2019 3:17 pm
(PS, as you have probably seen, I am using g++ because of std::string (plus later on for some additional C++ classes)
And I have told you where's my gcc code that works, and where you can find the equivalent g++ version :-)

Cheers,
bzt

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: code for UART comm from Pi to Arduino hangs up

Sun Jun 09, 2019 1:12 pm

thanks for your comments, but all that is far beyond my skills, I just can handle a little bit of wiringPi, even pigpio or above all native UART or termios are far too complicated (and what the hell is PL011 or MniAUX?) :
so a very convenient lib (apart from wiringPi, if necessary) and a working code example would be neened, just like it already exists for Arduino (if they internally use native Linux functions that wouldn't matter of course, as long as they provide simple user-friendly API wraps around them).

As already stated, I actually had expected that such a stable communication lib between Arduino and Raspi already existed since a long time yet, I honestly cannot believe that I am supposed to be the first one who needs such a thing.

bzt
Posts: 374
Joined: Sat Oct 14, 2017 9:57 pm

Re: code for UART comm from Pi to Arduino hangs up

Sun Jun 09, 2019 5:13 pm

dsyleixa123 wrote:
Sun Jun 09, 2019 1:12 pm
thanks for your comments, but all that is far beyond my skills, I just can handle a little bit of wiringPi, even pigpio or above all native UART or termios are far too complicated (and what the hell is PL011 or MniAUX?) :
It is not complicated (see my example) just looks like it :-) Has three parts: 1. open the file, 2. set up port (copy this one from an example or from a tutorial, don't care about the details), 3. use read() and write().
PL011 and MiniAUX are the two UART chips integrated into the RPi's SoC, you can access them on GPIO pins 14/15. See BCM2835-ARM-Peripherals.pdf. By default, the Linux console is redirected to that, so you have to turn serial console off from config.txt to avoid noise in your communication. But otherwise they are there and you can use them without the need to occupy an USB port.
dsyleixa123 wrote:
Sun Jun 09, 2019 1:12 pm
so a very convenient lib (apart from wiringPi, if necessary) and a working code example would be neened, just like it already exists for Arduino (if they internally use native Linux functions that wouldn't matter of course, as long as they provide simple user-friendly API wraps around them).
Well, termios is included in libc and is POSIX standard, so it is considered to be a native Linux function. To me it's interface is simple (just call some functions on an fd), but I can understand if it looks martian to you. My advice is don't be afraid of it. Open the device, call termios on it in the initialization phase, then forget about termios, just use read(), write().
dsyleixa123 wrote:
Sun Jun 09, 2019 1:12 pm
As already stated, I actually had expected that such a stable communication lib between Arduino and Raspi already existed since a long time yet, I honestly cannot believe that I am supposed to be the first one who needs such a thing.
You are absolutely right that it should work. But for some reason it doesn't in your set-up. Of course this doesn't mean the problem is with the library, I wouldn't rule out a faulty USB cable either just yet. The point is, use trial-and-error, replace all components one-by-one until you found the faulty one. Believe me, that's the best debugging advice anybody can give you.

Cheers,
bzt

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: code for UART comm from Pi to Arduino hangs up

Sun Jun 09, 2019 5:35 pm

the USB cables I had already checked and swapped, also a 2nd Mega2560, also a Arduino Due (Atsam3x8e or so) using different microUSB cables.
All the same, runs for a time, then stalls.
Arduinos connected to my PC (Borland C++ Builder): no problem, runs like a charm.

All I would need is a simple-to-use function

int SerialReadString(std::string rcvString, int maxlen, int fd);

which reads the UART bytes into that std::string until maxlen (or stops prematurely when nothing comes in any more), and drops the rest if anything is coming after, providing all timeouts and buffers and error handlings which are needed, just like the Arduino or the Borland thing - and returns the number of bytes read, or a negative error code if failed.

If here is no one who can provide a fixed or a new functioning code then I have to give up and abandon that sh***y Raspberry Pi to Arduino thing.

bzt
Posts: 374
Joined: Sat Oct 14, 2017 9:57 pm

Re: code for UART comm from Pi to Arduino hangs up

Sun Jun 09, 2019 6:31 pm

dsyleixa123 wrote:
Sun Jun 09, 2019 5:35 pm
All I would need is a simple-to-use function

SerialReadString(std::string rcvString, int maxlen, int fd);
Is

Code: Select all

std::string SerialReadString(int maxlen, int fd) {
  char buff[maxlen];
  read(fd, &buff, maxlen);
  return new std::string(&buff);
}
and

Code: Select all

void SerialWriteString(std::string sndString, int len, int fd) {
  write(fd, sndString.c_str(), len);
}
simple enough? :-) (Note I haven't tested this code, just wrote from memory. I haven't coded in C++ for more than 15 years. Google for "char* std::string" to be sure).

Cheers,
bzt

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: code for UART comm from Pi to Arduino hangs up

Sun Jun 09, 2019 6:40 pm

that looks like what wiringSerial serialGetchar(fd) is supposed to do, but that fails, so what is the advantage?
where is the timeout handling, the buffer handling, perhaps intermediate buffers if bytes don't come fast enough or by gaps, a flush, a disconnect and a resync in case it's needed?

Both the Arduino Serial() and the Borland ComPort() classes have that integrated.
(Admittedly the Arduino Serial methods are utterly bad documented and the Arduino developers refuse any further functional explanation, but eventualy they appear to communicate fine e.g. with the Borland ComPort class, so there is actually no indication of any a malfunction).

Ps,
and after having received the entire message,
then an analogous Serial.write function would be needed, also failsafe, never stalling.

bzt
Posts: 374
Joined: Sat Oct 14, 2017 9:57 pm

Re: code for UART comm from Pi to Arduino hangs up

Mon Jun 10, 2019 2:06 pm

dsyleixa123 wrote:
Sun Jun 09, 2019 6:40 pm
that looks like what wiringSerial serialGetchar(fd) is supposed to do, but that fails, so what is the advantage?
You can rule out one component, and replace with one that known to be working on many architectures and OSes (Raspbian included).
dsyleixa123 wrote:
Sun Jun 09, 2019 6:40 pm
where is the timeout handling, the buffer handling, perhaps intermediate buffers if bytes don't come fast enough or by gaps, a flush, a disconnect and a resync in case it's needed?
In short, RTFM. For line buffered mode, you have to use the ICANON lflag. For timeout, as I have already wrote, use the select() system call with the single fd in the fd_set.
dsyleixa123 wrote:
Sun Jun 09, 2019 6:40 pm
Both the Arduino Serial() and the Borland ComPort() classes have that integrated.
(Admittedly the Arduino Serial methods are utterly bad documented and the Arduino developers refuse any further functional explanation, but eventualy they appear to communicate fine e.g. with the Borland ComPort class, so there is actually no indication of any a malfunction).

Ps,
and after having received the entire message,
then an analogous Serial.write function would be needed, also failsafe, never stalling.
Your set up is failing. Unless you want to leave it this way, you have to change something. I'm afraid that's all the advice I can give you. Termios never lost sync for me, but if you don't want to use it, then don't.

Cheers,
bzt

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: code for UART comm from Pi to Arduino hangs up

Mon Jun 10, 2019 2:37 pm

I think what you are missing is the following:
my setup for my Arduino is fine, it's the same as I am using to communicate with the PC and/or with another Arduino - with the PC and/or with another Arduino it works, with the Pi it temporarily (!) does not (sometimes already after a couple of seconds after start, sometimes only after more than half an hour, or anything in between). So whatever makes the communication fail to the Pi, it's a randomly exceptional event.

Additionally (which is probably crucial), both for the Arduino and for the PC there are simple "high-level" UART read/write functions available, e.g.
rcvbuf=Serial.readStringUntil('\n')
ComPort1->ReadStr(rcvbuf, 1024);
In both cases I don't have to care about any nasty low level details, and I don't have to invent the wheel anew, all is handled by the lib functions.
Same it's about the UART write functions.

For the Pi I don't know such failsafe lib functions, and that's what's appearently missing (wiringPi is unexpectedly failing, and it uses just wraps around the basic Uart functions like those you have shown).
OTOH, code examples working with timeouts (e.g. provided by LdB) all didn't work anything better than without those timeouts.

So if you can provide such a failsafe highlevel function based on termios, ready-to-use, then of course I'll highly appreciate that, just show me please! (To me termios itself is totally weird shambles.)
But if you can't show such a working function because you haven't programmed C(++) since 15 years as you have stated, it wouldn't help either if you just insist in advertising termios.

bzt
Posts: 374
Joined: Sat Oct 14, 2017 9:57 pm

Re: code for UART comm from Pi to Arduino hangs up

Tue Jun 11, 2019 12:43 pm

With respect, I think you are the one who's missing something.
dsyleixa123 wrote:both for the Arduino and for the PC there are simple "high-level" UART read/write functions available
Reading and writing from a file descriptor is the most abstract, highest level possible. The UNIX philosophy (and therefore Linux) abstracts everything to file read / writes. I've also given you examples, but there are literally hundreds of termios examples on the net, just a simple search away from you.
dsyleixa123 wrote:So whatever makes the communication fail to the Pi, it's a randomly exceptional event.
I don't think it's random. It looks much more like lost sync, caused by improper configuration of slightly different clock freqs inside the UART chips.
dsylexia123 wrote:But if you can't show such a working function because you haven't programmed C(++) since 15 years
Now these are your biggest mistakes (in plural).
1. don't mix C and C++, some would kill you for that (my university prof for one). The former is built on structural paradigm, the latter on OO. I said I haven't used C++ (because I prefer other languages for OO), and I program in C on a daily basis.
2. not one, but more working functions were already shown to you which you seem to ignore
3. don't expect us to do your work. We are here to help you and point you in the right direction, not to substitute you entirely.

Finally, if you're not willing to learn the native Linux API for serial ports, then don't.

Cheers,
bzt

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: code for UART comm from Pi to Arduino hangs up

Tue Jun 11, 2019 12:49 pm

don't expect us to do your work.
hahaha! Never heard that before - (tbh, mostly from people who personally only have vague ideas (plus unfounded suspicions) but are not able to provide actually working code though) ;)

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 11847
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: code for UART comm from Pi to Arduino hangs up

Tue Jun 11, 2019 1:53 pm

dsyleixa123 wrote:
Tue Jun 11, 2019 12:49 pm
don't expect us to do your work.
hahaha! Never heard that before - (tbh, mostly from people who personally only have vague ideas (plus unfounded suspicions) but are not able to provide actually working code though) ;)
This sneer is not acceptable behavior, we expect better from our guests.
the remark was probably triggered by previous experience with scholars who think they can get other members here to do their school assignment for them.
please follow our main community guideline, be nice to each other. :mrgreen:


User avatar
rpdom
Posts: 14456
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: code for UART comm from Pi to Arduino hangs up

Thu Jun 13, 2019 5:34 am

dsyleixa123 wrote:
Wed Jun 12, 2019 8:57 pm
- solved -
Are you going to tell us how, so that others may benefit from your experiences?

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: code for UART comm from Pi to Arduino hangs up

Thu Jun 13, 2019 7:11 am

I put my former code from the loop function into a pthread by medium to high SCHED_RR priority, currently trying some different prio values to find the optimum (tried so far: prios 40 to 60).

bzt
Posts: 374
Joined: Sat Oct 14, 2017 9:57 pm

Re: code for UART comm from Pi to Arduino hangs up

Thu Jun 13, 2019 5:00 pm

Hi,

I'm sorry if I sounded rude, I didn't meant to. I'm glad to hear that you have solved your issue!

Cheers,
bzt

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: code for UART comm from Pi to Arduino hangs up

Thu Jun 13, 2019 5:15 pm

Thank you, all right, no problem, is already long forgotten 8-)

Return to “C/C++”