0
votes

I'm trying to sendo datas from Arduino Uno to RaspberryPi 3B. I need to send 14 int (max value: 6000) from Arduino as soon as Raspberry ask for them. Each one of this 14 number came from ad ADC (SPI communication).

ARDUINO SIDE

#include "SPI.h"
byte incomingByte = 0;   // for incoming serial data

const int N_SENSORI=14;
const int DATAOUT = 11;
const int DATAIN = 12;
const int SPICLOCK = 13;
const int SLAVESELECT = 10;

//===============SPI COMMUNICATION================
short write_read_spi16(short what) {
  digitalWrite(SS, LOW);
  short res = SPI.transfer16(what);
  digitalWrite(SS, HIGH); 
  return res;
}

 //===============CONVERT INT IN BYTE AND SEND IT================
void longInt2Byte( int x){
  unsigned char buf[sizeof( int)];
  memcpy(buf,&x,sizeof(int));
Serial.write(buf,sizeof(buf));

}
//=======================================

void setup() {

  Serial.begin(115200);     
  SPI.begin();
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT); 
}
void loop() {


if (Serial.available() > 0) {         
  incomingByte= Serial.read();

  if (incomingByte=='E') {

    write_read_spi16(0b1000001101110000);  //THIS IS FOR THE ADC COMMUNICATION

    for (int i = 1; i<N_SENSORI+1; i++) { //DONE 14 TIMES.
      short s = write_read_spi16(0b1000001101110000 | (i<<10));
      int Data = s&0xFFF;
      longInt2Byte(Data);
        }       
      }
 }}

// C++ SIDE

void stimulationController::SetupDario(){

    cout<<"Dentro al setupDario"<<endl<<flush;
    buffer=new char [1000];
    const char* _portNameSensorsDario="/dev/ttyACM1";
    //SERIAL PORT FOR HAND SENSORS
    struct termios options;
    SerialHandleSensors=open(_portNameSensorsDario, O_RDWR | O_NOCTTY | O_NDELAY); //SerialHandleSensors=open(_portNameSensors, O_RDWR | O_NOCTTY | O_NDELAY); non blocking
    if (SerialHandleSensors == -1 )
    {
        cout<<endl<<"......ERROR: Unable to open: "<<_portNameSensorsDario<<endl;
        return;
    }
    else
    {
        fcntl(SerialHandleSensors, F_SETFL,0);
        cout<<"......OPENED PORT: Succesfully opened: "<<_portNameSensorsDario<<endl;
    }

    //GET THE OPTIONS, MODIFY AND SET
    tcgetattr(SerialHandleSensors,&options);
    cfsetispeed(&options,B115200); //BAUD RATE IN
    cfsetospeed(&options,B115200); //BAUD RATE OUT
    // options.c_lflag |= (ICANON | ECHO | ECHOE);
    options.c_cflag |= (CLOCAL | CREAD);
    options.c_cflag &= ~PARENB;
    options.c_cflag |= CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    tcsetattr(SerialHandleSensors,TCSANOW,&options);

    usleep(3000000);
cout<<"Fine Setup"<<endl<<flush;
}



int stimulationController::Dario( )
{

    {
    cout<<" NUOVA FUNZIONE"<<endl;


unsigned char bytes[4];
    bytes[0]=0x45;  // 'E'

    int tempWrite=write(SerialHandleSensors,bytes,1);
    if(tempWrite==-1)
    {
        cout<<"......ERROR: PROBLEM WRITING TO ROBOTIC HAND"<<endl;
        failure=true;
        return 0; 

    }

    int value=0;


    int tempRead=read(SerialHandleSensors,buffer,28);
    if(tempRead==-1)
    {
        cout<<"......ERROR: PROBLEM READING FROM ROBOTIC HAND"<<endl;
        failure=true;
        return 0;
    }


int j=0;
for( int i=0; i<28; i=i+2){
    value= buffer[i] | ((int)buffer[i+1]<<8);
    //ensorDataFoot.push_back(value);  //Aggiunge un elemento
    j=j+1;
        cout<<"Dato "<<j  <<"vale: "<<value<<endl<<flush;
    }

    return value;

}
}

The problem is that or the raspberry side some time it prints the right values, some time (the most of the times, actually) it doesn't. Data seems to be repeated or (2500 insted of 2000 for example).

I can't figure it out the problem.Could it be a matter of timing between the request of sending data and the reading? if so, there is a way to get rid of it?

I've added a do-while cycle in order to be sure that all the 28 bytes are read

int TotByte=28;
int ByteRead=0;
int TempRead=0;

do{ TempRead= read(SerialHandleSensors, buffer, (TotByte-ReadByte));
ReadByte= ReadByte+TempRead;
cout<<"ReadByte is: "<<ReadByte<<endl<<flush;
}while(ByteRead<TotByte);

Output:

ReadByte is: 5
ReadByte is: 15
ReadByte is: 25

and then it stay like that without doing anything

1
Thanks for editing the community wiki answer. If you would like to post it yourself (so you can edit it freely and get potential reputation points from it) then post another copy of it and let me know so I can delete the current one.halfer

1 Answers

0
votes

(Posted answer on behalf of the OP):

I figured it out; the problem were the settings of the serial port. For future reference, here is the working version.

bufferTemp=new char [1000];
    bufferDEF = new char[1000];
    const char* _portNameSensorsBT="/dev/rfcomm0";

    struct termios options;
    SerialHandleSensorsFoot=open(_portNameSensorsBT, O_RDWR ); //SerialHandleSensors=open(_portNameSensors, O_RDWR | O_NOCTTY | O_NDELAY); non blocking
    if (SerialHandleSensorsFoot == -1 )
    {
        cout<<endl<<"......ERROR: Unable to open: "<<_portNameSensorsBT<<endl;
        return 0;
    }
    else
    {
        fcntl(SerialHandleSensorsFoot, F_SETFL,0);
        cout<<"......OPENED PORT: Succesfully opened: "<<_portNameSensorsBT<<endl;
    }

    //GET THE OPTIONS, MODIFY AND SET
    tcgetattr(SerialHandleSensorsFoot,&options);
    cfsetispeed(&options,B115200); //BAUD RATE IN
    cfsetospeed(&options,B115200); //BAUD RATE OUT
    // options.c_lflag |= (ICANON | ECHO | ECHOE);

    options.c_iflag = IGNBRK | IGNPAR;
    options.c_oflag = 0; 
    options.c_lflag = 0; 

    options.c_cflag |= (CLOCAL | CREAD);
    options.c_cflag &= ~PARENB;
    options.c_cflag |= CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    tcsetattr(SerialHandleSensorsFoot,TCSAFLUSH,&options);

    usleep(5000000);

with these setting I'm able to communicate with bluetooth even though there might be some velocity problem.