I2C read problems

Thanks, that explains it. Must read more closely. :slight_smile:

i have one more problem

void setup()
{
Serial.begin(UartBaudRate);
Wire.begin(I2C_Address);
Wire.onRequest(requestEvent);
Wire.onReceive(ReceiveCommand);
}

void loop()
{
if(command == 'C')
{
Capture_OS4000();
Check_Sentence();
if ( SentenceState == true ) Extract_Info();
command = 'N';
}
}

void ReceiveCommand(int howMany)
{
while(!Wire.available());
command = Wire.receive();
}

its working

but

that is not working

void setup()
{
Serial.begin(UartBaudRate);
Wire.begin(I2C_Address);
Wire.onRequest(requestEvent);
Wire.onReceive(ReceiveCommand);
}

void loop()
{

}

void ReceiveCommand(int howMany)
{
while(!Wire.available());
command = Wire.receive();

if(command == 'C')
{
Capture_OS4000();
Check_Sentence();
if ( SentenceState == true ) Extract_Info();
command = 'N';
}
}

never executed the first command on Capture_OS4000();

also i am waiting enought untill i send another command on i2C

while(!Wire.available());

Try it with this removed

nothing

void requestEvent()
{
if ( command == 'a' ) // Send All
{
WireSendAll();
}
else if ( command == 'H' ) // Heading
{
WireSendInt(1963);
}
else if ( command == 'P' ) // Pitch
{
WireSendInt(54);
}
else if ( command == 'R' ) // Roll
{
WireSendInt(-10);
}
else if ( command == 'T' ) // Temp
{
WireSendInt(186);
}
else if ( command == 'D' ) // Depth
{
WireSendInt(Depth);
}
else if ( command == 'M' ) // Magnetic Vector
{
WireSendInt(MagneticVector);
}
else if ( command == 'X' ) // Magnetic X
{
WireSendInt(MagneticX);
}
else if ( command == 'Y' ) // Magnetic Y
{
WireSendInt(MagneticY);
}
else if ( command == 'Z' ) // Magnetic Z
{
WireSendInt(MagneticZ);
}
else if ( command == 'A' ) // Accelaration Vector
{
WireSendInt(AccelarationVector);
}
else if ( command == 'x' ) // Accelaration X
{
WireSendInt(AccelarationX);
}
else if ( command == 'y' ) // Accelaration Y
{
WireSendInt(AccelarationY);
}
else if ( command == 'z' ) // Accelaration Z
{
WireSendInt(AccelarationZ);

}
else if ( command == 'G' ) // Gyro X
{
WireSendInt(GyroX);

}
else if ( command == 'g' ) // Gyro Y
{
WireSendInt(GyroY);
}
else
{
}
command = 'N';
}

with

void WireSendInt (int val)
{
byte buf [2];
buf [0] = val >> 8;
buf [1] = val & 0xFF;
Wire.send (buf, 2);
}

and i am reading back with uart on the receiver:

H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 0 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186
H: 1963 P: 54 R: -10 T: 186

do you have any idea why?

herctrap:
void WireSendInt (int val)
{
byte buf [2];
buf [0] = val >> 8;
buf [1] = val & 0xFF;
Wire.send (buf, 2);
}

Look. Please learn to use the [ code ] tags. Don't quote code. You quote what people say. You use the "#" button on code. Quoting code makes the forum turn it into strange things.

Meanwhile, how about a "switch" statement? It makes it much more readable:

void requestEvent()
{
  switch (command)
     {
     case 'a': WireSendAll(); break;
     case 'H': WireSendInt(1963); break;
     case 'P': WireSendInt(54); break;

    //  and so on ...

     case 'g': WireSendInt(GyroY); break;
     default:   break;   // do nothing
     } // end of switch

  command = 'N';
}  // end of requestEvent

thanks a lot
i will use code tags from now on

but my output is

H: 3478 P: 17 R: 17 T: 305
H: 3478 P: 17 R: 17 T: 304
H: 3478 P: 17 R: 17 T: 303
H: 3478 P: 17 R: 17 T: 303
H: 3478 P: 17 R: 17 T: 305
H: 3478 P: 17 R: 17 T: 306
H: 3478 P: 17 R: 17 T: 307
H: 3478 P: 17 R: 17 T: 307
H: 3478 P: 17 R: 17 T: 306
H: 0 P: 17 R: 17 T: 304
H: 3478 P: 17 R: 17 T: 304
H: 3478 P: 17 R: 17 T: 303
H: 3478 P: 17 R: 17 T: 303
H: 3478 P: 17 R: 17 T: 305
H: 3478 P: 17 R: 17 T: 306
H: 3478 P: 17 R: 17 T: 307
H: 3478 P: 17 R: 17 T: 308
H: 3478 P: 17 R: 17 T: 308
H: 3478 P: 17 R: 17 T: 308
H: 3478 P: 0 R: 17 T: 309
H: 3478 P: 17 R: 17 T: 309
H: 3478 P: 17 R: 17 T: 309
H: 3478 P: 17 R: 17 T: 309
H: 3478 P: 17 R: 17 T: 308
H: 3478 P: 17 R: 17 T: 308
H: 3478 P: 17 R: 17 T: 308
H: 3478 P: 17 R: 17 T: 308
H: 3478 P: 17 R: 17 T: 306
H: 3478 P: 17 R: 17 T: 305

why is this happening?

if i use this on the receiver:

while ( Wire.available() < 2 ){}

the program freezes
so i think that the sender is not sending two bytes

OR

the sender is not sending the command so the receiver reply to that command

OR

the receiver does not receive the command to send the two bytes

herctrap:
thanks a lot
i will use code tags from now on

but my output is

if i use this on the receiver:

while ( Wire.available() < 2 ){}

the program freezes
so i think that ...

Now, can you please explain to me why you have decided to ignore my advice, which I have repeated, to not do that?

I'm curious. I have stated twice that it won't help to do that. And you leave it in, and then post asking why it isn't working.

This is what I said last time:

i am not using it it since the time you told me not to

then my output is 0
H: 0 P: 17 R: 17 T: 304

so i wanted to know if i get two 0 bytes

or none byte

if it freeze it means that is not receiving 2 bytes


but why its not receiving them?

if it freeze it means that is not receiving 2 bytes

You could simply print the number of bytes you get. There is no reason to make your code go into a loop it can never recover from.

Perhaps if you posted the updated version of all your code, since you've apparently made several changes, and show what results you are getting and what results you expect to get.

#include <Wire.h>

#define I2C_Address 2
#define UartBaudRate 57600

int Position;
int NextData;

boolean SentenceState = false;
char OS4000Data[128];

char command;

int Heading;
int Heading100;
int Heading10;
int Heading1;
int Heading01;

int Pitch;
int Pitch100;
int Pitch10;
int Pitch1;
int Pitch01;

int Roll;
int Roll100;
int Roll10;
int Roll1;
int Roll01;

int Temp;
int Temp100;
int Temp10;
int Temp1;
int Temp01;

int Depth;

int MagneticVector;

int MagneticX;

int MagneticY;

int MagneticZ;

int AccelarationVector;

int AccelarationX;

int AccelarationY;

int AccelarationZ;

int GyroX;

int GyroY;

void setup()
{
  Serial.begin(UartBaudRate);  
  Wire.begin(I2C_Address);  
  Wire.onRequest(requestEvent); 
  Wire.onReceive(ReceiveCommand);
}

void loop()
{
  if(command == 'C')
  {
    Capture_OS4000();
    Check_Sentence();
    if ( SentenceState == true ) Extract_Info();
    command = 'N';
  }
}


void ReceiveCommand(int howMany)
{
  while(!Wire.available());
  command = Wire.receive();
}

void requestEvent()
{
  switch (command)
  {
  case 'A': 
    WireSendAll(); 
    break;
  case 'H': 
    WireSendInt(Heading); 
    break;
  case 'P': 
    WireSendInt(Pitch); 
    break;
  case 'R': 
    WireSendInt(Roll); 
    break;
  case 'T': 
    WireSendInt(Temp); 
    break;
  case 'D': 
    WireSendInt(Depth); 
    break;
  case 'M': 
    WireSendInt(MagneticVector); 
    break;
  case 'X': 
    WireSendInt(MagneticX); 
    break;
  case 'Y': 
    WireSendInt(MagneticY); 
    break;
  case 'Z': 
    WireSendInt(MagneticZ); 
    break;
  case 'a': 
    WireSendInt(AccelarationVector); 
    break;
  case 'x': 
    WireSendInt(AccelarationX); 
    break;
  case 'y': 
    WireSendInt(AccelarationY); 
    break;
  case 'z': 
    WireSendInt(AccelarationZ); 
    break;
  case 'G': 
    WireSendInt(GyroX); 
    break;
  case 'g': 
    WireSendInt(GyroY); 
    break;
  default:   
    break;
  }
  command = 'N';
}

void  Capture_OS4000()
{
  Serial.flush();
  while ( Serial.read () != '

the Extract_Info() is totaly corect
it is always updates corectly the
Heading PItch Roll Temp
i have check it with uart output

also i have tried

void requestEvent()
{
  switch (command)
  {
  case 'A': 
    WireSendAll(); 
    break;
  case 'H': 
    WireSendInt(100); 
    break;
  case 'P': 
    WireSendInt(-214); 
    break;
  case 'R': 
    WireSendInt(5); 
    break;
  case 'T': 
    WireSendInt(-98); 
    break;

);
 Serial.flush();
 while( Serial.available() < 127 );
 for ( Position = 0; Position < 126; Position++ ){
   OS4000Data[Position] = char( Serial.read());
 }
}

void Check_Sentence()
{
 if ( ( OS4000Data[0] == 'O' ) && ( OS4000Data[1] == 'H' ) && ( OS4000Data[2] == 'P' ) && ( OS4000Data[3] == 'R' ) && ( OS4000Data[4] == ',' ) )SentenceState = true;
 else SentenceState = false;
}

void Extract_Info()
{
 Heading100 = 0;
 Heading10 = 0;
 Heading1 = 0;
 Heading01 = 0;
 if ( OS4000Data[8] == '.' ){
   Heading100 = OS4000Data[5] - '0';
   Heading10 = OS4000Data[6] - '0';
   Heading1 = OS4000Data[7] - '0';
   Heading01 = OS4000Data[9] - '0';
   NextData = 10;
 }
 else if ( OS4000Data[7] == '.' ){
   Heading10 = OS4000Data[5] - '0';
   Heading1 = OS4000Data[6] - '0';
   Heading01 = OS4000Data[8] - '0';
   NextData = 9;
 }
 else if ( OS4000Data[6] == '.' ){
   Heading1 = OS4000Data[5] - '0';
   Heading01 = OS4000Data[7] - '0';
   NextData = 8;
 }
 Heading = 1000Heading100 + 100Heading10 + 10*Heading1 + Heading01;

Pitch100 = 0;
 Pitch10 = 0;
 Pitch1 = 0;
 Pitch01 = 0;
 if ( OS4000Data[NextData+1] == '-' ){
   if ( OS4000Data[NextData+5] == '.' ){
     Pitch100 = OS4000Data[NextData+2] - '0';
     Pitch10 = OS4000Data[NextData+3] - '0';
     Pitch1 = OS4000Data[NextData+4] - '0';
     Pitch01 = OS4000Data[NextData+6] - '0';
     NextData += 7;
   }
   else if ( OS4000Data[NextData+4] == '.' ){
     Pitch10 = OS4000Data[NextData+2] - '0';
     Pitch1 = OS4000Data[NextData+3] - '0';
     Pitch01 = OS4000Data[NextData+5] - '0';
     NextData += 6;
   }
   else if ( OS4000Data[NextData+3] == '.' ){
     Pitch1 = OS4000Data[NextData+2] - '0';
     Pitch01 = OS4000Data[NextData+4] - '0';
     NextData += 5;
   }
   Pitch = - ( 1000Pitch100 + 100Pitch10 + 10Pitch1 + Pitch01 );
 }
 else
 {
   if ( OS4000Data[NextData+4] == '.' ){
     Pitch100 = OS4000Data[NextData+1] - '0';
     Pitch10 = OS4000Data[NextData+2] - '0';
     Pitch1 = OS4000Data[NextData+3] - '0';
     Pitch01 = OS4000Data[NextData+5] - '0';
     NextData += 6;
   }
   else if ( OS4000Data[NextData+3] == '.' ){
     Pitch10 = OS4000Data[NextData+1] - '0';
     Pitch1 = OS4000Data[NextData+2] - '0';
     Pitch01 = OS4000Data[NextData+4] - '0';
     NextData += 5;
   }
   else if ( OS4000Data[NextData+2] == '.' ){
     Pitch1 = OS4000Data[NextData+1] - '0';
     Pitch01 = OS4000Data[NextData+3] - '0';
     NextData += 4;
   }
   Pitch = ( 1000
Pitch100 + 100Pitch10 + 10Pitch1 + Pitch01 );
 }

Roll100 = 0;
 Roll10 = 0;
 Roll1 = 0;
 Roll01 = 0;
 if ( OS4000Data[NextData+1] == '-' ){
   if ( OS4000Data[NextData+5] == '.' ){
     Roll100 = OS4000Data[NextData+2] - '0';
     Roll10 = OS4000Data[NextData+3] - '0';
     Roll1 = OS4000Data[NextData+4] - '0';
     Roll01 = OS4000Data[NextData+6] - '0';
     NextData += 7;
   }
   else if ( OS4000Data[NextData+4] == '.' ){
     Roll10 = OS4000Data[NextData+2] - '0';
     Roll1 = OS4000Data[NextData+3] - '0';
     Roll01 = OS4000Data[NextData+5] - '0';
     NextData += 6;
   }
   else if ( OS4000Data[NextData+3] == '.' ){
     Roll1 = OS4000Data[NextData+2] - '0';
     Roll01 = OS4000Data[NextData+4] - '0';
     NextData += 5;
   }
   Roll = - ( 1000Roll100 + 100Roll10 + 10Roll1 + Roll01 );
 }
 else
 {
   if ( OS4000Data[NextData+4] == '.' ){
     Roll100 = OS4000Data[NextData+1] - '0';
     Roll10 = OS4000Data[NextData+2] - '0';
     Roll1 = OS4000Data[NextData+3] - '0';
     Roll01 = OS4000Data[NextData+5] - '0';
     NextData += 6;
   }
   else if ( OS4000Data[NextData+3] == '.' ){
     Roll10 = OS4000Data[NextData+1] - '0';
     Roll1 = OS4000Data[NextData+2] - '0';
     Roll01 = OS4000Data[NextData+4] - '0';
     NextData += 5;
   }
   else if ( OS4000Data[NextData+2] == '.' ){
     Roll1 = OS4000Data[NextData+1] - '0';
     Roll01 = OS4000Data[NextData+3] - '0';
     NextData += 4;
   }
   Roll = ( 1000
Roll100 + 100Roll10 + 10Roll1 + Roll01 );
 }

Temp100 = 0;
 Temp10 = 0;
 Temp1 = 0;
 Temp01 = 0;
 if ( OS4000Data[NextData+1] == '-' ){
   if ( OS4000Data[NextData+5] == '.' ){
     Temp100 = OS4000Data[NextData+2] - '0';
     Temp10 = OS4000Data[NextData+3] - '0';
     Temp1 = OS4000Data[NextData+4] - '0';
     Temp01 = OS4000Data[NextData+6] - '0';
     NextData += 7;
   }
   else if ( OS4000Data[NextData+4] == '.' ){
     Temp10 = OS4000Data[NextData+2] - '0';
     Temp1 = OS4000Data[NextData+3] - '0';
     Temp01 = OS4000Data[NextData+5] - '0';
     NextData += 6;
   }
   else if ( OS4000Data[NextData+3] == '.' ){
     Temp1 = OS4000Data[NextData+2] - '0';
     Temp01 = OS4000Data[NextData+4] - '0';
     NextData += 5;
   }
   Temp = - ( 1000Temp100 + 100Temp10 + 10Temp1 + Temp01 );
 }
 else
 {
   if ( OS4000Data[NextData+4] == '.' ){
     Temp100 = OS4000Data[NextData+1] - '0';
     Temp10 = OS4000Data[NextData+2] - '0';
     Temp1 = OS4000Data[NextData+3] - '0';
     Temp01 = OS4000Data[NextData+5] - '0';
     NextData += 6;
   }
   else if ( OS4000Data[NextData+3] == '.' ){
     Temp10 = OS4000Data[NextData+1] - '0';
     Temp1 = OS4000Data[NextData+2] - '0';
     Temp01 = OS4000Data[NextData+4] - '0';
     NextData += 5;
   }
   else if ( OS4000Data[NextData+2] == '.' ){
     Temp1 = OS4000Data[NextData+1] - '0';
     Temp01 = OS4000Data[NextData+3] - '0';
     NextData += 4;
   }
   Temp = ( 1000
Temp100 + 100Temp10 + 10Temp1 + Temp01 );
 }
}

void WireSendInt (int val)
{
 byte buf [2];
 buf [0] = val >> 8;
 buf [1] = val & 0xFF;
 Wire.send (buf, 2);
}

void WireSendAll ()
{
 byte buf [8];
 buf [0] = Heading >> 8;
}


the Extract_Info() is totaly corect
it is always updates corectly the 
Heading PItch Roll Temp
i have check it with uart output

also i have tried 

§DISCOURSE_HOISTED_CODE_1§

#include <Wire.h>
#define requestdelay 10

int heading;
byte headingMSB;
byte headingLSB;

int pitch;
byte pitchMSB;
byte pitchLSB;

int roll;
byte rollMSB;
byte rollLSB;

int temp;
byte tempMSB;
byte tempLSB;

void setup(){
  Wire.begin();
  Serial.begin(9600);
}

void loop(){

  Wire.beginTransmission(2);
  Wire.send('C');
  Wire.endTransmission();
  delay(200);

  Wire.beginTransmission(2);
  Wire.send('H');
  Wire.endTransmission();
  Wire.requestFrom(2,2);
  delay(requestdelay);
  if ( Wire.available() > 1 )
  {
    headingMSB = Wire.receive();
    headingLSB = Wire.receive();
    heading = ( ( headingMSB<<8 ) | ( headingLSB ) ); 
    Serial.print("H: ");
    Serial.print(heading);
    Serial.print("  ");
  }

  Wire.beginTransmission(2);
  Wire.send('P');
  Wire.endTransmission();
  Wire.requestFrom(2,2);
  delay(requestdelay);
  if ( Wire.available() > 1 )
  {
    pitchMSB = Wire.receive();
    pitchLSB = Wire.receive();
    pitch = ( ( pitchMSB<<8 ) | ( pitchLSB ) ); 
    Serial.print("P: ");
    Serial.print(pitch);
    Serial.print("  ");
  }

  Wire.beginTransmission(2);
  Wire.send('R');
  Wire.endTransmission();
  Wire.requestFrom(2,2);
  delay(requestdelay);
  if ( Wire.available() > 1 )
  {
    rollMSB = Wire.receive();
    rollLSB = Wire.receive();
    roll = ( ( rollMSB<<8 ) | ( rollLSB ) ); 
    Serial.print("R: ");
    Serial.print(roll);
    Serial.print("  ");
  }

  Wire.beginTransmission(2);
  Wire.send('T');
  Wire.endTransmission();
  Wire.requestFrom(2,2);
  delay(requestdelay);
  if ( Wire.available() > 1 )
  {
    tempMSB = Wire.receive();
    tempLSB = Wire.receive();
    temp = ( ( tempMSB<<8 ) | ( tempLSB ) ); 
    Serial.print("T: ");
    Serial.print(temp);
    Serial.print("  ");
  }

  Serial.println();
}

My output:

H: 3478 P: 17 R: 17 T: 305
H: 3478 P: 17 R: 17 T: 304
H: 3478 P: 17 R: 17 T: 303
H: 3478 P: 17 R: 17 T: 303
H: 3478 P: 17 R: 17 T: 305
H: 3478 P: 17 R: 17 T: 306
H: 3478 P: 17 R: 17 T: 307
H: 3478 P: 17 R: 17 T: 307
H: 3478 P: 17 R: 17 T: 306
H: 0 P: 17 R: 17 T: 304
H: 3478 P: 17 R: 17 T: 304
H: 3478 P: 17 R: 17 T: 303
H: 3478 P: 17 R: 17 T: 303
H: 3478 P: 17 R: 17 T: 305
H: 3478 P: 17 R: 17 T: 306
H: 3478 P: 17 R: 17 T: 307
H: 3478 P: 17 R: 17 T: 308
H: 3478 P: 17 R: 17 T: 308
H: 3478 P: 17 R: 17 T: 308
H: 3478 P: 0 R: 17 T: 309
H: 3478 P: 17 R: 17 T: 309
H: 3478 P: 17 R: 17 T: 309
H: 3478 P: 17 R: 17 T: 309
H: 3478 P: 17 R: 17 T: 308
H: 3478 P: 17 R: 17 T: 308
H: 3478 P: 17 R: 17 T: 308
H: 3478 P: 17 R: 17 T: 308
H: 3478 P: 17 R: 17 T: 306
H: 3478 P: 17 R: 17 T: 305

it is not periodic
and not always on the same output (heading,pitch,roll,temp)

its 0 because the receiver never gets two bytes

*this is checked becase if i use

while ( Wire.available() < 2 ){}

it frezzes

thanks a lot

  Wire.endTransmission();
  Wire.requestFrom(2,2);
  delay(requestdelay);

First off this delay where you have it does absolutely nothing. If you are trying to put a delay between sending a command and requesting data the delay needs to be:

  Wire.endTransmission();
  delay(requestdelay);
  Wire.requestFrom(2,2);

Once Wire.requestFrom is finished the data has already been read from the slave into the master. In other words Wire.receive() doesn't actually "receive" any data from the slave device, it just reads data from the buffer in the master device that was already received.

One of the things I've found with the Wire library that I don't like is that there is no error checking for Wire.requestFrom() like there is for Wire.endTransmission(). Wire.endTransmission() will return a 0 if communication was successfully completed and return other numbers if there was a problem. Wire.requestFrom() returns the number of bytes received from the slave device. With that being said using Wire.available() to check if you received 2 bytes back is completely pointless since you can see that from the returned value from Wire.requestFrom(). Now how can you use this information to help fix your problem? "If at first you don't succeed...try try again" (I think I got that quote right) so here's what I usually do:

for(int i = 0; i < 3;i++){
  if(Wire.requestFrom(2,2)){break;}
}

Basically it will attempt to request the data three times before it fails. It's been my experience to use as much error checking as possible when using I2C between two Arduinos. Obviously you can change the 3 to whatever you want. Good luck.

delay(requestdelay);

I would get rid of all of those. I don't see what they achieve except to make it more likely you will miss out on incoming data.

void ReceiveCommand(int howMany)
{
  while(!Wire.available());
  command = Wire.receive();
}

You DON'T NEED this:

  while(!Wire.available());

This is an interrupt service routine. It is called if there is something to receive. The variable "howMany" tells you how much you received. A loop here is pointless.

I am guessing your real problem is this:

void loop(){

  Wire.beginTransmission(2);
  Wire.send('C');
  Wire.endTransmission();
  delay(200);

  Wire.beginTransmission(2);
  Wire.send('H');
  Wire.endTransmission();

The first thing you send is 'C', right? And it usually fails on 'H'?

Now the 'C' command is what triggers off reading from your gadget, 127 bytes of it. I calculate it will take around 22 mS alone just to read the data at that baud rate, and then you do Check_Sentence and Extract_Info on it.

My guess is that the other end just isn't ready in the 200 mS you give it (perhaps it is looking for that '$' you are looping looking for). So sometimes it just isn't ready when you hit it with the 'H' command. So it sends nothing back. I would try increasing the delay somewhat, just to see what happens. Just that single delay(200).

It might be better to do something like:

do
  {
  Wire.beginTransmission(2);
  Wire.send('H');
  Wire.endTransmission();
  Wire.requestFrom(2,2);
  } while (Wire.available() < 2);

Note that this is different from what you had before. This example actually re-requests the data if we don't get a reply length 2 back. So it will eventually succeed.

And I would lose all the "2" magic numbers. How about making a define? That way if you ever decide to change 2 to 3 you won't have to go through all the code. Something like:

#define SLAVE_ADDRESS 2

do
  {
  Wire.beginTransmission(SLAVE_ADDRESS);
  Wire.send('H');
  Wire.endTransmission();
  Wire.requestFrom(SLAVE_ADDRESS,2);
  } while (Wire.available() < 2);

Don't you think it is confusing having:

Wire.requestFrom(2,2);

... where one of those "2" is the slave address, and the other "2" is the number of bytes? A lot of scope for future error there.

first if all thanks for you replies

the second code is just to test the first code

the i2c readout it will be done by an FPGA


thats why i dont have the

#define SLAVE_ADDRESS 2

as i have on the first one

#define I2C_Address 2

and everything is on a loop


Now 200ms i think its enought
it is working and on 100ms

I also have tested at 500ms and i have the same issues

when you send the C "Capture-Convert" command

1- the programm listens the Uart and seeking for the '$'
2- after he finds it - fills in the Uart buffer
3- resets to 0 the heading
4- updates the heading
5- resets to 0 the pitch
6 - udates the pitch
7- resets to 0 the roll
8 - udates the roll
9- resets to 0 the temp
10 - udates the temp

then if you just send again the C command it will do the same
or if you send another command it has to reply back with some data

i might have to use that

Wire.endTransmission();
  delay(requestdelay);
  Wire.requestFrom(2,2);

as you suggest me

because the programm might not have the time to do that :

void ReceiveCommand(int howMany)
{
  while(!Wire.available());
  command = Wire.receive();
}

tanks again

the reader does not receive the two bytes ( thats why it freezes with while command ) and it is not receiving two zero bytes

herctrap:
Now 200ms i think its enought
it is working and on 100ms

I also have tested at 500ms and i have the same issues

I am confused. Is it working or not? You say "it is working" ... "I have the same issues".

Did you try my suggested code (to re-request the "H" data)?

herctrap:

void ReceiveCommand(int howMany)

{
  while(!Wire.available());
  command = Wire.receive();
}




the reader does not receive the two bytes ( thats why it freezes with while command ) and it is not receiving two zero bytes

If it enters ReceiveCommand then there is definitely something available. So the "while" achieves nothing. It doesn't wait for more, it achieves nothing.

Do yourself a favour and rework this:

  Heading100 = 0;
  Heading10 = 0;
  Heading1 = 0;
  Heading01 = 0;
  if ( OS4000Data[8] == '.' ){
    Heading100 = OS4000Data[5] - '0';
    Heading10 = OS4000Data[6] - '0';
    Heading1 = OS4000Data[7] - '0';
    Heading01 = OS4000Data[9] - '0';
    NextData = 10;
  }
  else if ( OS4000Data[7] == '.' ){
    Heading10 = OS4000Data[5] - '0';
    Heading1 = OS4000Data[6] - '0';
    Heading01 = OS4000Data[8] - '0';
    NextData = 9;
  }
  else if ( OS4000Data[6] == '.' ){
    Heading1 = OS4000Data[5] - '0';
    Heading01 = OS4000Data[7] - '0';
    NextData = 8;
  }
  Heading = 1000*Heading100 + 100*Heading10 + 10*Heading1 + Heading01;

The variable Heading is an int. Why are you even bothering with decimal places?

Try something simpler like:

float Heading = atof ("123.34");

or:

int Heading = atoi ("123.34");

this seems to work

Wire.beginTransmission(2);
  Wire.send('P');
  Wire.endTransmission();
  delay(requestdelay);
  Wire.requestFrom(2,2);
  if ( Wire.available() > 1 )
  {
    pitchMSB = Wire.receive();
    pitchLSB = Wire.receive();
    pitch = ( ( pitchMSB<<8 ) | ( pitchLSB ) ); 
    Serial.print("P: ");
    Serial.print(pitch);
    Serial.print("  ");
  }

with requestdelay at 25ms

thanks a lot for you replies


i am not sure how to use atof and atoi

this is my uart input:

$OHPR,346.2,1.0,1.8,30.6,0.0000,168.01,-163.19,-39.50,-5.94,1.011,0.019,0.033,1.010,0.00,-0.01,-0.01,48145S0*59

$OHPR,346.2,1.0,1.8,30.6,0.0000,168.00,-163.18,-39.50,-5.95,1.011,0.018,0.033,1.010,0.00,-0.01,-0.01,48146S0*5A

$OHPR,346.2,1.0,1.8,30.6,0.0000,168.02,-163.20,-39.50,-5.98,1.011,0.019,0.033,1.010,0.00,-0.01,-0.01,48147S0*5E

$OHPR,heading,pitch,roll,temp,depth, ..... .......,gyroX*