[ unisoft @ 10.12.2011. 17:21 ] @
Preko programa koji dolazi uz instalaciju Windows XP-a uspesno sam uspostavio komunikaciju sa GSM modulom preko USB uarta. Uspeo sam da posaljem par SMS poruka i da procitam odgovore koje salje GSM modul na racunar ali samo preko HyperTerminal-a. Problem se desava kada sam pokusao da napisem svoj program za slanje SMS poruka u jeziku C#. Ne mogu da procitam odgovore (Respone) koje dobijam na slanje komandi GSM modulu. Napominjem da sam dugo godina radio sa VB6 i da sam se pre par meseci prebacio na .NET okruzenje Vb i C# pa se jos bas najbolje ne snalazim sa nekim naprednijim programiranjem i nemojte da mi zamerite ako sam napravio neke greske u dole napisanom kodu. Zamolio bih vas koji mi odgovorite da mi lepo objasnite sta znaci koja komanda za serijsku komunikaciju ili da mi preporucite neku lepu knjigu ili tutorijal...

Evo kako izgleda komunikacija preko HyperTerminal-a:



Aplikacija u C#:



Kod od aplikacije:

Code:

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

namespace WindowsFormsApplication6
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            cboAvailablePorts.Items.Clear();

            foreach (string strPort in System.IO.Ports.SerialPort.GetPortNames())
                cboAvailablePorts.Items.Add(strPort);
        }

        private void butPortConnect_Click(object sender, EventArgs e)
        {
            if (spoCom.IsOpen != true)
            {
                spoCom.BaudRate = 19200;
                spoCom.DataBits = 8;
                spoCom.DiscardNull = true;
                spoCom.DtrEnable = true;
                spoCom.Handshake = Handshake.None;
                spoCom.NewLine = "\n";
                spoCom.Parity = Parity.None;
                spoCom.ParityReplace = 63;
                spoCom.PortName =(cboAvailablePorts.Text);
                spoCom.ReadBufferSize = 4096;
                spoCom.WriteBufferSize = 2048;
                spoCom.ReadTimeout = 250;
                spoCom.WriteTimeout = 250;
                spoCom.ReceivedBytesThreshold = 1;
                spoCom.RtsEnable = true;
                spoCom.StopBits = StopBits.One;
                spoCom.Open();
                butPortConnect.Enabled = false;
                butPortClose.Enabled = true;
            }
        }

        private void butPortClose_Click(object sender, EventArgs e)
        {
            spoCom.Close();
            butPortConnect.Enabled = true;
            butPortClose.Enabled = false;
        }

        private void butSendCommand_Click(object sender, EventArgs e)
        {
            if (tboCommand.Text != "")
            {
                spoCom.WriteLine(tboCommand.Text.Trim());
                tboCommandWindow.AppendText("Send on " + DateTime.Now + "-->   " + tboCommand.Text + "\n");
            }
        }

        private void spoCom_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            tboCommandWindow.AppendText("Respone on " + DateTime.Now + "-->   " + spoCom.ReadLine() + "\n");
        }

        private void cboAvailablePorts_SelectedIndexChanged(object sender, EventArgs e)
        {
            butPortConnect.Enabled = true;
        }
    }
}

Po pokretanju programa i aktiviranja dogadjaja Data_Recived od spoCom (Serial Port control) dobijem sledecu gresku:



Program bi trebalo da izgleda ovako ... (respone sam ja prosledio kao string, nisam ga procitao sa ulaza USB uart-a).



Postavio sam i sam projekat kao ATTACH-uz post.

[Ovu poruku je menjao unisoft dana 10.12.2011. u 18:37 GMT+1]
[ ha_23 @ 10.12.2011. 21:35 ] @
Eve ispravio sam tvoj kod probaj.


Code:
using System;
using System.IO.Ports;
using System.Windows.Forms;
using System.Windows;
using System.Timers;

namespace WindowsFormsApplication6
{
    public partial class Form1 : Form
    {
        string respone_string;

        public Form1()
        {
            InitializeComponent();
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            cboAvailablePorts.Items.Clear();

            foreach (string strPort in System.IO.Ports.SerialPort.GetPortNames())
                cboAvailablePorts.Items.Add(strPort);
        }

        private void butPortConnect_Click(object sender, EventArgs e)
        {
            if (spoCom.IsOpen != true)
            {
                spoCom.BaudRate = 19200;
                spoCom.DataBits = 8;
                spoCom.DiscardNull = true;
                spoCom.DtrEnable = true;
                spoCom.Handshake = Handshake.None;
                spoCom.NewLine = "\n";
                spoCom.Parity = Parity.None;
                spoCom.ParityReplace = 63;
                spoCom.PortName =(cboAvailablePorts.Text);
                spoCom.ReadBufferSize = 4096;
                spoCom.WriteBufferSize = 2048;
                spoCom.ReadTimeout = 250;
                spoCom.WriteTimeout = 250;
                spoCom.ReceivedBytesThreshold = 1;
                spoCom.RtsEnable = true;
                spoCom.StopBits = StopBits.One;
                spoCom.Open();
                butPortConnect.Enabled = false;
                butPortClose.Enabled = true;
            }
        }

        private void butPortClose_Click(object sender, EventArgs e)
        {
            spoCom.Close();
            butPortConnect.Enabled = true;
            butPortClose.Enabled = false;
        }

        private void butSendCommand_Click(object sender, EventArgs e)
        {
            if (tboCommand.Text != "")
            {
                spoCom.WriteLine(tboCommand.Text.Trim());
                tboCommandWindow.AppendText("Send on " + DateTime.Now + "-->   " + tboCommand.Text + "\n");
            }
        }

        
        private void spoCom_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
           
            respone_string = spoCom.ReadLine();
            
           this.Invoke(new EventHandler(DisplayText));
           
        }

        private void DisplayText(object sender, EventArgs e)
        {
            tboCommandWindow.AppendText("Respone on " + DateTime.Now + "-->   " + respone_string + "\n");
        }


        private void cboAvailablePorts_SelectedIndexChanged(object sender, EventArgs e)
        {
            butPortConnect.Enabled = true;
        }
    }
}


Pozdrav
[ ha_23 @ 10.12.2011. 21:43 ] @
Ovde imas detalno objasnato sta svaka komanda znaci :SerialPort Class MSDN.
Isto dobar tutorial imasna sledeci link: csharp.simpleserial.com



[ unisoft @ 10.12.2011. 22:57 ] @
Ufff. Ispravka. Ne radi, ne mogu opet da procitam informacije sa ulaza USB Uarta. Kao odgovor od modema dobijem komandu koju sam mu poslao :(?.

Postoji li mogucnost da nisu u redu podesavanja veze???

Code:

                spoCom.BaudRate = 19200;
                spoCom.DataBits = 8;
                spoCom.DiscardNull = true;
                spoCom.DtrEnable = true;
                spoCom.Handshake = Handshake.None;
                spoCom.NewLine = "\n";
                spoCom.Parity = Parity.None;
                spoCom.ParityReplace = 63;
                spoCom.PortName =(cboAvailablePorts.Text);
                spoCom.ReadBufferSize = 4096;
                spoCom.WriteBufferSize = 2048;
                spoCom.ReadTimeout = 250;
                spoCom.WriteTimeout = 250;
                spoCom.ReceivedBytesThreshold = 1;
                spoCom.RtsEnable = true;
                spoCom.StopBits = StopBits.One;
                spoCom.Open();
                butPortConnect.Enabled = false;
                butPortClose.Enabled = true;


Podesavanja HyperTerminal-a:



[Ovu poruku je menjao unisoft dana 11.12.2011. u 00:26 GMT+1]
[ ha_23 @ 11.12.2011. 14:04 ] @
Kaj mene radi komunikacija preko virtual serial port emulator, keirao sam dva com porta COM2 i COM3 kako pair, i preko
terminala prima i praca komande. E sad so realni hardware mozda nesto zeza oko podesavanja veze.
Probaj bez podesivane samo spoCom.BaudRate = 19200;
Drugo po default.

Mislim da na ova tema nije mesto "mikrokontroleri" :)
[ unisoft @ 11.12.2011. 16:03 ] @
Zamolio bih te da preuzmes fajl (.rar) koji sam postavio na www.megaupload.com. To je snimak ekrana laptop-a u toku komunikacije sa GSM modulom preko VS i HyperTerminal-a. Video ce te uveriti da ne radi preko VS komunikacija, ni slanje, a ni citanje...

http://www.megaupload.com/?d=WJ13VE9W

Fajl ima nepunih 6MB (duzina je 2min, u *avi formatu), msl da ti nece biti problem da ga preuzmes sa net-a ako imas ADSL (nadam se) :D.
[ ha_23 @ 11.12.2011. 18:37 ] @
Pregledao sam video, evo i ja sam postavio video na postupak kako sam ja testirao tvoj program.
link:http://www.megaupload.com/?d=18K6UGA0
Inace mozda e problem ReadTimeout i WriteTimeout, kako sto vidim po default COM port e podesen ReadTimeout = -1 i WriteTimeout = -1.
Probao sam i tako:
spoCom.ReadTimeout = -1;
spoCom.WriteTimeout = -1;
i simulacija e opet radila.
Inace procitan string sa komandom ReadLine(); mora na kraj da ima znak LF(Line Feed), mada to nije probljem takvi stringovi vraca modem.
Neznam sta bi moglo biti problem.

Pozdrav.
[ unisoft @ 11.12.2011. 21:56 ] @
Upisivao sam i druge vrednosti za ReadTimeout i WriteTimeout: 100, 300, 500... i ne vredi, nece da procita odgovor sa GSM modula. Video si kada sam preko HyperTerminal-a poslao komandu AT+COPN (komanda za listu svih mreznih operatera) i u trenutku ispisa odgovora na formi od HyperTerminal-a LED diode na USB UARTU se ne gase (ne trepere) i Rx i Tx, tj. sijaju sve vreme dok traje ispis, a kada posaljem komandu iz VS programa samo trepne LED Rx USB Uarta (nema odgovora od GSM modula) znaci komanda je stigla do USB uarta ali nije prosledjena do GSM modula jer da je prosledjena modem bi odgovorio sa OK ako je komanda ispravna, a sa ERROR ako nije ispravna. LED Tx lampica bi morala barem da blinkne ako je kratka informacija (ako je samo OK ili ERROR odgovor), a ako je duza (kao AT+COPN niz informacija) da sija sve vreme.???

Trenutno sam u corsokaku. Ne znam sta da radim. Probao sam primer sa MSDN i nece i sa njim. Jedina opcija koja mi je jos ostala je da probam sa Encoding-om informacija koje se primaju i salju... pa cemo da vidimo sta ce tada da se desi.

Jos uvek ne odustajem jel znam da postoji nacin samo trenutno jos nemam taj nivo znanja koji je potreban za to :D. Kao sto sam naglasio u prvom postu tek sam se prebacio na C#, pre par meseci, a dugo godina sam radio sa VB6, a ovo je vec napredno programiranje (komunikacija sa eksternim uredjajima).

E video ti je dobar. Svidja mi se program koji si koristio za emulaciju portova. Toliko mi je puta tako nesto trebalo i morao sam da bacam pare na convertere jel nisam znao da takvi programi postoje. Tnx :D.

Nisam ni ranije sumnjao da tebi radi, a meni ne. Ocito je da treba jos nesto uraditi sto ja i ti ne znamo, za sada. Ako komunikacija preko HyperTerminal-a radi bez greske,a sa VS nece... moze samo da se izvede jedan zakljucak.

[Ovu poruku je menjao unisoft dana 12.12.2011. u 07:39 GMT+1]
[ ha_23 @ 12.12.2011. 10:40 ] @
U potpunost slazem se, i javi ako resis problem :)
I dobro bi bilo jos neko ko vec radio nesto slicno da se ukluci u diskusii.
Ja sam radio komukinacii u C#, ali ne sa realnim hardwerom nego sa Proteus simulator, i nemam zasada problem,
tako da i mene interesira sta bi moglo da bude pricina da ovo neradi u VS a hoce u terminal.

Mozda ovo bi moglo da pomogne http://www.elitesecurity.org/t433918-MAX-MAX-protiv-GM

Citat: "Obzirom da sam resio problem ne bi bilo lose da napisem u cemu je bio stos. Na kraju svake AT komande treba dodati jos "\r\n"."




[Ovu poruku je menjao ha_23 dana 12.12.2011. u 12:38 GMT+1]
[ shpiki @ 12.12.2011. 13:43 ] @
Zasto ce maltretiras sa C# ako mozes to da odradis u VB? Ako je "skripa" i u VB, mogu da pokusam da pomognem...
I ne mora "\n" na kraju svake komande, dovoljno je "\r" ili "Cr" ili chr(13) - decimalno, chr(D) - hexadec, itd...
[ unisoft @ 12.12.2011. 15:21 ] @
Hvala. Spasao si me sati mucenja, nadam se. Ako stignem probacu veceras. Ne znam kako nam nije proradio kliker da kaga mu prosledimo neku komandu on nam kao odgovor vrati istu stvar :(? Pa lepo rekoh da sam se tek prebacio na .NET okruzenje (pre par meseci). Lepsi mi je C# :D...
[ unisoft @ 13.12.2011. 09:17 ] @
Najzad smo uspeli :D. Bilo je potrebno dodati samo "\r" uz svaku prosledjenu komandu. Sada imam samo jedan mali problem. Ponekad se desava da odgovor od modema mi ne stane u jedan red, tj. ako je modemu prosledjena komanda AT odgovor treba da bude OK ili ERROR i taj odgovor treba da stane u jednu liniju. Meni se desi da u jednu liniju ispise ERRO i u drugu liniju ispise R. Ostalo mi je samo malo da se igram sa BUFFER-om i Encoding-om i sve ce biti OKee.

Hvala na pomoci ha_23, spasao si me sati, dana, a mozda i meseci mucenja (a bilo je potrebno samo dodati \r) :D !!! Tnx

[Ovu poruku je menjao unisoft dana 13.12.2011. u 10:31 GMT+1]
[ ha_23 @ 13.12.2011. 11:54 ] @
Super :D, Da dovolno e samo "\r", probaj so ReadExisting() umesto ReadLine() a isto i sa velicina buferom .
Bitno bilo da dobies respone :)