Arduino med Python via Pyfirmata - problem

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Ampere
Inlägg: 11
Blev medlem: 22 mars 2018, 21:14:21

Arduino med Python via Pyfirmata - problem

Inlägg av Ampere »

Hej,
jag försöker lära mig att programmera Python för att styra en Arduino mha Pyfirmata. Uppgiften är att grafiskt visa utslaget från en vridpotentiometer. Det ska ske "live" Problemet är att fönstret öppnar, men det är väldigt litet samt att ingen graf skrivs ut i fönstret.
Koden ser ut som följer:

#!/usr/bin/python

# This code is supporting material for the book
# Python Programming for Arduino
# by Pratik Desai
# published by PACKT Publishing

import sys, csv
from matplotlib import pyplot
import pyfirmata
from time import sleep
import numpy as np

# Associate port and board with pyFirmata
port = 'COM5'
board = pyfirmata.Arduino(port)

# Using iterator thread to avoid buffer overflow
it = pyfirmata.util.Iterator(board)
it.start()

# Assign a role and variable to analog pin 0
a0 = board.get_pin('a:0:i')

# Initialize interactive mode
pyplot.ion()

pData = [0.0] * 25
fig = pyplot.figure()
pyplot.title('Real-time Potentiometer reading')
ax1 = pyplot.axes()
l1, = pyplot.plot(pData)
pyplot.ylim([0, 1])

# Real-time plotting loop
while True:
try:
#print pData
sleep(1)
pData.append(float(a0.read()))
pyplot.ylim([0, 1])
del pData[0]
l1.set_xdata([i for i in xrange(25)])
l1.set_ydata(pData) # update the data

pyplot.draw() # update the plot
except KeyboardInterrupt:
board.exit()
break


Några "libs" finns nog där för framtida bruk, tror jag...

Nån som kan hjälpa mig på traven?
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43148
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Arduino med Python via Pyfirmata - problem

Inlägg av sodjan »

Jag har inget direkt svar, men det skulle i alla fall
underlätta för den som vill kolla koden om du postar
den med [/c] taggarna före och efter.
Ampere
Inlägg: 11
Blev medlem: 22 mars 2018, 21:14:21

Re: Arduino med Python via Pyfirmata - problem

Inlägg av Ampere »

Tack för tipset! Testar igen...

Kod: Markera allt

#!/usr/bin/python

# This code is supporting material for the book
# Python Programming for Arduino
# by Pratik Desai
# published by PACKT Publishing

import sys, csv
from matplotlib import pyplot
import pyfirmata
from time import sleep
import numpy as np

# Associate port and board with pyFirmata
port = 'COM5'
board = pyfirmata.Arduino(port)

# Using iterator thread to avoid buffer overflow
it = pyfirmata.util.Iterator(board)
it.start()

# Assign a role and variable to analog pin 0 
a0 = board.get_pin('a:0:i')

# Initialize interactive mode
pyplot.ion()

pData = [0.0] * 25
fig = pyplot.figure()
pyplot.title('Real-time Potentiometer reading')
ax1 = pyplot.axes()
l1, = pyplot.plot(pData)
pyplot.ylim([0, 1])

# Real-time plotting loop
while True:
    try:
        sleep(1)
        pData.append(float(a0.read()))
        pyplot.ylim([0, 1]) 
        del pData[0]
        l1.set_xdata([i for i in xrange(25)])
        l1.set_ydata(pData)  # update the data
         pyplot.draw()  # update the plot
    except KeyboardInterrupt:
        board.exit()
        break
Användarvisningsbild
KLset
Inlägg: 207
Blev medlem: 31 augusti 2014, 17:36:19
Ort: Uppsala

Re: Arduino med Python via Pyfirmata - problem

Inlägg av KLset »

Har du kört något fungerande exempel med bara pyplot, så att du vet att det fungerar som det ska? Det finns exempel som du kan testa på https://matplotlib.org/examples/pyplots/index.html.
Ampere
Inlägg: 11
Blev medlem: 22 mars 2018, 21:14:21

Re: Arduino med Python via Pyfirmata - problem

Inlägg av Ampere »

Jag använde pyplot framgångsrikt i föregående övning, som såg ut som följer:

Kod: Markera allt

#!/usr/bin/python

# This code is supporting material for the book
# Python Programming for Arduino
# by Pratik Desai
# published by PACKT Publishing


import csv
from matplotlib import pyplot

i = []
mValues = []
pValues = []

with open('SensorDataStore.csv', 'r') as f:
    reader = csv.reader(f)
    header = next(reader, None)
    for row in reader:
        i.append(int(row[0]))
        pValues.append(float(row[1]))
        if row[2] == 'True':
            mValues.append(1)
        else:
            mValues.append(0)

pyplot.subplot(2, 1, 1)
pyplot.plot(i, pValues, '-')
pyplot.title('Line plot - ' + header[1])
pyplot.xlim([1, 25])
pyplot.xlabel('X Axis')
pyplot.ylabel('Y Axis')

pyplot.subplot(2, 1, 2)
pyplot.bar(i, mValues)
pyplot.title('Bar chart - ' + header[2])
pyplot.xlim([1, 25])
pyplot.xlabel('X Axis')
pyplot.ylabel('Y Axis')

pyplot.tight_layout()

pyplot.show()
Användarvisningsbild
KLset
Inlägg: 207
Blev medlem: 31 augusti 2014, 17:36:19
Ort: Uppsala

Re: Arduino med Python via Pyfirmata - problem

Inlägg av KLset »

En vild gissning bara men kanske det saknas ett pyplot.show() innan loopen?
Ampere
Inlägg: 11
Blev medlem: 22 mars 2018, 21:14:21

Re: Arduino med Python via Pyfirmata - problem

Inlägg av Ampere »

Testade med en pyplot.show() på lite olika ställen i programmet. Ingen skillnad. Fönstret öppnar, men är mycket litet och när jag hovrar markören i fönstret så snurrar "timglaset".

Några fler uppslag att prova?
Användarvisningsbild
KLset
Inlägg: 207
Blev medlem: 31 augusti 2014, 17:36:19
Ort: Uppsala

Re: Arduino med Python via Pyfirmata - problem

Inlägg av KLset »

Då tänker jag att det kanske är något i loopen. Vad händer om du ersätter den med koden nedan?

Kod: Markera allt

# Real-time plotting loop
pData.append(float(a0.read()))
pyplot.ylim([0, 1])
del pData[0]
l1.set_xdata([i for i in xrange(25)])
l1.set_ydata(pData)  # update the data
pyplot.draw()  # update the plot
Ampere
Inlägg: 11
Blev medlem: 22 mars 2018, 21:14:21

Re: Arduino med Python via Pyfirmata - problem

Inlägg av Ampere »

Jag antog att du menade inne i try:-uttrycket. Jag provade att ersätta koden, ingen skillnad i resultat.
Sleep(1) är väl där för att skapa fördröjning för att uppdatera värdet varje sekund?

Jag för även nedanstående felmeddelande i kommandoprompten när jag startar upp programmet.Förstår det inte fullt ut, men har provat att namnge x- och y-axeln med pyplot.xlabel('tid'). Då blir det ett syntax error.

C:\Python27\lib\site-packages\matplotlib\cbook\deprecation.py:107: MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance. In a future version, a new instance will always be created and returned. Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.
warnings.warn(message, mplDeprecation, stacklevel=1)
Användarvisningsbild
KLset
Inlägg: 207
Blev medlem: 31 augusti 2014, 17:36:19
Ort: Uppsala

Re: Arduino med Python via Pyfirmata - problem

Inlägg av KLset »

Jag menade att du tar bort själva loopen, det vill säga while-uttrycket. Då ska det se ut så här istället:

Kod: Markera allt

#!/usr/bin/python

# This code is supporting material for the book
# Python Programming for Arduino
# by Pratik Desai
# published by PACKT Publishing

import sys, csv
from matplotlib import pyplot
import pyfirmata
from time import sleep
import numpy as np

# Associate port and board with pyFirmata
port = 'COM5'
board = pyfirmata.Arduino(port)

# Using iterator thread to avoid buffer overflow
it = pyfirmata.util.Iterator(board)
it.start()

# Assign a role and variable to analog pin 0
a0 = board.get_pin('a:0:i')

# Initialize interactive mode
pyplot.ion()

pData = [0.0] * 25
fig = pyplot.figure()
pyplot.title('Real-time Potentiometer reading')
ax1 = pyplot.axes()
l1, = pyplot.plot(pData)
pyplot.ylim([0, 1])

# Real-time plotting loop
pData.append(float(a0.read()))
pyplot.ylim([0, 1])
del pData[0]
l1.set_xdata([i for i in xrange(25)])
l1.set_ydata(pData)  # update the data
pyplot.draw()  # update the plot
Med andra ord ska koden ovan bara ta en mätning med a0.read() och sedan visa grafen. Det är tanken i alla fall. Funkar den koden?
Användarvisningsbild
KLset
Inlägg: 207
Blev medlem: 31 augusti 2014, 17:36:19
Ort: Uppsala

Re: Arduino med Python via Pyfirmata - problem

Inlägg av KLset »

Felmeddelandet som du får är inget syntaxfel, det är en varning som författarna av matplotlib har lagt in för att varna användare i förtid att beteendet i API:et kommer att förändras i en framtida version.
guckrum
Inlägg: 1669
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Arduino med Python via Pyfirmata - problem

Inlägg av guckrum »

Det kan vara en genväg till snabbt resultat att klippa in ett stycke kod någonstansifrån och sedan "bara ändra lite", men eftersom du säger
jag försöker lära mig att programmera Python...
och inte "jag vill bara få precis det här programmet att snurra", så kanske en annan metod är att föredra, speciellt om man kört fast.

Några tips, i all välmening
- När du får problem, försök isolera det, till exempel genom att försöka skapa ett så litet program som möjligt som har problemet. Då löser det sig ofta. Om du fortfarande behöver hjälp, posta det minimala problemet.
- Inkludera inte en massa saker du inte använder. Kolla om inte din editor kan göra grundläggande koll av koden.
- Läs felmeddelandena. En "Warning" är inte ett "syntax error". Det kanske känns otillräckligt, men texten är för att hjälpa dig.
- Om du är osäker, tex på vad "sleep(1)" gör, läs på och/eller testa, tex genom att skriva ett minimalt program

Kod: Markera allt

  print("före")
  sleep(1)
  print("efter")
Sedan lider jag lite med dig för jag tycker inte att pyplots API(er) är speciellt lättbegripliga.
Ampere
Inlägg: 11
Blev medlem: 22 mars 2018, 21:14:21

Re: Arduino med Python via Pyfirmata - problem

Inlägg av Ampere »

Provade med att ta bort loopen och ersätta enligt förslag, men ingen skillnad.

Ska kika på om jag kan isolera felet mer. Har försökt i ett par timmar tre kvällar i rad men inte lyckats än...
Användarvisningsbild
KLset
Inlägg: 207
Blev medlem: 31 augusti 2014, 17:36:19
Ort: Uppsala

Re: Arduino med Python via Pyfirmata - problem

Inlägg av KLset »

Hur kör du koden? Från någon IDE typ IDLE, från en IPython-prompt eller genom python.exe?
guckrum
Inlägg: 1669
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Arduino med Python via Pyfirmata - problem

Inlägg av guckrum »

matplotlib :evil:

Här har du en grund som du kanske kan använda

Kod: Markera allt

from matplotlib import pyplot as plt
from math import sin

plt.ion()
plt.show()

for x in range(10):
        plt.plot([sin((x + t)/3.14) for t in range(20)])
        plt.draw()
        plt.pause(1)
Skriv svar