Analog value glitch in serial communications

I'm trying to learn how to send analog values from one Arduino to another. The first one gathers data from a potentiometer, processes and sends that data, and the second one prints that value to an LED on pin 13. The data seems to be exiting the first arduino perfectly fine, but there seems to be a problem somewhere in the second arduino. The LED will begin to light up as the POT turns as intended, but it maxes out at a very dim level. Then the RX and TX pins will light up, at which point the arduino becomes unresponsive and I need to cut power to regain control of the board.

Here is the transmitter code:

int led13 = 13;

void setup(){ 
  Serial1.begin(9600);
}

void loop(){
    transmitAnalog();
}


void transmitAnalog(){
    int analogPin = analogRead(A0);
    int analogValue = map(analogPin,0,1023,0,255);
    analogWrite(led13, analogValue);
    Serial1.write(led13);
    Serial1.write(analogValue);
}

and here's the receiver code:

int led13 = 13;

void setup(){
  Serial1.begin(9600);
  pinMode(led13, OUTPUT);
}

void loop(){
    receiveDataAnalog();
}


void receiveDataAnalog(){
   int updateReceived;
   if (Serial1.available()>1){
   led13 = Serial1.read(); 
   int analogValue = Serial1.read(); 
   updateReceived = 1;
   } 
   if (updateReceived == 1){
   updateReceived = 0;
   analogWrite(led13, analogValue);
   }
}

Also just so the moderators don't need to clean up after me anymore, how to I properly format the code into those convenient text boxes that code is always displayed in?

#7 below

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

Ok thanks for that. No more moderators cleaning up after me! Now ass for the code itself...

You write two bytes to serial and you read two bytes from serial. How do you make sure you are reading byte 1 and then byte 2, instead of byte 2 and then byte 1 from the next transmission? You should try to send number in plane text and separate them with comma, then end the second number with a new line. On the receiving end you read until you get the new line, then parse the two numbers. Even better, you start with a start character such as 'A' and end with '\n'. This way your receiver can determine if it receives a complete sentence. Your send/receive is unreliable and anything could happen so trying to explain why the arduino hangs is pointless. I'll see if I can dig up some sample code so you can test on.

void loop(){
    transmitAnalog();
}

loop() will run much faster than Serial communication, so the buffer will fill up and overflow quickly. Send the data as a much lower frequency.

    int analogValue = map(analogPin,0,1023,0,255);

Kind of a long winded way of a simple right shift by 2.

    Serial1.write(led13);
    Serial1.write(analogValue);

What happens when one byte is missed and they get out of sync? You should be using start and end of packet marker to keep everything in sync.

If the write buffer overflows I suppose the next call traps until there is space in the buffer again. I'm talking about arduino IDE 1.0.x

Below is some servo/pot test code setup with a delay and deadband so the output is easily visible in the serial monitor for testing. You don’t need a servo attached to see the output in the serial monitor. For testing, you might start with a simple delay in your sending code to slow the looping down.

//zoomkat dual pot/servo test 12-29-12
//view output using the serial monitor

#include <Servo.h> 
Servo myservo1;
Servo myservo2;

int potpin1 = 0;  //analog input pin A0
int potpin2 = 1;

int newval1, oldval1;
int newval2, oldval2;

void setup() 
{
  Serial.begin(9600);  
  myservo1.attach(2);  
  myservo2.attach(3);
  Serial.println("testing dual pot servo");  
}

void loop() 
{ 
  newval1 = analogRead(potpin1);           
  newval1 = map(newval1, 0, 1023, 0, 179); 
  if (newval1 < (oldval1-2) || newval1 > (oldval1+2)){  
    myservo1.write(newval1);
    Serial.print("1- ");
    Serial.println(newval1);
    oldval1=newval1;
  }

  newval2 = analogRead(potpin2);
  newval2 = map(newval2, 0, 1023, 0, 179);
  if (newval2 < (oldval2-2) || newval2 > (oldval2+2)){  
    myservo2.write(newval2);
    Serial.print("2- ");    
    Serial.println(newval2);
    oldval2=newval2;
  }
  delay(50);
}

Yes indeed I plugged a few 50mSec delays into the transmit code after byte 1 and byte 2 and that seems to have made it work perfectly. Evidently the theory that the loop speed vs. subroutine speed was correct. So I need to either tinker with the delays and find out how short of a delay I can get away with while keeping the arduino stable or implement a packetizing scheme. I think I’ll tinker with the packetizing scheme since this code will eventually have interrupts and I’ve learned that interrupts don’t play well with delays.

Thanks for the help everybody!

Even better yet! Check this out I got to use a new command! woo!:

/*Transmitter: lines marked with //T are transmitter code,
lines marked with //R are reciever code*/


int led13 = 13; 

void setup(){ 
  Serial1.begin(9600);
}

void loop(){
    transmitAnalog();
}

void transmitAnalog(){
    int analogPin = analogRead(A0);
    int analogValue = map(analogPin,0,1023,0,255);
    analogWrite(led13, analogValue);
    Serial1.flush();
    Serial1.write(led13);
    Serial1.flush();
    Serial1.write(analogValue);
}

Serial1.flush() waits for the register to empty out before loading it up again, at least post Arduino1.0.x. This seems like a simple way to keep the data I'm sending organized.

Interesting use of Serial.flush().

Bosscheesemo:
This seems like a simple way to keep the data I'm sending organized.

Not to me, it doesn't.

Relying on timing to indicate which bytes are part of the same message and where message boundaries are is not a good approach. It is far, far better to use a message encoding scheme that explicitly tells you where each message starts and ends. A very simple encoding scheme that is easy to develop and test is to send your values as an ascii string containing a sequence of comma separated values, with messages separated by an end-of-line character. This is very convenient to enter using the Arduino IDE Serial monitor or any other serial interface, and can also be printed directly to help test/debug your code.

On the sending side you would just use print() to print the values and comma separators, and println() to end each message.

On the receiving side you would just receive bytes as they become available, buffer them until you reach the end-of-line, and then parse the buffer using scanf(), strtok(), atol() and so on to extract your values.

If you want to continue using a binary encoding scheme then you can separate messages in other ways, for example by defining a reserved value (e.g. 0x00 or 0xff) which you know will not be included in your data and using that to terminate each message. If there is no such reserved value then you would need a slightly more complex encoding scheme. In any case I'd suggest that a textual encoding scheme is the better way to go, rather than binary.