Rallentare la ProgressBar

di il
16 risposte

Rallentare la ProgressBar

Ciao

Utilizzo il seguente semplice codice per vedere da una periferica esterna il valore di una ProgressBar:
ProgressBar.Value = Xnr
dove Xnr è un dato numerico che continua ad arrivarmi ogni 250ms tramite un timer che interroga la periferica hardware.

La periferica manda un valore da 0 a 200 che però fa ballare la ProgressBar in modo eccessivamente veloce e a scatti.

Ho già provato a modificare il timer ma anche mettendo il timer a 1 secondo o a 1ms, gli sbalzi sono comunque notevoli perché in 1 secondo o ms potrebbe arrivare qualsiasi numero da 0 a 200 o viceversa...

Quindi ad esempio a 250ms che è un attuale compromesso ma non sufficiente, l'arrivo dei dati dalla periferica potrebbe quindi essere 200 poi 100 poi 0 poi 130 poi 50...ecc con una visione molto a scatti.

Un po' come elettricamente mettere un condensatore elettrolitico su uno strumento a lancetta... ma non ho nessuna idea di come mettere un condensatore virtuale in codice...

Qualche consiglio?

16 Risposte

  • Re: Rallentare la ProgressBar

    Ma a cosa serve una Progress Bar se il dato che osservi non è una progressione?
  • Re: Rallentare la ProgressBar

    Se mi consigli cosa usare posso provare...

    Comunque ricevo una variabile che va comunque da 0 a 200.
    vedila un po' come uno strumento di un impianto stereo solo che se ad esempio va da 1 a 100 non lo fa a 1 a 1 passa magari da 1 a 50 poi a 100 e non 1-2-3-4-5-6-7-8-9-10---- 100 e viceversa.
  • Re: Rallentare la ProgressBar

    Prova a fare la media degli ultimi N campioni. Prova a mettere il timer più corto possibile (finché funziona senza errori), Poi fai un'array ciclico di N+1 campioni e prendi la media degli ultimi N (il valore di N sufficiente per i tuoi scopi lo puoi scoprire solo tu)
  • Re: Rallentare la ProgressBar

    Grazie Weierstrass,

    purtroppo non saprei proprio come fare...

    La salita potrebbe essere anche "repentina" la discesa dovrebbe essere "tranquilla"....

    se hai qualche riga di codice da consigliarmi benvenga...
  • Re: Rallentare la ProgressBar

    Non ho capito una cosa...

    Per consuetudine la progress bar è un componente usato per indicare lo stato di un lavoro in corso. Pertanto ci si aspetta di avere un valore minimo (inizio lavoro), uno massimo (fine lavoro) e uno che sta nel mezzo fra i due (quanto lavoro è stato fatto).

    Se i numeri che arrivano dalla periferica vanno da 0 a 200 e arrivano in ordine sempre crescente (es: 0, 10, 11, 14, 30, ...) allora ha senso usare una progress bar.

    Se invece sono randomici (es: 0, 130, 41, 84, 12, ...) allora la progress bar è un componente che non ci azzecca nulla, poichè quello che si deve visualizzare non è un avanzamento lavori.

    Qual è il tuo caso?
  • Re: Rallentare la ProgressBar

    Un miscuglio dei due.

    Vedilo come un segnale audio che arriva da una periferica che mi passa una variable 0-200 appunto, cioê non è casuale ma una sequenza sempre dal basso verso l'alto e viceversa.
    Questo sale e scende a dipendenza dei picchi di segnale audio che riceve ma che può da zero arrivare al massimo o a metà o altro di colpo... e variare poi di conseguenza in più o in meno.

    Hai presente la linea dei LED o la lancetta dello strumentino analogico di un impianto stereo?

    In teoria per arrivare a 50 100 o 200, che comunque parte sempre da zero, non fa 1 2 3 4 5 6 7 8 9....98 99 100 ma fa dei salti.
    Ad esempio se termino la richiesta evidentemente da 100 o quel che è, va a zero di colpo, magari con un intermedio o due e vorrei che rallentasse almeno la discesa.... cioè quando il xnr diventa inferiore all'ultimo ricevuto...

    come dicevo sopra, non saprei proprio come poter fare come quando metto un elettrolitico allo strumento analogico... che si carica velocemente ma si scarica lentamente: quindi la lancetta del meter o la barra led si alza velocemente verso l'alto ma scende piano piano con una specie di delay.

    Non so se sono riuscito a spiegarmi...
  • Re: Rallentare la ProgressBar

    AntoAnto ha scritto:


    Hai presente la linea dei LED o la lancetta dello strumentino analogico di un impianto stereo?
    Data questa premessa, a mio avviso è innanzitutto la scelta della ProgressBar a non essere magari quella ideale: meglio qualcosa di gestibile graficamente con più scioltezza, disegnandola direttamente tramite funzioni grafiche primitive.

    Per la dinamica della visualizzazione che vuoi ottenere, credo ci sia da scomodare un po' di matematica, ma non saprei indirizzarti.
  • Re: Rallentare la ProgressBar

    Weierstrass ha scritto:


    Prova a fare la media degli ultimi N campioni
    Secondo me matematicamente questa è un'ottima idea, ovviamente bisogna fare delle prove per capire quanti valori considerare.
  • Re: Rallentare la ProgressBar

    Grazie Alka per il consiglio "grafico", purtroppo non ho idea da che parte cominciare, zero esperienza con funzioni grafiche.

    Forse matematicamente facendo una media potrei rallentare il saliscendi o un qualcosa che se riceve una variabile inferiore ne rallenti la discesa... a parte che non saprei come inserire i dati che ricevo.

    Se potessi... inserire l'elettrolitico col saldatore avrei risolto...

    boh, qualsiasi semplice esempio potrebbe darmi aiuto.

    Grazie
  • Re: Rallentare la ProgressBar

    Non posso farti quello che ti serve; ti posso dare un'indicazione di massima, tipo dentro la classe del form :
    
        Private packet(999) As Byte ' il pacchetto che ricevi dalla periferica hardware
    
        Private readings(9) As Byte
        Private read_index As Integer = 0
        Private value As Byte
    
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            readings(read_index) = packet(4) ' o quello che e', a seconda di dove sta la tua lettura nel pacchetto
            read_index += 1
            If read_index >= readings.Length Then
                read_index = 0
            End If
            Dim mean As Double = 0.0
            For i As Integer = 0 To readings.Length - 1
                mean += readings(i)
            Next
            mean /= readings.Length
            value = CByte(mean)
        End Sub      
    
    e value è la media degli ultimi dieci campioni, da mettere in un componente grafico
  • Re: Rallentare la ProgressBar

    AntoAnto ha scritto:


    Grazie Alka per il consiglio "grafico", purtroppo non ho idea da che parte cominciare, zero esperienza con funzioni grafiche.
    Qui c'è una piccola guida.
  • Re: Rallentare la ProgressBar

    Grazie a tutti, faccio un po' di prove... ma mi sa che dovrò accontentarmi di veder saltellare lo "strumento"....

    grazie se per caso riesco pubblicherò la soluzione.
  • Re: Rallentare la ProgressBar

    Hai provato eventualmente a usare un framework differente per la tua applicazione?

    Ad esempio, se usi WPF (Windows Presentation Foundation) hai a disposizione delle animazioni che puoi sfruttare per fare in modo che una determinata figura, che potrebbe essere la barra di progressione da animare, venga raffigurata con una determinata larghezza, e a seguito di modifiche al valore di quella dimensione, ottenere in automatico l'effetto di "transizione" da uno stato A (barra piena al valore più alto) a uno stato B (barra meno piena) in modo graduale e non grezzo e/o istantaneo.

    Ciao!
  • Re: Rallentare la ProgressBar

    Eccoti del codice semplice semplice per darti modo di studiarlo, capirlo, e modificarlo.
    Crea un form e mettici dentro una progress bar, poi copia-incolla questo codice e mandalo in esecuzione.
    Il programma genera dei numeri casuali da 0 a 200 e li mostra nella progressbar che ovviamente sarà "a scatti".
    Poi, sulla routine MediaValore, togli la riga "Return num" e mandalo in esecuzione di nuovo, vedrai la progress bar molto più rallentata.
    Il programma tiene conto delle ultime 10 letture (ma puoi modificarlo come vuoi tu) con un buffer circolare
    Prova e facci sapere

    Sergio
    
        Dim Valori(9) As Integer ' buffer da 10 posti
        Dim ValoriIdx As Integer = 0
    
        Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
    
            ProgressBar1.Minimum = 0
            ProgressBar1.Maximum = 200
    
            Dim rnd = New Random
    
            For x = 1 To 100
                Dim num = rnd.Next(0, 201) ' numero casuale da 0 a 200
                ProgressBar1.Value = MediaValore(num)
                Application.DoEvents()
                Threading.Thread.Sleep(80)
                Application.DoEvents()
            Next
    
            Me.Dispose()
    
        End Sub
    
        Private Function MediaValore(ByVal num As Integer) As Integer
    
            Return num  ' <<< linea da disabilitare
    
            Valori(ValoriIdx) = num ' memorizza il valore nel buffer
            ValoriIdx += 1 ' avanza il puntatore
            If ValoriIdx = 10 Then ValoriIdx = 0 ' riporta il puntatore all'inizio
    
            ' calcola la media
            Dim somma As Integer = 0
            For Each valore In Valori
                somma += valore
            Next
            Return CInt(somma / Valori.Length)
    
        End Function
    
    Per calcolare la media si poteva anche usare una sola linea di codice sfruttando il Linq, ma così hai qualcosa in più da studiare
Devi accedere o registrarti per scrivere nel forum
16 risposte