After i run the ComArduino2.py from my pc terminal, i'm getting following error:
Serial port /dev/ttyACM0 opened Baudrate 9600
Arduino is ready
Sent from PC -- LOOP NUM 0 TEST STR <LED1,200,0.2>
Reply Received Msg LED1 NewFlash 200 SrvFrac 0.20 SrvPos 42 Time 1
===========
Traceback (most recent call last):
File "pyserial.py", line 170, in <module>
runTest(testData)
File "pyserial.py", line 118, in runTest
sendToArduino(teststr)
File "pyserial.py", line 60, in sendToArduino
ser.write(sendStr)
File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 489, in write
raise SerialException('write failed: %s' % (v,))
serial.serialutil.SerialException: write failed: [Errno 5] Input/output error
I am using ubuntu 14.04, xenomai patched linux, arduino uno, with latest arduino ide.
I was following this link.
When i don't connect the servo, the program runs fine. But after i connect the servo and attach it with pin 8, it shows above error.
#include <Servo.h>
Servo myServo;
byte servoPin = 3;
byte servoMin = 10;
byte servoMax = 170;
byte servoPos = 0;
byte newServoPos = servoMin;
const byte numLEDs = 2;
byte ledPin[numLEDs] = {12, 13};
unsigned long LEDinterval[numLEDs] = {200, 400};
unsigned long prevLEDmillis[numLEDs] = {0, 0};
const byte buffSize = 40;
char inputBuffer[buffSize];
const char startMarker = '<';
const char endMarker = '>';
byte bytesRecvd = 0;
boolean readInProgress = false;
boolean newDataFromPC = false;
char messageFromPC[buffSize] = {0};
int newFlashInterval = 0;
float servoFraction = 0.0; // fraction of servo range to move
unsigned long curMillis;
unsigned long prevReplyToPCmillis = 0;
unsigned long replyToPCinterval = 1000;
//=============
void setup() {
Serial.begin(9600);
// flash LEDs so we know we are alive
for (byte n = 0; n < numLEDs; n++) {
pinMode(ledPin[n], OUTPUT);
digitalWrite(ledPin[n], HIGH);
}
delay(500); // delay() is OK in setup as it only happens once
for (byte n = 0; n < numLEDs; n++) {
digitalWrite(ledPin[n], LOW);
}
// initialize the servo
myServo.attach(servoPin);
moveServo();
// tell the PC we are ready
Serial.println("<Arduino is ready>");
}
//=============
void loop() {
curMillis = millis();
getDataFromPC();
updateFlashInterval();
updateServoPos();
replyToPC();
flashLEDs();
moveServo();
}
//=============
void getDataFromPC() {
// receive data from PC and save it into inputBuffer
if(Serial.available() > 0) {
char x = Serial.read();
// the order of these IF clauses is significant
if (x == endMarker) {
readInProgress = false;
newDataFromPC = true;
inputBuffer[bytesRecvd] = 0;
parseData();
}
if(readInProgress) {
inputBuffer[bytesRecvd] = x;
bytesRecvd ++;
if (bytesRecvd == buffSize) {
bytesRecvd = buffSize - 1;
}
}
if (x == startMarker) {
bytesRecvd = 0;
readInProgress = true;
}
}
}
//=============
void parseData() {
// split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(inputBuffer,","); // get the first part - the string
strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
newFlashInterval = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
servoFraction = atof(strtokIndx); // convert this part to a float
}
//=============
void replyToPC() {
if (newDataFromPC) {
newDataFromPC = false;
Serial.print("<Msg ");
Serial.print(messageFromPC);
Serial.print(" NewFlash ");
Serial.print(newFlashInterval);
Serial.print(" SrvFrac ");
Serial.print(servoFraction);
Serial.print(" SrvPos ");
Serial.print(newServoPos);
Serial.print(" Time ");
Serial.print(curMillis >> 9); // divide by 512 is approx = half-seconds
Serial.println(">");
}
}
//============
void updateFlashInterval() {
// this illustrates using different inputs to call different functions
if (strcmp(messageFromPC, "LED1") == 0) {
updateLED1();
}
if (strcmp(messageFromPC, "LED2") == 0) {
updateLED2();
}
}
//=============
void updateLED1() {
if (newFlashInterval > 100) {
LEDinterval[0] = newFlashInterval;
}
}
//=============
void updateLED2() {
if (newFlashInterval > 100) {
LEDinterval[1] = newFlashInterval;
}
}
//=============
void flashLEDs() {
for (byte n = 0; n < numLEDs; n++) {
if (curMillis - prevLEDmillis[n] >= LEDinterval[n]) {
prevLEDmillis[n] += LEDinterval[n];
digitalWrite( ledPin[n], ! digitalRead( ledPin[n]) );
}
}
}
//=============
void updateServoPos() {
byte servoRange = servoMax - servoMin;
if (servoFraction >= 0 && servoFraction <= 1) {
newServoPos = servoMin + ((float) servoRange * servoFraction);
}
}
//=============
void moveServo() {
if (servoPos != newServoPos) {
servoPos = newServoPos;
myServo.write(servoPos);
}
}
and Comarduino2.py:
def sendToArduino(sendStr):
ser.write(sendStr)
#======================================
def recvFromArduino():
global startMarker, endMarker
ck = ""
x = "z" # any value that is not an end- or startMarker
byteCount = -1 # to allow for the fact that the last increment will be one too many
# wait for the start character
while ord(x) != startMarker:
x = ser.read()
# save data until the end marker is found
while ord(x) != endMarker:
if ord(x) != startMarker:
ck = ck + x
byteCount += 1
x = ser.read()
return(ck)
#============================
def waitForArduino():
# wait until the Arduino sends 'Arduino Ready' - allows time for Arduino reset
# it also ensures that any bytes left over from a previous message are discarded
global startMarker, endMarker
msg = ""
while msg.find("Arduino is ready") == -1:
while ser.inWaiting() == 0:
pass
msg = recvFromArduino()
print msg
print
#======================================
def runTest(td):
numLoops = len(td)
waitingForReply = False
n = 0
while n < numLoops:
teststr = td[n]
if waitingForReply == False:
sendToArduino(teststr)
print "Sent from PC -- LOOP NUM " + str(n) + " TEST STR " + teststr
waitingForReply = True
if waitingForReply == True:
while ser.inWaiting() == 0:
pass
dataRecvd = recvFromArduino()
print "Reply Received " + dataRecvd
n += 1
waitingForReply = False
print "==========="
time.sleep(5)
#======================================
# THE DEMO PROGRAM STARTS HERE
#======================================
import serial
import time
print
print
# NOTE the user must ensure that the serial port and baudrate are correct
serPort = "/dev/ttyACM0"
baudRate = 9600
ser = serial.Serial(serPort, baudRate)
print "Serial port " + serPort + " opened Baudrate " + str(baudRate)
startMarker = 60
endMarker = 62
waitForArduino()
testData = []
testData.append("<LED1,200,0.2>")
testData.append("<LED1,800,0.7>")
testData.append("<LED2,800,0.5>")
testData.append("<LED2,200,0.2>")
testData.append("<LED1,200,0.7>")
runTest(testData)
ser.close
It is same as the files provided by the link described in the link given in question. This kind of error i.e input output error, also used to come when i was using ros_serial and ros_arduino_bridge, when communicating arduino with ros nodes. Firs the servo moves, than suddently error comes.
The program is same as i've given above. The problem is that after attaching servo motors, i got the error. At first, when i run the python program, the servo moves, than the error comes. Than i don't know somehow the port name changes from /dev/ttyACM0 to /dev/ttyACM1 and it contenious. If i again remove and reinsert the usb cable, than again the port name changes to /dev/ttyACM0. I am using python 2.7.
dineshlama:
The program is same as i've given above. The problem is that after attaching servo motors, i got the error. At first, when i run the python program, the servo moves, than the error comes. Than i don't know somehow the port name changes from /dev/ttyACM0 to /dev/ttyACM1 and it contenious.
That sounds like you are powering the servo from the Arduino 5v pin and it is drawing too much current which causes the voltage to fall and the Arduino to reset - hence the change of port. It can also damage the Arduino.
Give the servos a separate power supply with the servo GND connected to the Arduino GND.
Ok thanks, solved the problem. Since the servo motor didn't have mentioned any current specification in its document, i forgot about the current and only saw the voltage. I am using this motor.