Close

c# a arduino seriova komunikace

Úvodní stránka Fórum Vaše projekty Arduino c# a arduino seriova komunikace

Označeno štítky: , , , ,

  • Toto téma obsahuje celkem 3 odpovědi. Do diskuze (1 diskutující) se naposledy zapojil uživatel dehtak a poslední změna proběhla před 7 roky a 12 měsíci.
Aktuálně jsou na stránce zobrazeny 4 příspěvky - 1. až 4. (celkem z 4)
  • Autor
    Příspěvky
  • #6621
    dehtak
    Účastník

    Zdravim resim takovou zalezitost.
    Na arduinu mam asi 16 spinacu (Shiftin) a 32 kanalu (TLC5940).
    Kdyz stisknu nektery ze spinacu arduiono posle data pocitaci, ten data zpracuje a posle zpatky. A tady mi to prave kulha. Bud muzu data odesilat urduinu bez problemu, nebo arduino muze posilat data pocitaci bez problemu. Ale jakmile chci zpracovat prijata data a odeslat zpatky.
    Jako by se zahltila seriova linka.
    Myslim ze chyba je v C#

    v c# to mam takto

    
    void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
        int count = arduino.BytesToRead;
        byte[] ByteArray = new byte[count];
        arduino.Read(ByteArray, 0, count); 
          // ByteArray[1] urcuje jakou akci provadet
          // ByteArray[0] jsou data k z pracovani
           if(ByteArray[1]==1) arduinoIsConnect = true; 
           if(ByteArray[1]==2){invoke(Spinac((int)ByteArray[0])); }
        }
    
    private void Spinac (int i){
      if (i==1){
       // 1 hodnota kanal 
       // druha hodnota intenzita svitu
       //3 hodnota urcujici o kterou akci se jedna
        
       arduino.Write(new byte[3] {1,255,2}, 0, 3);// kanal 1 cervena 255 max hodnota 
       arduino.Write(new byte[3] {2,127,2}, 0, 3);// kanal 2 zelena
       arduino.Write(new byte[3] {3,255,2}, 0, 3); // kanal 3 modra
      }
    }

    myslim ze problem je ve metode DataReceivedHandler jelikoz ta vypisuje data z arduina tudiz nemohu poslat data zpatky dokud se linka neuvolni. Jak ale prijmout data, zpracovat je a odeslat zpatky ?

    #6624
    dehtak
    Účastník

    u arduina mam v loop

       if(Serial.available()==3){
        int inData[3] = { Serial.read(), Serial.read() , Serial.read()};
       // odesle odpoved zda je arduino pripojeny 
        if (inData[2]==1){SendData[0]=1; SendData[1]=1; Serial.print(SendData);     
        // jedna se o akci nastavit kanal odesle prijmuta data funkci setRGB 
        if (inData[2] == 2){
            setRGB(inData[0],inData[1]); //odesle TLC5940    
       }
      }
    #6628
    dehtak
    Účastník

    Abych vysvetlil o co se jedna. Jde o desku ovladajici elektroniku v domacim kine. Roztahovani zavesu, spusteni vodopadu, nekolik kanalu svetel , stmivani (ruzne nastavitelne efekty. Fotku plosnaku sem dal do prilohy.
    Dejme tomu ze kanal 1,2,3 je v podstate 1 RGB kanal crevena,zelena, modra , kanal 24 a 25 jsou 2 rele ktere prepinaji 12 V jednou stav 1 = +- stav 2 vypnuto stav3 -+
    Pro motor ktery zveda oponu. Vsechny tyhle vlastnosti kanalu jsou ulozeny v programu v pc. Kde si uzivatel naprogramuje co ma jakej kanal delat kdy se spinat. Tak treba pro kanal1 (tj na desce kanal 1,2,3) si nastavi ze se zapne cervene svetlo 10 sekund bude svitit pak se ztmavy pomalu dalsich 10 sekund az do vypnuti. Vsechno proste bude neprogramovatelne v pocitaci a ten jen bude odesilat data v arduinu.
    Stejne jako tech 16 spinacu v programu v pc si uzivatel navoli jakej spinac ma co delat. pokud se sepne spinac arduino odesle pocitaci ten najde patricnou sekvenci dat pro tento spinac a posle to zaptky arduinu. Dejme tomu spinac jedna ma rosvitit 1 svetlo cerveny 2 bili ale jen napul a zapne treba vodopad. Arduino odesle prikaz 1,2 pocitac koukne prvne na cislo 2 vi aha to je prikaz pro spinace vezme cislo 1 a vi aha to je spinac jedna , najede si do databaze vybere patricny data a odesle arduinu
    1,255,2 // 1 svetlo cerveny
    4,127,2 // kanal 1 2 svetla pul cervena
    5,127,2 // kanal 2 2 svetla pul zelena
    6,127,2 // kanal 3 2 svetla pul modra
    30,255,2 // zapne se vodopad.
    Jde o to ze v seriovy komunikaci nemuzu pouzivat Delay nebo thread.Sleep a ty data je potreba posilat co nejrychleji. Jelikoz tam jde o cas .
    Vsechno uz mam hotovy az na to ze nemuzu z kompu poslat zpracovana data
    jde maximalne poslat 1 sekvence 3 cisel ale odezva je dost dlouha asi 100ms
    pri odeslani vice sekvenci se ztrati spojeni s arduinem . Skousel jsem vsechno delay thread sleeep mezi sekvencemi nebo pockat 1 sekundu co se data prijmou a pak odeslat zpracovana data. Pokazde je to stejny .
    Prez try { odeslat} catch{vypys chybu} to nevyhazuje zadny chyby.Zkousel jsem i zavrit port a znovu ho otevrit a poslad data. Taky nejde

    Mozna by ste me mohli poradit serial je mozna dost pomalej nemel bych pouzut lan nebo neco jineho , nebo ted jsem narazil na docela zajimavou knihovnu pro arduino jmenuje se to cmdMessenger CmdMessenger Mate s tim nekdo zkusenosti ? Nebylo by mozna lepsi pouzit toto ?
    V podstate moje seriova komunikace vali perfektne a nerad bych ted prepisoval kod pro arduino a komplet program kvuji jiny seriovy komunikaci. Myslim ze problem je jen v ty funci v C# DataReceivedHandler jelikoiz je to funkce cteci z arduina a nemuzu z ni volat funci zapisovaci do arduina. Zkousel jsem ze to i tak ze funkce DataReceivedHandler nastavi statickou promenou spinac = prijata data a pak prez timer se kouknu jestli spinac ma nastavena data a zpracuje pozadavek a odesle. Taky nejde. Proste se ty funkce musi od sebe oddelit funkce precte nastavi a ukonci se. Druha funkce precte nastaveni zpracuje a odesle. Ale jak to kua vyresit.

    Attachments:
    #6633
    dehtak
    Účastník

    Myslim ze jsem na to prisel, jeste to nemam otestovany uplne. Ma to cosi spolecnyho s delagatama a invoke , vubec nevim o co se jedna

     public partial class Form1 : Form
        {
    
            public delegate void DataReceivedEventHandler(int data);
            public event DataReceivedEventHandler OnSerialDataReceived;
    
     
    
            public Form1()
            {
                InitializeComponent();
                Control.CheckForIllegalCrossThreadCalls = false;
    arduino.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.DataReceivedHandler);
                OnSerialDataReceived += new DataReceivedEventHandler(SepnutySpinac);  
            }
            
    
            private void Form_load(object sender, EventArgs e)
            { 
                arduino.PortName = Properties.Settings.Default.ArduinoPort;
                arduino.BaudRate = Properties.Settings.Default.ArduinoBaudrate;
    
                try{
                    arduino.Open();
                    ArduinoSend(1, 1, 1);                
                }catch{
                    MessageBox.Show("Arduino neni pripojeny !!");  
                }
            }
    
            public void SepnutySpinac(int data)
            {
                this.Invoke(new EventHandler(delegate
                {
                    richTextBox1.Text += "" + data+"\n";  
                   
                }));
            }
    
            public void ArdConnected(bool v)
            {
                this.Invoke(new EventHandler(delegate
                {
                    if (v) { ArduinoStatus.Text = "Pripojeno"; } else { ArduinoStatus.Text = "Nepripojeno..."; }
                }));
            }
    
            void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
            {
                int spinac = 0; 
                int i = arduino.BytesToRead;
                if (i >= 2)
                {
                    byte[] data = new byte[i];
                    arduino.Read(data, 0, i);
                    if (data[1] == 1 && data[0] == 1) { ArdConnected(true); }
                    if (data[1] == 2) {spinac = data[0];} 
                    
                    if (OnSerialDataReceived != null){ OnSerialDataReceived(spinac); }
                }              
            }
Aktuálně jsou na stránce zobrazeny 4 příspěvky - 1. až 4. (celkem z 4)
  • Pro reakci na toto téma se musíte přihlásit.