Picproje Elektronik Sitesi

PROGRAMLAMA DİLLERİ => Visual C# => Konuyu başlatan: noob - 21 Aralık 2013, 20:44:14

Başlık: C# arduino bağlantısı - Ekg sensör
Gönderen: noob - 21 Aralık 2013, 20:44:14
Merhabalar.
Forumda çok yeniyim. Pic proje geliştirmekte de yeniyim sayılır. Bitirme ödevimi yapmak için sizlerden yardım almak istedim.
Ödevim ekg sensörünü arduino ya bağlayıp arduinoda programlayarak sonuçları c# ta tasarlayacağım arayüzde göstermek. arduino programlama kısmını hallettim sayılır bir kaç eksiği var ama az kaldı fakat c # hakkında çok bir bilgim yok. Tasarlayacağım arayüzde nabzı nasıl göstericem hangi kütüphaneyi kullanmam gerekiyor, form'a hangi göstergeyi koyucam hiç bilmiyorum. İnternette 2 gündür araştırıyorum ama pek bir şey bulamadım. Bu konuda sizlerin yardımınızı bekliyorum.
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: olemiss - 21 Aralık 2013, 21:24:34
Bu projenin iki alt kısmı bulunuyor: Arduino, ve PC arayüzü.  Ayrıca bu iki alt sistemin kullanacağı ortak protokol.  Siz Arduino ile C# arasındaki bu protokolden hiç söz etmemişsiniz?

"C# arayüzünde ne gösterilecek" sorusunun cevabı belli: Arduino'dan hangi veriler gönderiliyorsa, onlar gösterilecek.  Sizin yerinizde olsam, öncelikle bu verileri basit bir C# console programı ile DOS ekranına yazdırırdım.  Böylece protokol kısmını hallettikten sonra, GUI arayüzün tasarımına geçerdim.



Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: noob - 21 Aralık 2013, 21:37:25
Üstad sanırım ben derdimi anlatamadım.

Bahsettiğiniz iki alt programdan arduino kısmı zaten tamam diyorum. c# arayüzünde ne göstericem diye de sormadım ayrıca. Ben bu iki program arasında bağlantıyı nasıl yapıcam? ekg sensöründen gönderilen sinyalleri hangi göstergeyi kullanarak yapıcam bunları sordum. Bununla ilgili örnek varsa çok yardımcı olur.

edit: elde etmem gereken görüntü bu tarz olacak. ECG Machine (http://www.youtube.com/watch?v=UJRxHfsLoZo#ws)
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: atioky_216 - 22 Aralık 2013, 00:11:24
O arkadaş ta benim gibi arduino'yu android anlamıştır belki de :) Diyorum hem android hem pc niye..

Yapacağın şu: arduino  kablosunu pc' ye takacaksın muhtemelen COMx adında sanal port olarak görünecek. C# form app başlatacaksın ve oraya portu ekleyip kullanmaya başlayacaksın.

Artık neyi nasıl ekranda göstermek istersin sana kalmış.

NOT: İki program arası bağlantı diye bir şey olmuyor orada... Protokol (farklı cihaz sistem vb. haberleşmesi için ortak dil) ortak olursa mesela seri haberleşme gibi, senin arduino da çalışan C programın PC de çalışan C# ile konuşabiliyor.

Yapacağın C# da seri port kullanımı.
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: olemiss - 22 Aralık 2013, 00:30:17
Alıntı yapılan: atioky_216 - 22 Aralık 2013, 00:11:24
O arkadaş ta benim gibi arduino'yu android anlamıştır belki de :) Diyorum hem android hem pc niye..
Yok, ben Arduino olarak anlamıştım!  Herhalde şuradaki Arduino shield kullanılmakta: https://www.olimex.com/Products/Duino/Shields/SHIELD-EKG-EMG/ (https://www.olimex.com/Products/Duino/Shields/SHIELD-EKG-EMG/)

Şu projede açık kaynak C# grafik/şema çizim kütüphanesi ile ilgili bilgi var:

http://www.codeproject.com/Articles/32836/A-simple-C-library-for-graph-plotting (http://www.codeproject.com/Articles/32836/A-simple-C-library-for-graph-plotting)

Aşağıdaki gibi bir GUI elde etmek mümkün:

(http://www.codeproject.com/KB/miscctrl/GraphPlotting/graph_stacked.png)

Ayrıca şurada açık kaynak bir C# EKG yazılımı var: http://sourceforge.net/projects/ecgtoolkit-cs/ (http://sourceforge.net/projects/ecgtoolkit-cs/)

Belki işe yarayabilir.

Şuradaki stackoverflow sorusu aynı konuda: http://stackoverflow.com/questions/1299816/plot-ecg-in-winforms (http://stackoverflow.com/questions/1299816/plot-ecg-in-winforms)

Şu kaynak C/C++ ile yazılmış EKG kütüphanesi: http://www.codeproject.com/Articles/4353/ECG-recording-storing-filtering-and-recognition (http://www.codeproject.com/Articles/4353/ECG-recording-storing-filtering-and-recognition)
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: noob - 22 Aralık 2013, 01:24:07
Çok teşekkür ederim arkadaşlar. Çok yardımcı oldunuz. Allah razı olsun. Deneyip tekrar döneceğim inşaallah.

kolay gelsin.

edit: bu arada evet olimex'in ürettiği shield'i kullanmaktayım. bulgaristandan sipariş verdik çok masraf yaptırdı bana. öğrenciyim ben daha :D
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: noob - 24 Aralık 2013, 19:34:57
Projede baya ilerleme kaydetmiş bulunmaktayım. Yalnız hata alıyorum sizlere danışmak istedim tekrar.

arduino kod/**********************************************************/
/* Demo program for:                                      */
/*    Board: SHIELD-EKG/EMG + Olimexino328                */
/*  Manufacture: OLIMEX                                   */
/*  COPYRIGHT (C) 2012                                    */
/*  Designed by:  Penko Todorov Bozhkov                   */
/*   Module Name:   Sketch                                */
/*   File   Name:   ShieldEkgEmgDemo.ino                  */
/*   Revision:  Rev.A                                     */
/*    -> Added is suppport for all Arduino boards.        */
/*       This code could be recompiled for all of them!   */
/*   Date: 19.12.2012                                     */
/*   Built with Arduino C/C++ Compiler, version: 1.0.3    */
/**********************************************************/
/**********************************************************
Purpose of this programme is to give you an easy way to
connect Olimexino328 to ElectricGuru(TM), see:
[url]https://www.olimex.com/Products/EEG/OpenEEG/EEG-SMT/resources/ElecGuru40.zip[/url]
where you'll be able to observe yours own EKG or EMG signal.
It is based on:
***********************************************************
* ModularEEG firmware for one-way transmission, v0.5.4-p2
* Copyright (c) 2002-2003, Joerg Hansmann, Jim Peters, Andreas Robinson
* License: GNU General Public License (GPL) v2
***********************************************************
For proper communication packet format given below have to be supported:
///////////////////////////////////////////////
////////// Packet Format Version 2 ////////////
///////////////////////////////////////////////
// 17-byte packets are transmitted from Olimexino328 at 256Hz,
// using 1 start bit, 8 data bits, 1 stop bit, no parity, 57600 bits per second.

// Minimial transmission speed is 256Hz * sizeof(Olimexino328_packet) * 10 = 43520 bps.

struct Olimexino328_packet
{
  uint8_t sync0; // = 0xa5
  uint8_t sync1; // = 0x5a
  uint8_t version; // = 2 (packet version)
  uint8_t count; // packet counter. Increases by 1 each packet.
  uint16_t data[6]; // 10-bit sample (= 0 - 1023) in big endian (Motorola) format.
  uint8_t switches; // State of PD5 to PD2, in bits 3 to 0.
};
*/
/**********************************************************/
#include <compat/deprecated.h>
#include <FlexiTimer2.h>
//http://www.arduino.cc/playground/Main/FlexiTimer2

// All definitions
#define NUMCHANNELS 6
#define HEADERLEN 4
#define PACKETLEN (NUMCHANNELS * 2 + HEADERLEN + 1)
#define SAMPFREQ 256                      // ADC sampling rate 256
#define TIMER2VAL (1024/(SAMPFREQ))       // Set 256Hz sampling frequency                   
#define LED1  13
#define CAL_SIG 9

// Global constants and variables
volatile unsigned char TXBuf[PACKETLEN];  //The transmission packet
volatile unsigned char TXIndex;           //Next byte to write in the transmission packet.
volatile unsigned char CurrentCh;         //Current channel being sampled.
volatile unsigned char counter = 0;   //Additional divider used to generate CAL_SIG
volatile unsigned int ADC_Value = 0;   //ADC current value

//~~~~~~~~~~
// Functions
//~~~~~~~~~~

/****************************************************/
/*  Function name: Toggle_LED1                      */
/*  Parameters                                      */
/*    Input   :  No                             */
/*    Output  :  No                                 */
/*    Action: Switches-over LED1.                   */
/****************************************************/
void Toggle_LED1(void){

if((digitalRead(LED1))==HIGH){ digitalWrite(LED1,LOW); }
else{ digitalWrite(LED1,HIGH); }

}


/****************************************************/
/*  Function name: toggle_GAL_SIG                   */
/*  Parameters                                      */
/*    Input   :  No                             */
/*    Output  :  No                                 */
/*    Action: Switches-over GAL_SIG.                */
/****************************************************/
void toggle_GAL_SIG(void){
 
if(digitalRead(CAL_SIG) == HIGH){ digitalWrite(CAL_SIG, LOW); }
else{ digitalWrite(CAL_SIG, HIGH); }

}


/****************************************************/
/*  Function name: setup                            */
/*  Parameters                                      */
/*    Input   :  No                             */
/*    Output  :  No                                 */
/*    Action: Initializes all peripherals           */
/****************************************************/
void setup() {

noInterrupts();  // Disable all interrupts before initialization

// LED1
pinMode(LED1, OUTPUT);  //Setup LED1 direction
digitalWrite(LED1,LOW); //Setup LED1 state
pinMode(CAL_SIG, OUTPUT);

//Write packet header and footer
TXBuf[0] = 0xa5;    //Sync 0
TXBuf[1] = 0x5a;    //Sync 1
TXBuf[2] = 2;       //Protocol version
TXBuf[3] = 0;       //Packet counter
TXBuf[4] = 0x02;    //CH1 High Byte
TXBuf[5] = 0x00;    //CH1 Low Byte
TXBuf[6] = 0x02;    //CH2 High Byte
TXBuf[7] = 0x00;    //CH2 Low Byte
TXBuf[8] = 0x02;    //CH3 High Byte
TXBuf[9] = 0x00;    //CH3 Low Byte
TXBuf[10] = 0x02;   //CH4 High Byte
TXBuf[11] = 0x00;   //CH4 Low Byte
TXBuf[12] = 0x02;   //CH5 High Byte
TXBuf[13] = 0x00;   //CH5 Low Byte
TXBuf[14] = 0x02;   //CH6 High Byte
TXBuf[15] = 0x00;   //CH6 Low Byte
TXBuf[2 * NUMCHANNELS + HEADERLEN] =  0x01; // Switches state

// Timer2
// Timer2 is used to setup the analag channels sampling frequency and packet update.
// Whenever interrupt occures, the current read packet is sent to the PC
// In addition the CAL_SIG is generated as well, so Timer1 is not required in this case!
FlexiTimer2::set(TIMER2VAL, Timer2_Overflow_ISR);
FlexiTimer2::start();

// Serial Port
Serial.begin(57600);
//Set speed to 57600 bps

// MCU sleep mode = idle.
//outb(MCUCR,(inp(MCUCR) | (1<<SE)) & (~(1<<SM0) | ~(1<<SM1) | ~(1<<SM2)));

interrupts();  // Enable all interrupts after initialization has been completed
}

/****************************************************/
/*  Function name: Timer2_Overflow_ISR              */
/*  Parameters                                      */
/*    Input   :  No                             */
/*    Output  :  No                                 */
/*    Action: Determines ADC sampling frequency.    */
/****************************************************/
void Timer2_Overflow_ISR()
{
  // Toggle LED1 with ADC sampling frequency /2
  Toggle_LED1();
 
  //Read the 6 ADC inputs and store current values in Packet
  for(CurrentCh=0;CurrentCh<6;CurrentCh++){
    ADC_Value = analogRead(CurrentCh);
    TXBuf[((2*CurrentCh) + HEADERLEN)] = ((unsigned char)((ADC_Value & 0xFF00) >> 8)); // Write High Byte
    TXBuf[((2*CurrentCh) + HEADERLEN + 1)] = ((unsigned char)(ADC_Value & 0x00FF)); // Write Low Byte
  }

  // Send Packet
  for(TXIndex=0;TXIndex<17;TXIndex++){
    Serial.write(TXBuf[TXIndex]);
  }
 
  // Increment the packet counter
  TXBuf[3]++;
 
  // Generate the CAL_SIGnal
  counter++; // increment the devider counter
  if(counter == 12){ // 250/12/2 = 10.4Hz ->Toggle frequency
    counter = 0;
    toggle_GAL_SIG(); // Generate CAL signal with frequ ~10Hz
  }
}


/****************************************************/
/*  Function name: loop                             */
/*  Parameters                                      */
/*    Input   :  No                             */
/*    Output  :  No                                 */
/*    Action: Puts MCU into sleep mode.             */
/****************************************************/
void loop() {
 
__asm__ __volatile__ ("sleep");

}


C # GUI

using System.Windows.Forms;
using System.IO.Ports;
using ZedGraph;

namespace WindowsFormsApplication3
{

    public partial class Form1 : Form
    {
        private SerialPort port;
        private static int tickStart = 0;  //timer
        private double counter = 0;
        private int addindex = 0;
        private double[] datasend = new double[10000];
        private static ArrayList portdata;
        private Thread newthread;
        private Thread beepthread;
        private Thread OLthread;
        private Thread qrsthread;
        private Thread threshdecrement;
        private Boolean beeper = false;
        private double qrsaverage = 0;
        private double finitedif = 0;
        private double thresh = 10;
        private double[] qrs = new double[10];          //qrs detection array
        private double[] recentd = new double[150];     //overload detection array
        private double[] lowarray = new double[150];
        private double[] higharray = new double[150];
        private Boolean gainselect = false;
        private double heartbeat = 0;
        private DateTime oldbeep = DateTime.Now;
        private DateTime newbeep = DateTime.Now;

        public Form1()
        {
            InitializeComponent();

            for (int i = 0; i < 150; i++)           //overload checker
            {
                lowarray[i] = 0;
            }

            for (int j = 0; j < 150; j++)
            {
                higharray[j] = 1000;
            }

            // This is to remove all plots
            zedGraphControl1.GraphPane.CurveList.Clear();

            // GraphPane object holds one or more Curve objects (or plots)
            GraphPane pane = zedGraphControl1.GraphPane;
           

            //Set up Graph Pane
            pane.Fill.Color = System.Drawing.Color.RoyalBlue;
            pane.Title.Text = "ECG Machine";
            pane.XAxis.Title.Text = "Time (Seconds)";
            pane.YAxis.Title.Text = "Voltage (mV)";
            pane.Legend.IsVisible = false;
            pane.XAxis.Scale.MajorUnit = DateUnit.Millisecond;
            pane.XAxis.Scale.MinorUnit = DateUnit.Millisecond;

           
            zedGraphControl1.GraphPane.XAxis.Scale.Max = 30;
          //  zedGraphControl1.GraphPane.XAxis.Scale.Min = 0;
            zedGraphControl1.GraphPane.YAxis.Scale.Max = 1024;
            zedGraphControl1.GraphPane.YAxis.Scale.Min = 0;
           

            zedGraphControl1.IsShowHScrollBar = true;
            zedGraphControl1.IsAutoScrollRange = true;

            zedGraphControl1.AxisChange();

            // PointPairList holds the data for plotting, X and Y arrays
            PointPairList points = new PointPairList();

            // Add cruves to myPane object
            LineItem myCurve = pane.AddCurve("Heart Rate", points, Color.Red, SymbolType.None);
           
            tickStart = Environment.TickCount;
            portdata = new ArrayList();
           
           
        }

        private void EstablishConnection()
        {
            port = new SerialPort("COM3", 57600, Parity.None, 8, StopBits.One);
            port.Handshake = Handshake.None;
            port.ReadTimeout = 500;
            port.WriteTimeout = 500;
            if (!(port.IsOpen == true)) port.Open();
            port.Write("B");
            port.Write("D");
            port.Write("E");
        }


        /* This begins data reading from serial Port */
        private void button1_Click(object sender, EventArgs e)
        {
            EstablishConnection();
            button1.Enabled = false;
            pointHP.Select();
            newthread = new Thread(new ThreadStart(this.reader));
            newthread.IsBackground = true;
            newthread.Start();

            beepthread = new Thread(new ThreadStart(this.beepcontrol));
            beepthread.IsBackground = true;
            beepthread.Start();

            OLthread = new Thread(new ThreadStart(this.OLdetection));
            OLthread.IsBackground = true;
            OLthread.Start();

            qrsthread = new Thread(new ThreadStart(this.qrsdetection));
            qrsthread.IsBackground = true;
            qrsthread.Start();

            threshdecrement = new Thread(new ThreadStart(this.threshdec));
            threshdecrement.IsBackground = true;
            threshdecrement.Start();

            timer1.Interval = 1;
            timer1.Enabled = true;
            timer1.Start();     //start timer to add points to chart
           
        }

        private void threshdec()
        {
            while (port.IsOpen)
            {
                if (thresh > 0)
                {
                    if (!gainselect)
                    {
                        thresh = thresh - 1;
                        Thread.Sleep(80);
                    }
                    else
                    {
                        thresh = thresh - 2;
                        Thread.Sleep(20);
                    }
                }
            }
        }

        private void qrsdetection()
        {

            while (port.IsOpen)
            {
                if (addindex > 10)
                {
                    int sum = 0;
                    int C = portdata.Count - 1;
                    for (int i = 0; i < 10; i++)
                    {
                        qrs[i] = (double)portdata[C - (9 - i)];
                    }
                    foreach (int num in qrs)
                    {
                        sum += num;
                    }
                    qrsaverage = sum / 10;          //smooth out signal
                    finitedif = qrs[9] - qrsaverage;
                    if (finitedif > thresh)
                    {
                        thresh = finitedif;
                        if (thresh > 8)
                        {
                            beeper = true;
                        }
                   }
                }

            }
        }

        private void OLdetection()
        {

            while (port.IsOpen)
            {
                if (addindex > 150) {
                int C = portdata.Count - 1;
               

                for (int i = 0; i < recentd.Length; i++)
                {
                    recentd[i] = (double)portdata[C - (149 - i)];
                }

                if (lowcheck(recentd) || highcheck(recentd))
                {
                    setOL("Overload");
                    //set to 5 hp filter
                    Thread.Sleep(150);
                    selectfilter();

                }
                else
                {
                    setOL("");
                }
               
            }
                }
        }

        private void selectfilter()
        {
            if (this.InvokeRequired)
            {
                BeginInvoke(new MethodInvoker(delegate() { selectfilter(); }));
            }
            else
            {
                pointHP.Select();
                pointHP.Enabled = false;
                port.Write("D");
                thresh = 0;
            }
        }

        private void setOL(string text)
        {
            if (this.OverLoad.InvokeRequired)
            {
                try
                {
                    this.Invoke(new Action<string>(setOL), new object[] { text });
                    return;
                }
                catch (ObjectDisposedException) { }
            }
            try
            {
                OverLoad.Text = text;
            }
            catch (Win32Exception) { }
        }

        private void setHeartRate(double bpm)
        {
            if (this.HeartRate.InvokeRequired)
            {
                try
                {
                    this.Invoke(new Action<double>(setHeartRate), new object[] { bpm });
                    return;
                }
                catch (ObjectDisposedException) { }
            }
            try
            {
                HeartRate.Text = String.Format("{0:0.0}", bpm);
                   
            }
            catch (Win32Exception) { }
        }

        private void beepcontrol()
        {
            while (port.IsOpen)
            {
                if (beeper)
                {
                    Thread.Sleep(80);   //makes sure it doesnt beep twice within 1/120 sec
                    Console.Beep();
                    //get BPM
                    oldbeep = newbeep;
                    newbeep = DateTime.Now;
                    double span = (newbeep-oldbeep).Milliseconds;
                    heartbeat = 60000 / span;
                    setHeartRate(heartbeat);
                    beeper = false;
                   
                   
                }
            }
        }


        public void reader()
        {
            while (port.IsOpen)
            {

                    double pt;
                    string dat = port.ReadLine();

                    if (Double.TryParse(dat, out pt))           //if data read is a double value
                    {
                        portdata.Add(pt);
                    }

            }
        }


        private void timer1_Tick(object sender, EventArgs e)
        {
            //make sure curvelist isnt empty
            if (zedGraphControl1.GraphPane.CurveList.Count <= 0)
                return;

            //get first curve in graph
            LineItem curve = zedGraphControl1.GraphPane.CurveList[0] as LineItem;
            if (curve == null)
                return;

            IPointListEdit list = curve.Points as IPointListEdit;

                if (addindex < portdata.Count)
                {
                    list.Add(counter, (double)portdata[addindex]);

                    addindex = addindex + 20;
                    counter = counter + .02;

                }


            zedGraphControl1.GraphPane.XAxis.Scale.Max = counter + 5;
            zedGraphControl1.GraphPane.XAxis.Scale.Min = zedGraphControl1.GraphPane.XAxis.Scale.Max - 10;
            zedGraphControl1.AxisChange();
            zedGraphControl1.Invalidate();
            zedGraphControl1.Refresh();
        }


        private void NotchBox_CheckedChanged(object sender, EventArgs e)
        {
            if (NotchBox.Checked)
            {
                port.Write("F");
            }
            else
            {
                port.Write("E");
                thresh = 0;
            }
        }

        private void GainBox_CheckedChanged(object sender, EventArgs e)
        {
            thresh = 0;

            if (GainBox.Checked)
            {
                port.Write("A");
                gainselect = true;
            }
            else
            {
                port.Write("B");
                gainselect = false;
            }
        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            pointHP.Enabled = false;
            fiveHP.Enabled = true;
            port.Write("D");
        }

        private void fiveHP_CheckedChanged(object sender, EventArgs e)
        {
            fiveHP.Enabled = false;
            pointHP.Enabled = true;
            port.Write("C");
        }

        private void Snapshot_Click(object sender, EventArgs e)
        {
            this.Hide();
            int currentday,currentmonth,currentyear,currenthour,currentminute,currentsecond;
            double currentheartrate;
            string currenttime, currentdate;
            currentday = DateTime.Today.Day;
            currentmonth = DateTime.Today.Month;
            currentyear = DateTime.Today.Year;
            currenttime = DateTime.Now.ToString("hh:mm:ss tt", System.Globalization.DateTimeFormatInfo.InvariantInfo);
            currentdate = DateTime.Now.ToString();
            currenthour = DateTime.Now.Hour;
            currentminute = DateTime.Now.Minute;
            currentsecond = DateTime.Now.Second;
            currentheartrate = heartbeat;

            if (addindex > 9999)
            {
                for (int i = 0; i < 10000; i++)
                {
                    datasend[i] = (double)portdata[portdata.Count - (10000 - i)];
                }

                Database d = new Database(currentheartrate,currentday, currentmonth, currentyear, currenthour, currentminute, currentsecond, currentdate, currenttime, datasend,this);
                //timer1.Stop();
                d.Show();
            }
            else
            {
                MessageBox.Show("Not Enough Data Collected");
                this.Show();
            }
        }

        private Boolean lowcheck(double[] a)
        {
   
                for (int i = 0; i < a.Length; i++)
                {
                    if (a[i] != lowarray[i])
                        return false;
                }
                return true;

        }

        private Boolean highcheck(double[] a)
        {
                for (int i = 0; i < a.Length; i++)
                {
                    if (a[i] < higharray[i])
                        return false;
                }
                return true;
        }



        /* Unused methods */
        private void chart1_Click(object sender, EventArgs e) { }
        private void Form1_Load(object sender, EventArgs e) { }
        private void zedGraphControl1_Load(object sender, EventArgs e){ }
        private void textBox1_TextChanged(object sender, EventArgs e) { }
        private void Overload_TextChanged(object sender, EventArgs e) { }




           

    }

}


aldığım hata ise  string dat = port.ReadLine(); kod satırı zaman aşımına uğradı diyor. anladığım kadarıyla devreden bilgileri ya çok geç okuyor ya da hiç okumuyor.
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: ZZombie - 25 Aralık 2013, 17:17:21
Şu kod satrıındaki tüm tanımlar doğru mu?

port = new SerialPort("COM3", 57600, Parity.None, 8, StopBits.One);

Baund değerini değiştirip denemeler yapın bir de.
Hız farkı olabilir Arduino çıkışı ile PC girişi arasında
Ki 57600 baund oldukça yüksek bir hız.
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: olemiss - 25 Aralık 2013, 17:31:28
baund -> baud

;-)
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: noob - 25 Aralık 2013, 18:43:46
baud hızıyla alakalı olduğunu sanmıyorum. establishconnection'ın altındaki point.write("B") nin ve diğerlerinin içini değiştirmem gerekiyor bence. ama ne yazacağımı bilemedim.
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: picusta - 25 Aralık 2013, 20:30:10
C# ile Arduino kodlarinin arasinda baglanti yok.

C# programi degerleri tek tek bekliyor, text olarak yazilmis ve CR ile biten. ornegin  "14.45\r". O yüzden readLine timeout veriyor.

Olimex'teki abiler ise header + binary olarak 6 kanal ADC (16 bit üzerinden) girisilerini gönderiyor.

atioky'nin ön tespiti dogru imis :
Alıntı YapNOT: İki program arası bağlantı diye bir şey olmuyor orada... Protokol (farklı cihaz sistem vb. haberleşmesi için ortak dil) ortak olursa mesela seri haberleşme gibi, senin arduino da çalışan C programın PC de çalışan C# ile konuşabiliyor.
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: noob - 25 Aralık 2013, 21:37:14
Alıntı yapılan: picusta - 25 Aralık 2013, 20:30:10
C# ile Arduino kodlarinin arasinda baglanti yok.

C# programi degerleri tek tek bekliyor, text olarak yazilmis ve CR ile biten. ornegin  "14.45\r". O yüzden readLine timeout veriyor.

Olimex'teki abiler ise header + binary olarak 6 kanal ADC (16 bit üzerinden) girisilerini gönderiyor.

atioky'nin ön tespiti dogru imis :

arduinodaki gönderilen  kodları  stringe çevirip sonuna \r eklersem sorun çözülür mü yani? biraz daha açar mısınız?

ya da c# taki beklenen verileri sayısala mı çevirmeliyim? öyleyse nereleri değiştirmem gerekir?

seri porttan hiç anlamıyorum daha bu ilk projem affınıza sığınıyorum.
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: noob - 27 Aralık 2013, 05:37:15
lütfen yardımcı olur musunuz?
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: picusta - 27 Aralık 2013, 12:47:25
Arduino da degerini println fonksyonu çagirirsan olur.
Sonuna otomatik olarak Carriage Return (CR , veya 13 degerindeki byte (\r ) örnek :
Serial.println("14.56");

Koddaki timer2 overflow interuptta degistirmen gereken :

//Read the 1 ADC inputs and store current values in Packet
ADC_Value = analogRead(CurrentCh);
//send packet
Serial.println(ADC_Value );

CurrentCh degiskeninde ise hangi ADC girisi ile ilgileniyorsan o olacak.


C#  :

C# ta  port.ReadLine();  fonksyonu CR alana kadar bekler.

"portdata" listesi sonsuza kadar gidebilir, arada bir bosaltmak gerekir.
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: olemiss - 27 Aralık 2013, 13:30:24
Ek bir not:

Serial.Println() fonksiyonu satır sonuna iki karakter ekler: ASCII 13, '\r' (satırbaşı - carriage return - karakteri) ve ASCII 10, '\n' (yeni satır - newline - karakteri). 

Windows satır sonunu bu iki karakterle gösterir. 

Linux (Unix) sistemleri ise satır sonu için sadace newline karakteri kullanır.
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: noob - 28 Aralık 2013, 12:41:32
cevaplarınız için teşekkürler arkadaşlar fakat yine olmadı. c# kodlarını sıfırdan yazmaya başlıcam artık.
Başlık: Ynt: C# arduino bağlantısı - Ekg sensör
Gönderen: noob - 28 Aralık 2013, 23:26:52
sonuç olarak geldiğim nokta bir richtextbox'a sensörden gelen verileri yazdırabilmek oldu fakat grafiğe dökemiyorum. ayrıca gelen veriler arduino derleyicisindeki serial monitörde sürekli akarken c#'a sadece bir yere kadar geliyor. bu verinin sürekli akmasını sağlayabileceğim bir kod var mı ?