Posts: 10
Threads: 2
Joined: Mar 2018
I am trying to read the output of MPU6050 connected to Arduino using Python so that I could do vibration measurement of the motor. I am able to split and also convert the string to float and get all 6 values (Ax,Ay,Az,Gx,Gy,Gz) but I'm not able to plot it using matplotlib and also the code also stops executing with some errors like:
ValueError: could not convert string to float: '1.01.05\r\n'
or
IndexError: list index out of range
import serial
import matplotlib.pyplot as ply
import numpy
import pylab as py
from drawnow import *
ACCX=[]
ACCY=[]
ACCZ=[]
GYRX=[]
GYRY=[]
GYRZ=[]
arduinodata=serial.Serial('COM3',9600) #port name and baud rate
ply.ion()
def makeplotting():
ply.ylabel('ACCX (°/sec)')
ply.xlabel('Time')
ply.plot(ACCX)
while True:
while(arduinodata.inWaiting()==0):
pass
arduinostring=arduinodata.readline()
arduinostring=str(arduinostring,encoding="utf-8")
dataArray=arduinostring.split(',')
accxtemp=float(dataArray[0])
ACCX.append(accxtemp)
drawnow(makeplotting)
Posts: 8,156
Threads: 160
Joined: Sep 2016
Please, post full traceback in error tags.
Also - collect some sample data, as they come from arduino, without transforming them. This will help to better understand the format and also will allow to test the script (the part to parse the data)
Posts: 10
Threads: 2
Joined: Mar 2018
Mar-28-2018, 07:35 AM
(This post was last modified: Mar-28-2018, 08:37 AM by buran.)
it says the following:
Error: Traceback (most recent call last):
File "C:\Users\Meena\AppData\Local\Programs\Python\Python36\testpython1.py", line 63, in <module>
accytemp=float(dataArray[1])
IndexError: list index out of range
and the other is as below:
Traceback Error
Regrading the data from Arduino, I am able to get the output after reading the line from arduino as show in this image readline from arduino
but then stops executing as shown
Error message
Posts: 8,156
Threads: 160
Joined: Sep 2016
Mar-28-2018, 08:38 AM
(This post was last modified: Mar-28-2018, 08:38 AM by buran.)
help us to help YOU...
1. Post actual code that cause the error - your code from first post does not match the traceback you post now. The IndexError obviously is due to the fact that after split (at least for some lines) you get a 1-element tuple (i.e. the format of line is different from what you expect).
2. Don't post images - copy/paste in proper tags. Moreover your dropbox links don't work.
3. Provide some sample data
Posts: 10
Threads: 2
Joined: Mar 2018
This is the code
import serial
import matplotlib.pyplot as ply
import numpy #used for mathematical operations
import pylab as py
from mpl_toolkits.mplot3d import Axes3D
from drawnow import *
ACCX=[]
ACCY=[]
ACCZ=[]
GYRX=[]
GYRY=[]
GYRZ=[]
arduinodata=serial.Serial('COM3',9600) #port name and baud rate
fig = ply.figure()
ax = Axes3D(fig)
ply.ion()
def makeplotting():
ply.subplot(611)
ply.ylabel('ACCX (°/sec)')
ply.xlabel('Time')
ply.plot(ACCX)
ply.subplot(612)
ply.ylabel('ACCY (°/sec)')
ply.xlabel('Time')
ply.plot(ACCY)
ply.subplot(613)
ply.ylabel('ACCZ (°/sec)')
ply.xlabel('Time')
ply.plot(ACCZ)
while True:
while(arduinodata.inWaiting()==0):
pass
arduinostring=arduinodata.readline()
arduinostring=str(arduinostring,encoding="utf-8")
dataArray=arduinostring.split(',')
accxtemp=float(dataArray[0])
ACCX.append(accxtemp)
accytemp=float(dataArray[1])
ACCY.append(accytemp)
accztemp=float(dataArray[2])
ACCZ.append(accztemp)
drawnow(makeplotting) This is the error that I get
Error: Traceback (most recent call last):
File "C:\Users\Meena\AppData\Local\Programs\Python\Python36\testpython1.py", line 49, in <module>
accztemp=float(dataArray[2])
IndexError: list index out of range
This is the output i get after the split i.e.,dataArray
Output: ['-0.24', '0.05', '0.91\r\n']
['0.23', '-0.44', '1.14\r\n']
['0.07', '0.01', '1.15\r\n']
['0.18', '-0.12', '0.98\r\n']
['0.12', '-0.04', '0.98\r\n']
['0.12', '-0.03', '0.99\r\n']
['0.11', '-0.01', '1.00\r\n']
['0.10', '-0.02', '1.00\r\n']
['0.11', '0.01', '1.01\r\n']
['0.11', '-0.01', '1.00\r\n']
['0.11', '-0.02', '0.99\r\n']
['0.10', '-0.03', '1.01\r\n']
['0.11', '-0.02', '1.00\r\n']
['0.11', '-0.03', '0.99\r\n']
['0.11', '-0.02', '1.00\r\n']
['0.11', '-0.02', '1.00\r\n']
['0.11', '-0.03', '1.00\r\n']
This is the outuput i get after converting it to float.
These are the values in accxtemp:
Output: 0.1
0.11
0.1
0.11
0.11
0.11
0.11
0.1
0.1
0.1
0.11
0.1
0.11
0.1
0.11
0.1
0.11
0.11
0.11
0.11
0.11
0.11
0.11
0.11
0.11
0.1
I want the output in float so that I can go ahead with plotting.
Posts: 8,156
Threads: 160
Joined: Sep 2016
So with this data, you will not get the error.
Error comes because after split() you don't have 3-element list. Obviously, from time to time, data that comes are incomplete or in slightly different format. One option would be to add an if statement right after line#44 that checks the length of dataArray is 3 before executing rest of the code in the body
One more piece of advise - collect some data in a file, just write what comes from arduino to a file, without split, plotting, etc.
take relativly large sample of data - several thousands lines at least and examine why and when you get data in different format. This will allow you to better parse the data
Posts: 10
Threads: 2
Joined: Mar 2018
I have written that as you said: I think it works like that but the other problem still remains
This is my updated code below:
import serial
import matplotlib.pyplot as ply
import numpy #used for mathematical operations
import pylab as py
from mpl_toolkits.mplot3d import Axes3D
from drawnow import *
ACCX=[]
ACCY=[]
ACCZ=[]
GYRX=[]
GYRY=[]
GYRZ=[]
arduinodata=serial.Serial('COM3',9600) #port name and baud rate
fig = ply.figure()
ax = Axes3D(fig)
ply.ion()
def makeplotting():
ply.subplot(611)
ply.ylabel('ACCX (°/sec)')
ply.xlabel('Time')
ply.plot(ACCX)
ply.subplot(612)
ply.ylabel('ACCY (°/sec)')
ply.xlabel('Time')
ply.plot(ACCY)
ply.subplot(613)
ply.ylabel('ACCZ (°/sec)')
ply.xlabel('Time')
ply.plot(ACCZ)
while True:
while(arduinodata.inWaiting()==0):
pass
arduinostring=arduinodata.readline()
arduinostring=str(arduinostring,encoding="utf-8")
dataArray=arduinostring.split(',')
print (dataArray)
if (len(dataArray)==3):
if (type(float(dataArray[0]))is float):
accxtemp=float(dataArray[0])
ACCX.append(accxtemp)
print (accxtemp)
else:
print ('Data is not in float and hence marked to zero')
dataArray[0]=0.0
accxtemp=float(dataArray[0])
ACCX.append(accxtemp)
print (accxtemp)
if (type(float(dataArray[1]))is float):
accytemp=float(dataArray[1])
ACCY.append(accytemp)
print (accytemp)
else:
print ('Data is not in float and hence marked to zero')
dataArray[1]=0.0
accytemp=float(dataArray[1])
ACCY.append(accytemp)
print (accytemp)
if (type(float(dataArray[2]))is float):
accztemp=float(dataArray[2])
ACCZ.append(accztemp)
print (accztemp)
else:
print ('Data is not in float and hence marked to zero')
dataArray[2]=0.0
accztemp=float(dataArray[2])
ACCZ.append(accztemp)
print (accztemp)
drawnow(makeplotting)
else:
print ('there is some data missing') the oupt of this is:
Output: ['0.66\r\n']
there is some data missing
['-0.72', '-0.15', '0.66\r\n']
-0.72
-0.15
0.66
['-0.72', '-0.15', '0.66\r\n']
-0.72
-0.15
0.66
['-0.72', '-0.15', '0.66\r\n']
-0.72
-0.15
0.66
['-0.72', '-0.15', '0.66\r\n']
-0.72
-0.15
0.66
['-0.72', '-0.15', '0.66\r\n']
-0.72
-0.15
0.66
['-0.72', '-0.15', '0.66\r\n']
-0.72
-0.15
0.66
['-0.-0.72', '-0.15', '0.66\r\n']
Traceback (most recent call last):
File "C:\Users\Meena\AppData\Local\Programs\Python\Python36\testpython1.py", line 47, in <module>
if (type(float(dataArray[0]))is float):
ValueError: could not convert string to float: '-0.-0.72'
Error: Traceback (most recent call last):
File "C:\Users\Meena\AppData\Local\Programs\Python\Python36\testpython1.py", line 47, in <module>
if (type(float(dataArray[0]))is float):
ValueError: could not convert string to float: '-0.-0.72'
Posts: 8,156
Threads: 160
Joined: Sep 2016
Mar-28-2018, 11:13 AM
(This post was last modified: Mar-28-2018, 11:13 AM by buran.)
I'm not arduino expert. Do you have explanation why you get value like -0.-0.72 ?
below is example how to deal with such case
import serial
import matplotlib.pyplot as ply
import numpy #used for mathematical operations
import pylab as py
from mpl_toolkits.mplot3d import Axes3D
from drawnow import *
ACCX=[]
ACCY=[]
ACCZ=[]
GYRX=[]
GYRY=[]
GYRZ=[]
arduinodata=serial.Serial('COM3',9600) #port name and baud rate
fig = ply.figure()
ax = Axes3D(fig)
ply.ion()
def makeplotting():
ply.subplot(611)
ply.ylabel('ACCX (°/sec)')
ply.xlabel('Time')
ply.plot(ACCX)
ply.subplot(612)
ply.ylabel('ACCY (°/sec)')
ply.xlabel('Time')
ply.plot(ACCY)
ply.subplot(613)
ply.ylabel('ACCZ (°/sec)')
ply.xlabel('Time')
ply.plot(ACCZ)
def convert_float(value):
try:
return float(value)
except ValueError:
print ('Data {} is not in float and hence marked to zero'.format(value))
return 0.0
while True:
while(arduinodata.inWaiting()==0):
pass
arduinostring=arduinodata.readline()
arduinostring=str(arduinostring,encoding="utf-8")
dataArray=arduinostring.split(',')
print (dataArray)
if len(dataArray)==3:
dataArray = list(map(convert_float, dataArray))
# dataArray = [convert_float(v) for v in dataArray] # this is an alternative to map above
x, y, z = dataArray
ACCX.append(x)
ACCY.append(y)
ACCZ.append(z)
drawnow(makeplotting)
else:
print ('There is some data format problem: {}'.format(dataArray)) Couple of remarks:
Not sure, but could the problem with data come because you using inWaiting() and timeout?
Why do you use old version of pyserial? current version is 3.4 and inWaiting was changed to in_waiting in 3.0
it's possible to make additional changes to code to make it more readable/pythonic
Posts: 10
Threads: 2
Joined: Mar 2018
The reading are from sensor. I am not really sure whats he problem with it. Hence,I wanted to convert it to 0.0 if there is such format issue.
I tried updating pyserial but says its already updated and therefore i am using inWaiting instead of in_waiting.
I am still trying to process data. I am sure that most of the issues is taken care of.
Thanks a ton for your help. I was not really sure how to do it as I am an absolute beginner to python programming.
I will post in case I have some issues further.
Have a great day ahead... :)
Posts: 8,156
Threads: 160
Joined: Sep 2016
(Mar-28-2018, 11:39 AM)MeenakshiChowdhary Wrote: tried updating pyserial but says its already updated and therefore i am using inWaiting instead of in_waiting. strange. from the docs
Quote:in_waiting
Getter: Get the number of bytes in the input buffer
Type: int
Return the number of bytes in the receive buffer.
Changed in version 3.0: changed to property from inWaiting()
|