Servo will eventully crash board - potential problem with my code being unstable

Hi guys

What I’m trying to do is pass 3 characters through the serial and have these interpreted as an angle. This angle is then passed to the servo to move it.

 /*
Communicate */

#include <Servo.h> 

Servo myservo;  // create servo object to control my servo 
char byteread; //Char to hold the incoming byte from serial
int angle; //int to hold servo angle
int i = 0; //int to hold a counter variable
  
void setup() 
{ 
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  Serial.begin(9600); //begins serial communication
} 


void loop() 
{ 
  
  if (Serial.available()){
    delay(100);
    while(Serial.available()>0)

    {
    i=i++; // counter to determine which character is incoming from serial (looks for 3 in total)
    
    byteread = Serial.read() - '0'; // read current character
 
      
    // if statements to determine the byte
    if (i == 3){ //final counter variable the angle 
    angle = angle + byteread; //integer = byte * 1 
    
    angle = constrain(angle,0,180); // constrain movement angle to prevent inputs out of range for servo
    Serial.println(angle);
    Serial.println("Servo about to move");
    myservo.write(angle); // move servo
    Serial.print("Servo Moved");
    delay(15);
    angle = 0; // reset angle for next 3 character input
    i = 0; // reset counter for next 3 character input
    Serial.print(" : Loop Finished : ");
    }
    else if (i == 2){
    angle = angle + (byteread * 10); // integer = byte x 10 ( 2nd character)
    }
    else if (i == 1){
    angle = angle + (byteread * 100); // integer = byte x 100 (1st character)
    } 
} 
}
}

If i comment out the servo code and upload it the angle return works fine (again and again), however if i move the servo it seems to cause instability. It works but eventually crashes with the following error.

java.io.IOException: Input/output error in writeArray
	at gnu.io.RXTXPort.writeArray(Native Method)
	at gnu.io.RXTXPort$SerialOutputStream.write(RXTXPort.java:1124)
	at processing.app.Serial.write(Serial.java:517)
	at processing.app.Serial.write(Serial.java:540)
	at processing.app.SerialMonitor.send(SerialMonitor.java:200)
	at processing.app.SerialMonitor.access$100(SerialMonitor.java:32)
	at processing.app.SerialMonitor$3.actionPerformed(SerialMonitor.java:89)
	at javax.swing.JTextField.fireActionPerformed(JTextField.java:492)
	at javax.swing.JTextField.postActionEvent(JTextField.java:705)
	at javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:820)
	at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1636)
	at javax.swing.JComponent.processKeyBinding(JComponent.java:2851)
	at javax.swing.JComponent.processKeyBindings(JComponent.java:2886)
	at javax.swing.JComponent.processKeyEvent(JComponent.java:2814)
	at java.awt.Component.processEvent(Component.java:6040)
	at java.awt.Container.processEvent(Container.java:2041)
	at java.awt.Component.dispatchEventImpl(Component.java:4630)
	at java.awt.Container.dispatchEventImpl(Container.java:2099)
	at java.awt.Component.dispatchEvent(Component.java:4460)
	at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
	at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:704)
	at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:969)
	at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:841)
	at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:668)
	at java.awt.Component.dispatchEventImpl(Component.java:4502)
	at java.awt.Container.dispatchEventImpl(Container.java:2099)
	at java.awt.Window.dispatchEventImpl(Window.java:2475)
	at java.awt.Component.dispatchEvent(Component.java:4460)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

I’m scratching my head to this one as i cant see why its unstable, however i am fairly amateurish at this. Any help or guidance that you guys could provide would be very welcome. That may be a more robust approach or improving the above code.

Thanks

Steve

If you are trying to power the servo from the Arduino, don't. Use a separate power supply capable of supplying 1 ampere per straining servo.

Here is an easier way to get a number from Serial.

The problem is nothing to do with your sketch - that is a Java stack trace from an exception occurring within a Processing application running on the PC. What application is that - is it the Arduino IDE, or something else?

Simple servo testing code for use with the serial monitor.

// zoomkat 10-22-11 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// for IDE 0022 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

String readString;
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);
  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7, 500, 2500);  //the pin for the servo control, and range if desired
  Serial.println("servo-test-22-dual-input"); // so I can keep track of what is loaded
}

void loop() {
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string 
    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);
      myservo.writeMicroseconds(n);
    }
    else
    {   
      Serial.print("writing Angle: ");
      Serial.println(n);
      myservo.write(n);
    }

    readString=""; //empty for next input
  } 
}
 if (i == 3){ //final counter variable the angle 
    angle = angle + byteread; //integer = byte * 1

This part of your program interprets only the last byte read as ("some character's ascii value" - "the ascii value of the character 0") and adds it to the variable angle. However, the comments suggest that you intended all 3 ascii bytes to be interpreted as a number.

Guys,

Real big thank-you for your replies. It gave me somewhere to start. To let you know what i have done;

I tried the servo test code you provided zoomkat and retrieved the same error.

I wrote an application in visual basic studio (vb.net) to interact with the serial com port. This works fine without any errors so perhaps its the Arduino IDE? (thanks PeterH)

Would re installing the Arduino software potentially fix this?

I know as well not to power the servo from the board with some load!

Cheers
Steve