Topic: Dubbi su Pyplot e array  (Letto 272 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline Lama

  • python unicellularis
  • *
  • Post: 13
  • Punti reputazione: 0
    • Mostra profilo
Dubbi su Pyplot e array
« il: Aprile 07, 2019, 00:24 »
Buonasera , mi sto avvicinando al linguaggio di  programmazione Python. Sono radioamatore (IZ1PSS) e ho la necessità di leggere da seriale 50 righe formate da 3 dati provenienti da ARDUINO ,Frequenza, ampiezza e fase formattati con sprintf() . Quindi ogni riga è formattata regolarmente.
I dati che ricevo sul Pc vengono usati ,dopo opportuni calcoli, a visualizzare con matplotlib.pyplot alcuni grafici dopo averli memorizzati in 3 array. Mi  sembrerebbe logico dopo aver processato i dati, convertirli in float, poichè quelli che ho ricevuto dovrebbero essere stringhe. Inserisco un frammento di codice per chiarire il concetto:
..............
line = ser.readline()                 
    line = line.strip()
    while( len(line) !=0):
         line = ser.readline()
         freq = line[0:5]
         mag = line[6:10]
         phs = line[11:15]
        # print(freq,mag,phs)
         in_buffer_freq.append(freq)
         in_buffer_mag.append(mag)
         in_buffer_phs.append(phs)..........
ottengo regolarmente il grafico , ma secondo me, dovrei scrivere ad esempio : in_buffer_freq.append(float(freq)). Ma se scrivo questa riga il compilatore SI ARRABBIA e dice che non può fare il casting. Dove sbaglio ?  Evidentemente devo ancora imparare molto di questo mondo. Grazie Adriano  :thinking: :thinking:

Offline bebo

  • python erectus
  • ***
  • Post: 231
  • Punti reputazione: 0
    • Mostra profilo
    • bebo_sudo's personal homepage
Re:Dubbi su Pyplot e array
« Risposta #1 il: Aprile 07, 2019, 15:59 »
Ciao Adriano.
Riesci a produrre un MCVE? Cioe' un esempio minimale dell'input che ricevi, di come lo stai manipolando adesso e l'output o gli errori che ne risultano (quel "si arrabbia" non significa niente.. e' come se ti dicessero che una radio non funziona.. ok non funziona, ma per quale motivo? manca corrente? non hai montato l'antenna? sei fuori dalla giusta frequenza?) e infine quale output vorresti ottenere invece.
Ad es. la parte della lettura da seriale noi non possiamo averla per giocarci.. quindi immagina che la variabile 'line' sia gia' popolata nel tuo esempio, ad es. line = '123,456,789' e poi ci fai vedere cosa hai fatto finora.

Infine, quando posti codice su piu' righe, inseriscilo nel tag pythoncode in modo da renderlo leggibile; e' il pulsante con il simbolo di python nella barra sopra il campo di testo della risposta.

Offline Lama

  • python unicellularis
  • *
  • Post: 13
  • Punti reputazione: 0
    • Mostra profilo
Re:Dubbi su Pyplot e array
« Risposta #2 il: Aprile 07, 2019, 23:04 »
Grazie per la risposta. Cercherò di spiegarmi meglio:Di seguito frammento di codice funzionante. Il grafico viene visualizzato correttamente !
Dai convertitori AD di Arduino:
sprintf(buf,"%5d %4d %4d",freq_div, adcmag, adcphs);
Serial.println(buf);
Sul Pc Linus Ide Spyder :
Inizializzazione Seriale......

while (True):
   line = ser.readline()                 
    line = line.strip()
    while( len(line) !=0):
         line = ser.readline()
         freq = line[0:5]
         mag = line[6:10]
         phs = line[11:15]
         print(freq,mag,phs)
         in_buffer_freq.append(freq)
         in_buffer_mag.append(mag)
         in_buffer_phs.append(phs)
         if(len(line)== 0):   
                fig = plt.figure()
                Ax = fig.add_axes([0.1,0.1,0.8,0.8])
                Ax.set_xlabel('frequenza')
                Ax.set_ylabel('ampiezza')
                Ax.plot(in_buffer_freq,in_buffer_mag,'r--',in_buffer_freq, in_buffer_phs,LW= 2)
                plt.show()
                fig.savefig('test.png')


Quello che ricevo dalla Seriale : print(line)
16005  434  431
16010  207  203
16015  150  152
16020  208  206
16025   46   42
16030  138  136
16035  106  107
16040   53   55
16045   16   18
……………..
Questo è l'errore che mi da il compilatore se cambio la riga ->  in_buffer_freq.append(freq) con ->  in_buffer_freq.append(float(freq))
File "/home/adriano/Progetto HP/FrammentoRicSeriale.py", line 31, in <module>.
ValueError: could not convert string to float

Ripeto che il grafico lo ottengo, ma quello che mi sembra scorretto è di usare stringhe per disegnare il grafico, vorrei popolare i miei 3 array con valori float .  A me comunque servono valori float per ricavare tutti gli altri parametri per calcolare da ampiezza e fase, Rho ,SWR , impedenza (valore complesso) e |Z| e fase Z.
Mi scuso per eventuali imprecisioni e magari un uso scorretto del forum ma sono pronto a migliorare........73 adriano

Offline bebo

  • python erectus
  • ***
  • Post: 231
  • Punti reputazione: 0
    • Mostra profilo
    • bebo_sudo's personal homepage
Re:Dubbi su Pyplot e array
« Risposta #3 il: Aprile 08, 2019, 09:59 »
Ciao Adriano
Quello che hai postato e' il pezzo di codice come l'hai scritto te, che pero' io non posso riprodurre non avendo una seriale e gli strumenti per generare i tuoi input.

Citazione
Ad es. la parte della lettura da seriale noi non possiamo averla per giocarci.. quindi immagina che la variabile 'line' sia gia' popolata nel tuo esempio, ad es. line = '123,456,789' e poi ci fai vedere cosa hai fatto finora.

Ho provato a "immaginare" quale fosse il contenuto di 'line', ossia la linea che ricevi in input, e a me "funziona" la conversione.

>>> in_buffer_freq = []
>>> in_buffer_mag = []
>>> in_buffer_phs = []
>>>
>>> line = '16005 434 431'
>>>
>>> freq, mag, phs = line.split()
>>> mag
'434'
>>> float(mag)
434.0
>>>
>>>
>>> # Qua ora uso una list comprehension, ma puoi usare anche un normale for (piu' lento)
>>> # oppure map, se sei abituato a fare functional programming
>>> freq, mag, phs = [float(number) for number in line.split()]
>>>
>>> # esattamente uguale, in programmazione funzionale, ma meno "pythonico"
>>> freq, mag, phs = map(float, line.split())
>>>
>>> in_buffer_phs.append(phs)
>>> in_buffer_phs
[431.0]


Direi che c'e' qualcos'altro che noi non possiamo vedere.

Prova a mettere dopo il readline di riga 5 un
print(repr(line))

Questo ti stampera' la stringa cosi' come e' contenuta nella variabile line, senza cioe' interpretare i caratteri speciali che sono contenuti (ad es gli a capo \n, etc).

Poi, una volta che sei certo di cosa ricevi in input, prova a scrivere un pezzetto di codice che riproduce il tuo problema, ad es. anche nell'interprete di python come ho fatto io.

Offline Lama

  • python unicellularis
  • *
  • Post: 13
  • Punti reputazione: 0
    • Mostra profilo
Re:Dubbi su Pyplot e array
« Risposta #4 il: Aprile 08, 2019, 17:59 »
Grazie e ancora grazie per la pazienza e le risposte. Dalle righe di codice capisco che sei anni luce più esperto di me. Alcuni comandi non sapevo esistessero.
Il mio modo di programmare è empirico e mi piacerebbe migliorare, ma sono solo in un paesino di 900 abitanti e non ho nessuno con cui confrontarmi. Le cose che imparo ,le leggo sui forum, ma l'eleganza nella programmazione(la tua) è un'altra cosa. Non credo si impari sui banchi di scuola. Quando ho frequentato l'università faceva capolino lo Z80.
Ti allego la linea ottenuta con la tua istruzione : '16215   19   21\r\n' . Proverò  ad usare l'interprete di python ma ho dei dubbi sulla possibilità di gestire lo stream della seriale in modo interattivo.  Un saluto dalle risaie del vercellese. Adriano

Offline Lama

  • python unicellularis
  • *
  • Post: 13
  • Punti reputazione: 0
    • Mostra profilo
Re:Dubbi su Pyplot e array
« Risposta #5 il: Aprile 08, 2019, 21:09 »
Ciao Bebo, ho riscritto la parte di decodifica della linea come da tuoi suggerimenti. Ecco il codice completo

import matplotlib.pyplot as plt

import serial

from tkMessageBox import *
from Tkinter import *
in_buffer_freq = []
in_buffer_mag = [] 
in_buffer_phs =[]
data = []
SERIALPORT = "/dev/ttyUSB0"       
ser = serial.Serial(SERIALPORT, 9600, timeout=1)

try:
           ser = serial.Serial(SERIALPORT, 9600, timeout=1)
except:                                         # If error in opening audio stream, show error
           RUNstatus = 0
           showerror("Cannot open Serial device")

while (True):
               
    line = ser.readline()                 
    line = line.strip()
    while( len(line) !=0):
         line = ser.readline()
         freq, mag, phs = [float(number) for number in line.split()]
         in_buffer_freq.append(freq)
         in_buffer_mag.append(mag)
         in_buffer_phs.append(phs)
         if(len(line)== 0):   
                fig = plt.figure()
                Ax = fig.add_axes([0.1,0.1,0.8,0.5])
                #Ax.grid(True)
                Ax.set_xlabel('frequenza')
                Ax.set_ylabel('ampiezza')
                Ax.plot(in_buffer_freq,in_buffer_mag,'r--',in_buffer_freq, in_buffer_phs,LW= 1)
                plt.show()
                fig.savefig('test.png')

  Il compilatore mi restituisce il seguente errore :
  File "/home/adriano/Progetto HP/FrammentoRicSeriale_1.py", line 27, in <module>
    freq, mag, phs = [float(number) for number in line.split()]

ValueError: need more than 0 values to unpack.
Non so proprio cosa fare ! Aiuto !
Adriano

Offline bebo

  • python erectus
  • ***
  • Post: 231
  • Punti reputazione: 0
    • Mostra profilo
    • bebo_sudo's personal homepage
Re:Dubbi su Pyplot e array
« Risposta #6 il: Aprile 09, 2019, 10:06 »
Ciao Adriano.
Quello che segnali e' un problema del fatto che la variabile line e' una stringa QUASI vuota. Prova a mettere un print(repr(line)) appena prima della riga dove fai lo split.
(A riga 23 hai gia' usato quello che ti serve per risolvere.)

Ora pero', vedi che c'e' un secondo problema? vedi che stai ripetendo le stesse righe 22-23 e 24?
In questo momento stai usando readline, che legge una singola riga ad ogni invocazione. Esiste pero' anche readlines() (https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.readlines) che ti ritorna un iterabile/lista, utilizzando io.IOBase.readlines (https://docs.python.org/3/library/io.html#io.IOBase.readlines).

Questo significa che anziche' usare il secondo while (che e' "rotto" in questo momento, per il motivo di prima, e ti da quell'errore), significa che puoi iterare direttamente su ser.writelines() per ottenere line (e poi dovrai fare un controllo/pulizia, altrimenti ti trovi lo stesso errore di adesso).

Citazione
Dalle righe di codice capisco che sei anni luce più esperto di me. Alcuni comandi non sapevo esistessero.
Il mio modo di programmare è empirico e mi piacerebbe migliorare, ma sono solo in un paesino di 900 abitanti e non ho nessuno con cui confrontarmi. Le cose che imparo ,le leggo sui forum, ma l'eleganza nella programmazione(la tua) è un'altra cosa.
il trucco e' tutto qua: https://www.reddit.com/comments/b937m9
e poi, hai internet! io stesso ho imparato un sacco da questo forum un paio di anni fa, e adesso mi piace aiutare per quello che posso

Offline Lama

  • python unicellularis
  • *
  • Post: 13
  • Punti reputazione: 0
    • Mostra profilo
Re:Dubbi su Pyplot e array
« Risposta #7 il: Aprile 12, 2019, 11:25 »
Ciao Bebo.
Ti ringrazio dell' aiuto che mi hai dato. Allego il codice completo per chi volesse usarlo. La parte del grafico è rozza e da riscrivere a seconda delle necessità.

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Fri Apr 12 09:35:38 2019

@author: adriano
"""

import matplotlib.pyplot as plt

import serial

from tkMessageBox import *
from Tkinter import *
in_buffer_freq = []
in_buffer_mag = [] 
in_buffer_phs =[]
data = []
SERIALPORT = "/dev/ttyUSB0"       
ser = serial.Serial(SERIALPORT, 9600, timeout=1)

try:
           ser = serial.Serial(SERIALPORT, 9600, timeout=1)
except:                                         # If error in opening audio stream, show error
           RUNstatus = 0
           showerror("Cannot open Serial device")

while (True):
               
    line = ser.readline()                 
    if ser.inWaiting() != 0:
            line = ser.readline()
            line = line.decode('ascii').strip("\r\n")
            if line[0:1] == "(":
                  data = line.split("\t")
                  x, y, z = data[1], data[2], data[3]
                                 
                  in_buffer_freq.append(float(x))
                  in_buffer_mag.append(float(y))
                  in_buffer_phs.append(float(z))
                  line = ser.readline()
                  if ser.inWaiting()== 0: 
                      fig = plt.figure()
                      Ax = fig.add_axes([0.1,0.1,0.8,0.5])
                      #Ax.grid(True)
                      Ax.set_xlabel('frequenza')
                      Ax.set_ylabel('ampiezza')
                      Ax.plot(in_buffer_freq,in_buffer_mag,'r--',in_buffer_freq, in_buffer_phs,LW= 1)
                      plt.show()
                      fig.savefig('test.png')
                      ser.close()
                      break


Su Arduino
Serial.print("(");
   Serial.print("\t");
   Serial.print(fstart/1000);
   Serial.print("\t");
   Serial.print(adcmag);
   Serial.print("\t");
   Serial.print(adcphs);
   Serial.println();
Frutto di pensieri consigli e molto molto Copia e Incolla.......Grazie ancora Adriano.



                     

Offline bebo

  • python erectus
  • ***
  • Post: 231
  • Punti reputazione: 0
    • Mostra profilo
    • bebo_sudo's personal homepage
Re:Dubbi su Pyplot e array
« Risposta #8 il: Aprile 12, 2019, 14:27 »
Dai, diciamo che va meglio.
Un paio di dritte per migliorare:
  • C'e' quel line[0:1] che puo' essere semplicemente riscritto con un line[0]
  • data e' una lista, e ci si puo' fare l'unpacking in modo piu' pulito
    data = line.split("\t")
    _, x, y, z = data

    puoi anche evitare del tutto di salvare nella variabile data se vuoi essere piu' conciso, es. https://stackoverflow.com/questions/39041322/
  • Non capisco poi perche' c'e' quel secondo readline a linea 41 dentro al while e di nuovo quel if inwaiting; per come e' scritto, stai leggendo di nuovo dalla seriale ma non te ne fai niente della seconda lettura. Rimuovi quelle linee.
  • Per com'e' ora, il tuo codice cattura solo la prima linea dalla seriale e poi esce; devi ancora finirlo o e' vuoi leggere solo un input? Perche' nel secondo caso puoi evitare del tutto di usare il while e poi fare break.

Infine, puoi "pulire" molto il tuo codice applicando queste modifiche (se il tuo script deve continuare a leggere da seriale, che non e' quello che sta facendo ora):
Citazione
In questo momento stai usando readline, che legge una singola riga ad ogni invocazione. Esiste pero' anche readlines() (https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.readlines) che ti ritorna un iterabile/lista, utilizzando io.IOBase.readlines (https://docs.python.org/3/library/io.html#io.IOBase.readlines).

Questo significa che anziche' usare il secondo while (..) puoi iterare direttamente su ser.writelines() per ottenere line (..).

Offline Lama

  • python unicellularis
  • *
  • Post: 13
  • Punti reputazione: 0
    • Mostra profilo
Re:Dubbi su Pyplot e array
« Risposta #9 il: Aprile 12, 2019, 19:38 »
Ciao Bebo
cercherò di spiegaremi :
Credo di non poter usare readlines() perchè non so a priori quante lines potrò ricevere. La sweeppata, a seconda della risoluzione che voglio ottenere, ha una durata variabile.
Non è vero che ricevo una sola linea, infatti il secondo readline mi serve a capire quando il convertitore smette di inviarmi linee (ha terminato la sweeppata.
Il programma looppa continuamente fino a  che riceve il carattere di inizio riga ('('),senza mai entrare nella costruzione del grafico.
 

line = ser.readline()
                  if ser.inWaiting()== 0: 

Quando la line è vuota disegna il grafico ,chiude la seriale, ed esce dal loop.
Aspetto un tuo riscontro ed eventuali correzioni sempre gradite. Ancora grazie per la pazienza felicissimo di imparare .......Adriano

Offline bebo

  • python erectus
  • ***
  • Post: 231
  • Punti reputazione: 0
    • Mostra profilo
    • bebo_sudo's personal homepage
Re:Dubbi su Pyplot e array
« Risposta #10 il: Aprile 13, 2019, 00:39 »
Credo di non poter usare readlines() perchè non so a priori quante lines potrò ricevere.
Ma neppure usando inWaiting come stai facendo ora sai quante linee ricevi. readlines dovrebbe "restare in ascolto" della seriale, e rende il tutto piu' leggibile (e meno C-like).

Citazione
Non è vero che ricevo una sola linea,
Corretto. Non potendo provare il tuo codice vado a occhio.

Citazione
infatti il secondo readline mi serve a capire quando il convertitore smette di inviarmi linee
Ah non mi ero accorto che il secondo if aveva un uguaglianza invece di un "diverso" come nel primo caso; questo e' un altro motivo per cui si applica il concetto di DRY: Don't Repeat Yourself; perche' se vedi N volte lo stesso codice, ci passi sopra e non ti accorgi della virgola di differenza.

Citazione
Il programma looppa continuamente fino a  che riceve il carattere di inizio riga ('(') ... Quando la line è vuota disegna il grafico ,chiude la seriale, ed esce dal loop.
Qui c'e' qualcosa che mi sfugge.. in pratica ti aspetti che il tuo input dalla seriale sia una sequenza imprecisata di elementi, tutti che iniziano con '(',  e che poi d'improvviso si fermano. E tu vuoi plottare solo quando non hai piu' input.
Pero' qua vedo un possibile problema (sempre se ho capito bene la doc di pyserial, perche' non ho mai avuto da programmare seriali): ser.inWaiting ti dice solo quanti byte ci sono "in attesa di essere letti" nel buffer di input della seriale. Cosa succede se pero' il tuo arduino o la tua sorgente di input si blocca tra un invio e l'altro degli N input da processare? Ad es. assumiamo che questo sia il tuo input:
(cane)\n
(gatto)\n
(cavallo)\n



A questo punto non c'e' altro input dalla seriale, il tuo script legge fino a cavallo, poi legge ancora e poi controlla se c'e' altro nel buffer. IN QUEL MOMENTO non c'e' altro, quindi fa il plot.

Pero' in realta' il generatore random di nomi nell'arduino si era incantato e doveva generare questa sequenza invece:

(cane)\n
(gatto)\n
(cavallo)\n
                   <-- pausa/stallo
(papera)\n
(coniglio)\n



Lo script python pero' nella pausa dopo cavallo non aveva visto arrivare niente, e percio' aveva continuato con le sue cose, "perdendosi" di plottare gli elementi arrivati dopo.

Al volo mi viene da immaginare a due possibili soluzioni a questo *possibile* problema:
  • mettere un timeout dopo ogni lettura, di una cifra ragionevole (5 secondi?), in modo da aspettare eventuali input ritardatari (forse applicando ser.timeout in qualche modo? non sono sicuro).
  • se hai controllo della generazione dei dati, ad es se stai scrivendo te il software nell'arduino, la cosa migliore sarebbe mettere un carattere di "fine trasmissione" esplicito, ad es un 'EOF\n'. A questo punto potresti semplicemente continuare a leggere tutto fino a quella sequenza, ad es. usando read_until che sembra fatto apposta (https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.read_until, chiamandolo con ser.read_until(expected='EOF') ). E non c'e' piu' bisogno di fare una seconda lettura della linea, oppure usare break e cicli strani (i cicli while non sono "pythonici", ossia sono meno "leggibili" di un ciclo for.. convieni? Infatti si usano davvero raramente in produzione)



Altre osservazioni oltre a quelle nei primi 3 punti del mio messaggio precedente e alle altre sopra:
  • prova a sostituire quel while true e i successivi line = ser.readline con un for line in ser.readlines(), e' MOOOLTO piu' leggibile e mantenibile;
  • il metodo inWaiting e' stato deprecato in favore di in_waiting, con lo stesso significato. Significa che nelle prossime release di serial potrebbe non funzionare, modificalo.
  • puoi usare la classe Serial con un context manager, che in python e' la cosa piu' leggibile e piu' furba da fare; per informazioni su cos'e' un context manager vedi ad es questa pagina di wikibook: https://en.wikibooks.org/wiki/Python_Programming/Context_Managers, oppure questo tutorial https://book.pythontips.com/en/latest/context_managers.html o (piu' avanzato e piu' dettagliato) questo: https://jeffknupp.com/blog/2016/03/07/python-with-context-managers/.
    In pratica, e' sempre meglio evitare di aprire e chiudere cose "a mano" (ad es f = open("filename) e dopo f.close(), oppure nel tuo caso ser = Serial() e alla fine ser.close()), perche' tra l'apertura e la chiusura non sai bene cosa puo' succedere, potresti ad es. incontrare un'eccezione che interrompe l'esecuzione, e il tuo programma non raggiungera' mai quel close() laggiu' in fondo, lasciando delle referenze/descrittori di file aperti (che sono limitati, se guardi con ulimit -a e cerchi open files, di solito sono a 1024 per ogni utente.. quando una tua applicazione richiedera' il 1025esimo descrittore, si rompera' malamente).

    Quindi si usa:
    with Serial(..) as ser:
        # finche' resti dentro questa indentazione puoi usare ser come facevi prima
        # puoi anche passarlo come argomento ad una funzione
        fai_cose_con_la_seriale(input_serial=ser)

    # appena esci fuori, per QUALUNQUE motivo, python chiamera' ser.close per te
    # non c'e' piu' bisogno di chiamare manualmente ser.close


    A naso direi che se un programma non si scollega dalla seriale (che alla fine e' un file), altri programmi immagino non potranno usarla per fare altre cose, e l'utente finale (tu stesso, magari tra qualche mese quando avrai dato per funzionante questo script) si trovera' ad avere rogne con la seriale quando lo script non esce correttamente. Magari con la seriale non e' un granche' di problema, la stacchi e la riattacchi e il tuo SO gli assegnera' un nuovo nome perche' quello vecchio e' rimasto aperto dal tuo script che si e' rotto.
  • rivedi anche gli altri miei commenti piu' sopra, ad es. quel mandare a float i valori si puo' fare in maniera piu' pulita (se avessi mille valori da estrarre, dovresti scrivere 1000 volte float.. oppure scrivere una funzione che lo fa per te)

Offline Lama

  • python unicellularis
  • *
  • Post: 13
  • Punti reputazione: 0
    • Mostra profilo
Re:Dubbi su Pyplot e array
« Risposta #11 il: Aprile 13, 2019, 21:03 »
Ciao Bebo, come al solito accetto a piene "mani" le tue osservazioni. Per spiegarti meglio : la fonte dei miei dati è l'uscita plotter di un analizzatore di spettro Hp.
Le sue uscite sono: asse x, asse y, penup/pendown. La sweeppata è unica e di durata variabile.Molti vectorscopi da collegare al pc usati per analizzare filtri RF,  venduti a un discreto prezzo, (vedi Minivna) non hanno la possibilità di cambiare il tempo di scansione ,perciò se vuoi analizzare un filtro un pò stretto non lo puoi fare ( o meglio qualcuno crede di farlo) ! Da qui la necessità di plottare l'uscita del mio Analizzatore di spettro che ha una risoluzione di 10 Hz. Riscriverò il programma su Arduino affinchè a fine sweeppata mi mandi un carattere di fine lavoro. Ti ringrazio ancora perchè finalmente sto imparando a scrivere qualche riga in un modo più Pythonico.....spero che non ti stancherai di darmi suggerimenti sempre  molto molto apprezzati. a presto Adriano

Offline Lama

  • python unicellularis
  • *
  • Post: 13
  • Punti reputazione: 0
    • Mostra profilo
Re:Dubbi su Pyplot e array
« Risposta #12 il: Aprile 14, 2019, 16:57 »
Ciao Bebo , ti scrivo amareggiato, demoralizzato e....... Sembrava funzionare, ma era solo un illusione. Questa mattina avevo un po di tempo e ho fatto alcune prove con il programma che avevo postato e l'analizzatore di spettro. Inutile dire che avevo prima provato a riscrivere quel while(True) con ser.read_until() senza peraltro riuscirci. Ho provato comunque. Variando la velocità di acquisizione dell'analizzatore (sono tempi dell'ordine del secondo ) ho notato che iniziava a perdere dati, tipo la frequenza la scriveva nella lista ogni 30 Khz invece che ogni 10 Khz. Con un terminale la lettura dell'uscita dell'HP era naturalmente ogni 10. Rallentando ulteriormente la base dei tempi  il prg si pianta e ritorna questo messaggio:
 File "/home/adriano/Progetto HP/LetturaSeriale_0.py", line 38, in <module>
    line = ser.readline()
 File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 483, in read
    ready, _, _ = select.select([self.fd, self.pipe_abort_read_r], [], [], timeout.time_left())
Ho decisamente affrontato un argomento moooolto più grande di me.
Desolato Adriano

Offline bebo

  • python erectus
  • ***
  • Post: 231
  • Punti reputazione: 0
    • Mostra profilo
    • bebo_sudo's personal homepage
Re:Dubbi su Pyplot e array
« Risposta #13 il: Aprile 14, 2019, 21:46 »
Ciao Adriano,
qualcosa di elettronica l'ho studiato, ma di pratico so ben poco e quindi posso seguire poco il tuo problema.

Cerco di ripetere quello che ho capito essere il problema ora: in pratica lo script che hai scritto e' troppo lento e non riesce a catturare tutto l'input dalla tua seriale, corretto?

Se e' questo il problema, ci sono un paio di strade che consiglierei, in ordine di complessita':
  • migliorare il codice seguendo un po' di suggerimenti gia' dati
  • evitare di manipolare alcun input finche' non hai finito di leggere tutto, ossia fino al EOF che invii, e poi fare gli split e la pulizia necessaria con calma
  • riscrivere il tutto in C, o perche' no, in Rust (che e' piu' difficile di C all'inizio)
  • usare python asincrono: recentemente avevo bisogno di catturare delle raffiche di pacchetti TCP (poca roba, in burst ne arrivavano max una decina al secondo), manipolarli leggermente e reinviarli.. in pratica scrivendo python normale ne perdeva alcuni ogni tanto. Ho riscritto il tutto in quart (https://pgjones.gitlab.io/quart/) e ora va perfetto.

Non saprei quale tra le ultime due sia la piu' difficile per un novizio di programmazione.. di sicuro C per un elettronico non fa male, anzi, potrebbe venire quasi facile, ed e' sempre utile soprattutto come forma mentis. Lavorare in async in python e' come lavorare in un mondo diverso dal normale python, ed e' piu' complesso.

Offline Lama

  • python unicellularis
  • *
  • Post: 13
  • Punti reputazione: 0
    • Mostra profilo
Re:Dubbi su Pyplot e array
« Risposta #14 il: Aprile 15, 2019, 22:10 »
Ciao Bebo, cerco di motivare la mia scelta di usare Python. Ho iniziato 40 anni fa a programmare in Turbo C (ho 68 anni e tanta voglia di imparare) ,sono poi passato al VisualC++6 in ambiente Windows XP. Ho scritto diversi programmi di comunicazione con macchine utensili (visualizzatori) e anche il programma che comunicava con il mio analizzatore di spettro. L'interfaccia  era basata su PIC Microchip programmato in HitechC. Poi tutto è cambiato...Widows 7 non era più compatibile con VisualC++6 e molte delle librerie usate per l'interfaccia grafica(IOCOMP) non erano più supportate. Allora perché non passare a Linus, Arduino, Matplotlib eRaspberry . Decisamente usare QT5 e Tkinter era troppo ,infondo mi bastava semplicemente Matplotlib direi molto simile a Matlab. Tutto per imparare nuove tecniche e soprattutto opensource. Naturalmente tutti i miei programmi sono stati scritti "A modo mio" ma funzionanti.
Scusa per il mio sfogo molto negativo di ieri ma non demordo......Ti scriverò presto sottoponendoti una nuova versione della comunicazione seriale, ancora tutta nella tastiera, sperando nei tuoi preziosi consigli. Grazie per l'ospitalità e della pazienza che hai avuto. A presto Adriano.