C# ve chart'da veri kaydırma

Başlatan Mucit23, 18 Eylül 2024, 18:00:25

Mucit23

Selamlar

C#'ın kendi chart kontrolünü kullanarak veri kaydırma nasıl yapılır? Örnek veriyorum 100 noktalı bir pencere için osiloskop efekti yapmak istiyorum.



İstediğim gibi yapamadım bir türlü.

tunayk

Chart kontrolü biraz yavaş çalışıyor bu işlerde. Normalde point arraydan 0. Elemanı alıp yeni değeri eklersin. Refresh edersin. Çalışır ama pek şık bir çözüm değil.

Mucit23

Evet onu denedim gerçekten çok yavaş çalışıyor farklı bir alternatif arıyorum

kudretuzuner

Merhaba,
Ben de 00-FF arası PC'ye gelen 250 civarında hex kodlarını okuyacağım ama başaramadım. Dikey bargraf olarak okudum ama sinyal olarak okumak için her bir datayı bir bit ihtiva eden PictureBox ları yan yana diziyorum. Gelen her bir data sinyalinin resmini dosyadan ekrana çağıracağım. Bakalım olacak mı? frekans 200 hz civarı baudrate 9600 dür.
VB.Net 2010 express edition kullanmaktayım.
Amatör

tunayk

Daha hızlı grafik kontrollerden faydalanabilirsiniz, ya da grafiği kendiniz çizdirirsiniz. Drawing Namespace altındaki komutlar ile.

Bir örnek olarak ;

Formda görüntüleme için picturebox kullanabilirsiniz. Grafiği Picturebox ebatlarında bir bitmap objesi üzerine çizin ve gösterin. Arkaplanda bir sonraki karede görülecek olan kaydırılmış formdaki grafiği başka bir bitmap üzerine çizdirin. Gösterme zamanı gelince 2. resmi picturebox'a image olarak atayın. O ekranda görülürken siz bir sonraki kareyi hazırlayın. Örneğin 40ms timer ile sürekli resim güncellerseniz, göz sürekli akan bir görüntü görür.

Mevcut resmi kaydırıp, sadece yeni gelen kısmı ekleyerek de çizim yapılabilir.  Performans gereksinimine göre çeşitli yollar var.

DirectX / OpenGL kütüphanesi ile de çeşitli işler yapılabilir ancak sizin için çok gerekli olacağını düşünmüyorum   

tunayk

Alıntı yapılan: kudretuzuner - 18 Eylül 2024, 22:03:51Merhaba,
Ben de 00-FF arası PC'ye gelen 250 civarında hex kodlarını okuyacağım ama başaramadım. Dikey bargraf olarak okudum ama sinyal olarak okumak için her bir datayı bir bit ihtiva eden PictureBox ları yan yana diziyorum. Gelen her bir data sinyalinin resmini dosyadan ekrana çağıracağım. Bakalım olacak mı? frekans 200 hz civarı baudrate 9600 dür.
VB.Net 2010 express edition kullanmaktayım.

Hocam sizinki de bir yöntem elbetteki ancak o kadar uğraşmanıza gerek yok.
Örneğin boş bir form üzerinde istediğiniz bir noktadan itibaren her bir sayısal değere karşılık bir nokta koyarsınız

Form.CreateCraphics() fonksiyonu size çizim için kullancağınız yüzeyi ve gerekli tüm araçları sağlar.  Graphics.DrawLine() komutu ile itediğiniz iki nota arasına, kalınlığını, rengini sizin belirlediğiniz çizgi atabilirsiniz.  İsterseniz nokta nokta gidin, isterseniz noktadan noktaya çizgi atın. size kalmış.
Graphics kütüphanesi zevklidir. Biraz geometri gerektirir.
 :) 

tunayk

Bir formun üzerinde yerleştirilmiş PictureBox üzerinde grafik çizen örnek kodu aşağıda veriyorum. Temel prensibi anladıktan sonra, eksen çizgileri, yazılar vs. süs püs eklenebilir.
        Point P1, P2;
        Random r = new Random();
        Pen pLine = new Pen(Color.Red, 2);
        Bitmap b1, b2;
        int step=5;
        bool t = false;
        List<int> deger = new List<int>();
        private void Form1_Load(object sender, EventArgs e)
        {
            
           
            b1 = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            Graphics G = Graphics.FromImage(b1);
            G.Clear(Color.White);
            P1 = new Point(0, pictureBox1.Height);
            for (int i = 0; i < 300; i++)
            {
                deger.Add( r.Next(0, pictureBox1.Height-40));                
                if (i > 0) 
                {
                    P2 = new Point(i*step, pictureBox1.Height-deger[i]);
                    G.DrawLine(pLine, P1, P2);
                    P1.X = P2.X;
                    P1.Y = P2.Y;
                }
            }
            pictureBox1.Image  = b1;
        }

        void Draw() 
        {
            try
            {
                b1 = new Bitmap(pictureBox1.Width, pictureBox1.Height);
                Graphics G = Graphics.FromImage(b1);
                G.Clear(Color.White);
                deger.RemoveAt(0);
                deger.Add(r.Next(0, pictureBox1.Height - 40));
                P1 = new Point(0, pictureBox1.Height);
                for (int i = 0; i < 100; i++)
                {                    
                        P2 = new Point(i * step, pictureBox1.Height - deger[i]);
                        G.DrawLine(pLine, P1, P2);
                        P1.X = P2.X;
                        P1.Y = P2.Y;                   
                }
                pictureBox1.Image = b1;
            }
            catch (Exception ex)
            {

            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
             
            Draw();
        }

Mucit23

Selamlar

C# üzerinde chart ile veri kaydırma işlemi yapıp osiloskop benzeri bir görüntü elde etmeye çalışıyorum. Veri kaydırma işlemi için basit bir alogoritma yapıp o kısmı çözdüm.

Alıntı YapRandom rnd = new Random();
                int sayi = rnd.Next(0, 5);

                if (chartControl1.Series[0].Points.Count >= 100)
                {
                    chartControl1.Series[0].Points.RemoveAt(ChartXindex - 100);
                }

                XYDiagram diagram = (XYDiagram)chartControl1.Diagram;

                diagram.AxisX.WholeRange.SetMinMaxValues(ChartXindex - 100, ChartXindex);
                diagram.AxisX.VisualRange.SetMinMaxValues(ChartXindex - 100, ChartXindex);

                ChartXindex += 1;
                chartControl1.Series[0].Points.Add(new SeriesPoint(ChartXindex, sayi));
                chartControl1.Invalidate();//update chart

Kod güzel çalışıyor ama daha nasıl hızlandırabilirim diye optimizasyon önerilerine ihtiyacım var.

Benim amacım Seri porttan gelen verilerle osiloskop benzeri bir görüntü elde etmek. Bunu yapıyorum aslında ama 100Hz gibi bir veri sıklığına ulaşınca sistem hataya düşüyor. 10ms aralıklarla yeni bir veri paketi geliyor. Yukarıdaki kodların işlenme süresi, veri gelme sıklığından daha uzun sürüyor. Her zaman olmasa da arada oluyor bu da sistemi sekteye uğratıyor.

Seri port veri gelme olayında bir thread'i tetikleyerek Yukarıdaki kodları çalıştırıyorum. Yukarıdaki kodların daha hızlı daha öncelikli çalışmasını sağlamak mümkünmüdür?


elektronikhobi

Seri porttan gelen verileri, gelir gelmez veritabanına kaydedebilirsiniz.

Veritabanından örnekleme yöntemi ile veri okuyup çizdirmeyi deneyebilirsiniz.

"Yirminci asrın akıllara hayret veren keşiflerinden birisi de hiç şüphesiz transistörlerdir."


kudretuzuner

#9
Merhaba, bu aralar ChatGPT ile yazdığım kodları iyileştiriyorum. "Tunayk" arkadaşın önerisini AI ile kodu yaz dedim. Hem C de hem de VB.Net için kodları istedim.Aşağıdaki bilgileri verdi. Deneyip bakacağım. Teşekkürler Tunayk.

Form.CreateCraphics() fonksiyonu ile form1 içine 100,100 koordinatına  bir piksel gösteren kodu yaz

ChatGPT:
ChatGPT
Form.CreateGraphics() fonksiyonu, bir Windows Forms uygulamasında çizim yapmak için kullanılabilir. Aşağıdaki kod, Form1 üzerinde 100,100 koordinatına bir piksel çizen bir örnektir:

csharp
Kodu kopyala
using System;
using System.Drawing;
using System.Windows.Forms;

public class Form1 : Form
{
    public Form1()
    {
        this.Text = "Piksel Çizimi";
        this.Load += Form1_Load;
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        // Graphics nesnesini oluştur
        using (Graphics g = this.CreateGraphics())
        {
            // Bir fırça (brush) tanımla
            SolidBrush brush = new SolidBrush(Color.Black);

            // Piksel çizmek için küçük bir dikdörtgen kullan
            g.FillRectangle(brush, 100, 100, 1, 1);
        }
    }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}
Açıklamalar:
Graphics Nesnesi:
this.CreateGraphics() ile form üzerinde çizim yapmak için bir Graphics nesnesi oluşturulur.
Pixel Çizimi:
Pikseller, aslında çok küçük dikdörtgenlerdir. Bu nedenle FillRectangle metodu kullanılarak 1x1 boyutunda bir dikdörtgen çizilir.
Renk Ayarı:
Siyah renkte bir fırça (SolidBrush) kullanılmıştır. İsterseniz Color.Red gibi farklı renkler de seçebilirsiniz.
Dispose Kullanımı:
Graphics nesnesi kullanıldıktan sonra kaynak yönetimi için Dispose edilir. using anahtar kelimesi bu işi otomatik yapar.
Bu kodu bir Windows Forms projesinde çalıştırarak belirtilen koordinata bir piksel çizebilirsiniz.






Şunu dedin:
VB.Net Form.CreateCraphics() fonksiyonu ile form1 içine 100,100 koordinatına  bir piksel gösteren kodu yaz
ChatGPT:
ChatGPT
VB.Net kullanarak Form.CreateGraphics() ile Form1 içine 100,100 koordinatında bir piksel çizen kod şu şekildedir:

vb.net
Kodu kopyala
Public Class Form1
    "Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load" buraya değil hata veriyor

    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles MyBase.Paint------buraya yazılan kod çalıştı
        ' Graphics nesnesi oluştur
        Dim g As Graphics = Me.CreateGraphics()

        ' Fırça (Brush) tanımla
        Dim brush As New SolidBrush(Color.Black)

        ' Piksel çizmek için küçük bir dikdörtgen kullan
        g.FillRectangle(brush, 100, 100, 1, 1)

        ' Graphics nesnesini serbest bırak
        g.Dispose()
    End Sub
End Class
Açıklamalar:
Graphics Nesnesi:
Me.CreateGraphics() form üzerinde çizim yapmak için bir Graphics nesnesi oluşturur.
Pixel Çizimi:
Pikseller dikdörtgen olarak çizildiğinden FillRectangle metodu 1x1 boyutunda bir dikdörtgen çizer.
Renk Seçimi:
Color.Black kullanılarak siyah bir piksel çizilir. İsterseniz rengi Color.Red gibi başka bir renk ile değiştirebilirsiniz.
Dispose Kullanımı:
Kullanılan Graphics nesnesi, Dispose metodu ile serbest bırakılır.
Çalıştırma:
Bu kodu bir Windows Forms projesine eklediğinizde ve çalıştırdığınızda, form yüklendiğinde 100,100 koordinatında bir siyah piksel gösterilecektir.
Amatör