Italian Rielaborazione dati senza grafico

AlpVir

Well-Known Member
Licensed User
Longtime User
Mi riallaccio al post "generare grafici spline" per descrivere la mia esigenza che non riguarda assolutamente il disegno di un grafico ma l'elaborazione di certi dati che potrebbero essere sì rappresentati in un grafico (ma non ne ho la necessità).
Ho una serie di valori Y che non si susseguono a distanza di tempo costante (asse X). Essi descrivono (un po' approssimativamente a causa dell'imprecisione del sensore) un fenomeno che ho la certezza essere di tipo sinusoidale con frequenza variabile nel tempo fra 1 e 0.001 Hz approssimativamente.
Avrei bisogno di ricavare ESCLUSIVAMENTE il numero 3 che corrisponde alla somma dei massimi (ossia 2 nel caso raffigurato) pìù la somma dei minimi (1 nel caso raffigurato).
Quale approccio matematico mi consigliereste, tenendo ancora conto che il conteggio (1, 2, 3, 4, ecc.) dovrebbe essere in tempo reale ?
Difficile ?
Grazie per l'attenzione.

C1.jpg
 

Attachments

  • C1.zip
    7.7 KB · Views: 291

Star-Dust

Expert
Licensed User
Longtime User
Non so se ho ben capito in questa onda sinusoidale vuoi calcolare l'ampiezza o il periodo?

Perché il picco massimo nell'esempio è 8,6 e il minimo è -2.

Tu scrivi che lo somma è 3 cioè 2 + 1 , come da esempio... Ho frainteso qualcosa, oppure i dati a cui ti riferisci non sono quelli dell'esempio ?
 
Last edited:

AlpVir

Well-Known Member
Licensed User
Longtime User
Nè ampiezza nè periodo ma solo il numero dei picchi (positivi o negativi)
I dati dell'esempio forniscono il risultato indicato (3)

Avrei bisogno di ricavare ESCLUSIVAMENTE il numero 3

In altre parole: io do in pasto ad un algoritmo (quale ?) i valori di un sensore e lui mi restituisce, nel tempo, 1 poi 2, poi 3, ecc. ecc.
 

Star-Dust

Expert
Licensed User
Longtime User
Ok adesso ho capito... Non sembra complicato.

Adesso sono fuori sede. Appena rientro spero di poter buttare giù qualche rigo di codice.
 

Star-Dust

Expert
Licensed User
Longtime User
Ho creato al volo un breve codice.
Simulando la lettura dell'onda sinusoidale con la funzione Sin() , memorizzo l'ultima lettura in una variabile e la direzione dell'onda in un altra.
Per stabilire la direzione dell'onda (in salita o in discesa) confronto la lettura attuale con la precedente.
Se la direzione dei valori letti non cambia (sempre salita o sempre discesa) prosegue il ciclo con le letture.
Appena la lettura rivela che la direzione è cambiata lui aggiunge "1" al contatore. (c'è appena stato un picco)

Ovviamente i primi due valore li salto perché mi servono per stabilire in che modo l'onda sta partendo, in salita o in discesa.

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim Count As Int
    Dim Direzione As Int
    Dim Ultimo As Double
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")  
    Direzione=100
    Count=0
    For i=1 To 20
        Conteggio(LetturaValori(i))
        Log(i & ":" & LetturaValori(i))
    Next
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub LetturaValori(i As Int) As Double
    Return Sin((cPI*i)/5)
End Sub

Sub Conteggio(Valore As Double)
    Select Direzione
        Case 100
            ' lettura primo valore
            Ultimo=Valore
            Direzione=0
        Case 0
            ''Ancora la direzione (ascesa o discesa) non é stata stabilita
            If Ultimo<Valore Then
                ' inizia la lettura con una salita
                Ultimo=Valore
                Direzione=1
            Else  If Ultimo>Valore Then
                ' inizia la lettura con una discesa
                Ultimo=Valore
                Direzione=-1
            Else
                ' valore uguale, NESSUNA OPERAZIONE,               
            End If
        Case 1
            ' lettura precedenti in salita
            If Ultimo<Valore Then
                ' Ancora in salita, nessun cambiamento
                Ultimo=Valore
            Else  If Ultimo>Valore Then
                ' Cambiata direzione, conta un picco
                Ultimo=Valore
                Direzione=-1
                Count=Count+1
                Log("------------ " & Count)
            Else
                ' valore uguale, NESSUNA OPERAZIONE,
            End If
        Case -1
            ' lettura precedenti in discesa
            If Ultimo<Valore Then
                ' Cambiata direzione conta un picco
                Ultimo=Valore
                Direzione=1
                Count=Count+1
                Log("------------ " & Count)
            Else  If Ultimo>Valore Then
                ' Ancora in discesa, nessuna variazione
                Ultimo=Valore
            Else
                ' valore uguale, NESSUNA OPERAZIONE,
            End If
    End Select
      
End Sub

Non é molto raffinato ma da l'idea dell'algoritmo da sviluppare. Poi tu lo perfezionerai.
Una cosa da perfezionare ad esempio è se per errore di lettura alcuni valori arrivati potrebbero dare un falso picco.
Magari c'è una sequenza del tipo:
1.01
1.02
1.03
1.28 (imprecisione di lettura)
1.40


Questo si potrebbe perfezionare ...

Ma vado troppo di fretta.. alla prossima. Spero di esserti stato utile
 

LucaMs

Expert
Licensed User
Longtime User
Mi sembra che tu non possa fare la somma dei minimi e dei massimi, a meno che tu non stabilisca QUANTI minimi e QUANTI massimi considerare.

Volendo fare la somma dei soli singoli minimi e massimi, la cosa è molto semplice: li memorizzi in continuazione, durante il ricevimento dei dati.


Ma vado troppo di fretta
[io sono andato di fretta perché mentre scrivevo ho visto che c'era un nuovo "messaggio", quello sopra di @LordZenzo, quindi non ho scritto uno pseudo codice per la seconda ipostesi, quella delle List. Dato che perdere tempo mi aiuta a non occuparmi dei fatti miei, lo faccio adesso :p]
 

LucaMs

Expert
Licensed User
Longtime User
Sono andato talmente di fretta che lo pseudo-codice che avevo scritto nel post (ops, messaggio) precedente è sparito: devo aver clickato (?) su annulla, probabilmente.

B4X:
NewY = UltimoDatoArrivato
If NewY < MinY Then
    Miny = NewY
End If

If NewY > MaxY Then
    MaxY = NewY
End If

SommaMassimi = MinY + MaxY
 
Last edited:

AlpVir

Well-Known Member
Licensed User
Longtime User
@LucaMs
""Volendo fare la somma dei soli singoli minimi e massimi, la cosa è molto semplice: li memorizzi in continuazione, durante il ricevimento dei dati.""
Esatto !
@Star-Dust
Grazie del tentativo ma ...
Il sensore fornisce dati non a cadenza costante (come la tua simulazione presuppone) e soprattutto non sono iscrivibili esattamente in una sinusoide. Ergo: il conteggio del picco non può essere fatto quando viene individuato il cambio di direzione.
La tua sub LetturaValori dovrebbe essere riscritta tenendo conto dei due inconvenienti sopra segnalati, "spostando" di un valore random sia il valore della "i" che quello di ritorno della sub. In altre parole lo "spostamento" modifica di un certo valore random il valore teorico della sinusoide, sia sull'asse del tempo (la X) che su quello dei valori del sensore (la Y).
 

AlpVir

Well-Known Member
Licensed User
Longtime User
Aggiungo
In considerazione che non ho il sensore sottomano debbo anch'io fare delle simulazioni.
Quindi il "sensore" simulato potrà sì essere un generatore di onde sinusoidali a frequenza un po' variabile e di ampiezza anch'essa variabile; entrambe le variazioni dovranno essere random in modo da simulare :
1) l'imprecisione del sensore
2) la non costanza nel tempo dei dati forniti dallo stesso.
Sempre più difficile, per me.
Probabilmente, per controllare il corretto funzionamento dell'algoritmo, dovrò aggiungere un sistema per disegnare i soli punti sperimentali sugli assi cartesiani, con la X che scorre, quasi come un oscilloscopio.
Guardando questo "grafico" l'occhio umano distingue perfettamente un andamendo sinusoidale ed è in grado di contare uno, due, tre, ecc, ma il computer .... non ancora.
 
Last edited:
Top