Reading Continuous Serial Packets

Ran new Test code same problem. Shows proper code initially then misses.

7 below will help you.

http://arduino.cc/forum/index.php/topic,148850.0.html

Number 7 is the code tags. Please put your code between the code tags.

I have some serious problems with your code. The problem is the data flow. Perhaps you can make a abstract drawing of how you want the data flow, without thinking about interrupts or so. After that, make your sketch according to your drawing.

To make it work, make it very simple. Don't use the event in the slave, just check the Wire.available() in the loop and print it. If that is okay, you can use the receiveEvent, but make the code simpler. You have a while that is probably skipped every time, since the I2C data is received one byte after one byte (the I2C 100kHz clock is slow).

Erdin

I don't think the problem lies with the slave code the slave will putout or print what is given by the master. It appears to be some timing issue on the Master, maybe due to code execution time.

I'm concerned with how the serial buffer is filled and when a character is read or pulled off. Is it loaded with the next new and then holds for a new read before it loads again or does it get to 64 bytes and start dropping unread characters.

I'm perplexed is there a good manual on Arduino's syntax codes that you know of, I'm learning while doing :).

I did install a USB monitor on the Master computer to monitor the code sent to the Master Arduino, BFF's packets are solid.

Good to hear the BFF packets are okay.

About the programming, I am kind of lost there. I don't know what you want to do anymore. I was serious about the code tags, the data flow and the Wire.available() in a loop.

About the Serial communication: Received data is placed into a buffer. The Serial.available() return the number of bytes in the buffer. Using Serial.read() return a byte from the buffer and lowers the number of available bytes. I didn't know what would happen if the buffer overflows, so I made a test sketch:

void setup() 
{
  Serial.begin( 9600);
  Serial.println("Start");
  delay( 10000 );

  Serial.println("Received:");
  while( Serial.available() > 0)
  {
    Serial.print( (char) Serial.read());
  }
}

void loop() 
{
   ;
}

During the 10 seconds wait time, I copied a very long line to the serial monitor. After that it prints only the first 64 characters. -> correction, it was 63 with Arduino 1.5.2 and Uno.

Conclusion: If the buffer is full, the received characters are discarded.

http://arduino.cc/en/Reference/serial http://arduino.cc/en/Reference/Wire

Erdin

Here what the Sim software needs to do

Master: It needs to be able to read BFF's packets into the Master controller.

Out of the packet of the packet the Master needs to get each actuator value ie AB153765320535313 where in this case Act1=53 Act2=76 Act3=53 Act4=20 Act5=53 Act6=53.

Each actuator value needs to be sent the its Slave controller.

Slave:

The slave controller will need to read the value and evaluate it against the motor's potentiometer (pot) value and turn the motor on in the direction where its pot value will head towards the actuator value ie Act1. That would be either forward, reverse or stop if Act1 is equal to the pot. This would be looped where the motor pot value chases the Act1 value.

Thats Basically it.

I got it the # button for code sorry about that, Im trying the quote.

the data flow and the Wire.available() in a loop.

Dont follow are you say I would only need it once and do the reads there after?

[quoteDuring the 10 seconds wait time, I copied a very long line to the serial monitor. After that it prints only the first 64 characters.

Conclusion: If the buffer is full, the received characters are discarded. ][/quote]

So therefore if Arduino fills the buffer one byte at a time and its full, Bff's bytes will be lost. And the next Bff byte to go into the buffer on the next read (making space available) will in fact be out of sequence. Is that whats happening? Sounds like I need to slow down how fast Bff send it's bytes where the buffer never fills.

here is how I collect and use servo control data received via the serial port. The servo data packets are delimited by a comma.

//zoomkat 11-22-12 simple delimited ',' string parse 
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added 

String readString;
#include <Servo.h> 
Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo 

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

  //myservoa.writeMicroseconds(1500); //set initial servo position if desired

  myservoa.attach(6);  //the pin for the servoa control
  myservob.attach(7);  //the pin for the servob control
  myservoc.attach(8);  //the pin for the servoc control
  myservod.attach(9);  //the pin for the servod control 
  Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}

void loop() {

  //expect single strings like 700a, or 1500c, or 2000d,
  //or like 30c, or 90a, or 180d,
  //or combined like 30c,180b,70a,120d,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      if (readString.length() >1) {
        Serial.println(readString); //prints string to serial port out

        int n = readString.toInt();  //convert readString into a number

        // auto select appropriate value, copied from someone elses code.
        if(n >= 500)
        {
          Serial.print("writing Microseconds: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
          if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
          if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
          if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
        }
        else
        {   
          Serial.print("writing Angle: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.write(n);
          if(readString.indexOf('b') >0) myservob.write(n);
          if(readString.indexOf('c') >0) myservoc.write(n);
          if(readString.indexOf('d') >0) myservod.write(n);
        }
         readString=""; //clears variable for new input
      }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

The message protocol looks pretty straight forward and makes it easy to detect the start and end of a message. On the serial side I suggest you need to explicitly find the start and end of each message. I think the best way to implement that is as a state machine which keeps track of where you are within the current message and the most obvious way to represent state is as the byte offset with the current message. With this approach you don't actually need to buffer the messages since you can process and then discard each byte as it arrives.

// incomplete, untested
if(Serial.available())
{
  byte val = Serial.read();

  switch(state)
  {
    case 0:
      if(val == 'A')
      {
        state++;
      }
      else
      {
        // not the expected character
        state = 0;
      }
      break;
    case 2:
      if(val == 'B')
      {
        state++;
      }
      else
      {
        // not the expected character
        state = 0;
      }
      break;
    case 2 .. 8:
      sendActuatorValue(state-2, val);
      state++;
      break;
    default:
      // end of message
      state = 0;
  }
}

It seems that the values you're sending to each slave consist of a single byte so you don't need any fancy encoding there, just write a byte containing the new value for the actuator.

If it's only dealing with serial input the master device will be almost idle. What's the nature of the interface between each slave and its actuator? Have you ruled out driving these directly from the master? If feasible, that would simplify your solution considerably.