logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Przesyłanie RS232 "nie stringów"

fliper_katrill 16 Cze 2010 23:04 2508 13
  • #1 8198418
    fliper_katrill
    Poziom 20  
    Witam!
    Mam bardzo proste pytanie, nie mam pojęcia w tym temacie.
    Przy wysyłaniu z dajmy na to sterownika danych powiedzmy z Bascoma stosujemy "Print". To co odczytuję z portu RS232 to string, czemu? Może mogą być to inne typy danych? Pytam bo drażni mnie ta późniejsza konwersja ( w c# ) danych z COMa ze stringa na jakieś typy liczbowe. Jak i czy się da wysłać liczbę i otrzymać liczbę?
  • #2 8198981
    chudybyk
    Poziom 31  
    Przez RS232 wysyła się bajty. Ośmiobitowe liczby. Interpretacja tych liczb zależy od programisty. Wysyłając znaki w kodzie ASCII (ośmiobitowe) można je odebrać jako pojedyncze znaki tekstowe, ale również jako liczby. Przy ciągach tekstowych i liczbach wielobajtowych trzeba się zastanowić nad identyfikacją początku lub końca ciągu bajtów, które przesyłane bajty reprezentują.
    Przez RS232 da się przesłać każdą informację cyfrową, w tym tekst, liczby, multimedia, czy kto tam co wymyśli. Odpowiednio zakodowane.
  • #3 8200304
    fliper_katrill
    Poziom 20  
    To wychodzi na to, że ja przesyłam stringi o długości 5 znaków (XX.XX) no i jeden znak to pewnie bajt czyli 5 bajtów w sumie. Na podglądzie wiem, że są one przedzielone "\r\n" , co zatem zrobić w takim przypadku? Programuję w c#.
  • Pomocny post
    #4 8202196
    chudybyk
    Poziom 31  
    Znaki terminujące - czyli "\r\n", ewentualnie NULL, zazwyczaj kończą zmienne typu string. Nie sądzę, żeby były wysyłane po każdym znaku. Nie programowałem w C#, ale wydaje mi się, że kompilator dodaje Ci te znaki automatycznie. Spróbuj odbierane znaki zapisać do zmiennej innego typu, np "byte" lub "char".
    Jak wygląda Twoja procedura odbierająca znaki z RS232?
  • #5 8202259
    fliper_katrill
    Poziom 20  
    Link
    Dziękuję że zainteresowałeś się moją sprawą to jest link do całego kodu mojego programu :)
  • #6 8202301
    chudybyk
    Poziom 31  
    W funkcji"serialPort1_DataReceived " używasz "ReadExisting()", które zwraca dane typu string. Zamiast tego spróbuj użyć ReadByte() lub Read(). Poczytaj trochę o klasie "SerialPort".
  • #7 8202600
    fliper_katrill
    Poziom 20  
    ReadByte czyta mi tylko 2 cyfry i to z kosmosu, oczywiście wprowadziłem konwersję int na string do programu wcześniej wspomnianego
  • #8 8202774
    chudybyk
    Poziom 31  
    Rzuć kodem, który nie działa. Pewnie źle interpretujesz otrzymane dane.
  • #9 8203163
    fliper_katrill
    Poziom 20  
    
    
            string dane;
            int RxString;
    ....................................
        private void serialPort1_DataReceived
              (object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            {
                RxString = serialPort1.ReadByte();
                this.Invoke(new EventHandler(DisplayText));
            }
    
    ....................................
         private void DisplayText(object sender, EventArgs e)
            {
    
                dane = Convert.ToString(RxString);
                //textBox1.Text(RxString);
                label1.Text=dane;
                //y = double.Parse(RxString);
            }
    .....................................
    


    To są w sumie kawałki odpowiedzialne za czytanie a reszta się nie zmieniła jest w linku powyżej :) Jeszcze raz dzięki.
  • Pomocny post
    #10 8203313
    chudybyk
    Poziom 31  
    Funkcja "serialPort1_DataReceived " pobierze tylko 1 bajt. Zostanie on skonwerowany do postaci liczbowej - czyli do zakresu 0..255 i coś takiego wyświetlisz. Jeśli odebraną daną jest kawałek tekstu, to będzie to wartość liczbowa kodu ASCII odebranego znaku.
    Co w zasadzie chcesz odbierać? Tekst, czy liczby? Pojedyncze znaki ASCII można odebrać przez ReadChar();
  • #11 8203751
    fliper_katrill
    Poziom 20  
    Najlepiej liczby, bo stringi mi coś źle odczytuje, tak jak wspominałem jest to liczba XXXX powiedzmy, że doprowadzę ją do postaci XXX (max 400), bo nie chcę komplikować z double XX.X bo taki jest właściwy format.Podsumowując ma być liczba z zakresu 0-400 (255 to za mało). Dzięki
  • #12 8210529
    chudybyk
    Poziom 31  
    No to teraz z drugiej strony sznurka. ;-)
    Jakie dane są wysyłane przez tego RS-a? W jakim formacie i czy jest tam zaimplementowany jakiś protokół? Te liczby są w formacie binarnym, BCD, ASCII? Masz kawałek kodu, który wysyła dane?
    To w zasadzie niemożliwe, żeby procedury obsługi RS-a działały nieprawidłowo. Ciągle uważam, że źle interpretujesz przesyłane dane, albo też urządzenie wysyłające źle koduje wartości.
  • #13 8211394
    fliper_katrill
    Poziom 20  
    
    'Program przygotowany dla zestawu EvB 4.3 firmy And-Tech.pl
    
    'Definicja procesora dla:
    ' Mega16 wpisać m16def.dat
    ' Mega32 wpisać m32def.dat
    ' Mega644p wpisać m644pdef.dat
    $regfile = "m32def.dat"
    
    'Częstotliwość kwarcu domyślnie 16MHz
    $crystal = 16000000
    
    $hwstack = 32                                               ' default use 32 for the hardware stack
    $swstack = 10                                               'default use 10 for the SW stack
    $framesize = 40                                             'default use 40 for the frame space
    
    
    'Podłączenie pinów LCD do mikroprocesora
    ' BL = PortC.1
    ' Rs = PortC.2
    '  E = PortC.3
    'Db4 = PortC.4
    'Db5 = PortC.5
    'Db6 = PortC.6
    'Db7 = PortC.7
    
    Config Lcdpin = Pin , Rs = Portc.2 , E = Portc.3 , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7
    Config Lcd = 16 * 2
    
    'Pin podświetlenia LCD
    Config Portc.1 = Output
    Set Portc.1
    
    Cls
    Cursor Off
    Lcd "Test DS18B20"
    
    Dim Lsb As Byte
    Dim Msb As Byte
    Dim Tempa As Single
    Dim Tekst1 As String * 10
    
    
    
    'Pin do czujnika DS18B20
    Config 1wire = Pind.4
    Dim Ds(8) As Byte
    
    1wreset
    1wwrite &H33
    Ds(1) = 1wread(8)
    
    Do
    
    1wreset
    1wwrite &HCC
    1wwrite &H44
    Wait 1
    
    1wreset
    
    1wwrite &HCC
    1wwrite &HBE
    
      Lsb = 1wread():
      Msb = 1wread():
    
      Tempa = Msb * 256
      Tempa = Tempa + Lsb
      Tempa = Tempa / 16
      Tekst1 = Fusing(tempa , "#.##")
    
      Locate 2 , 1
      Lcd "DS18B20= " ; Tekst1
      Print Tekst1
      //Próbowałem też z Print Tempa
    Loop
    
    Ot i cały kod Bascoma, może teraz uda się Tobie mi pomoć :) Dzięki
    
    
  • Pomocny post
    #14 8212977
    chudybyk
    Poziom 31  
    Nie lubię i nie używam Basica, ale moim zdaniem jest tak:
    PRINT wysyła dane typu STRING, a FUSING zamienia liczby na ciągi ASCII. Dodatkowo PRINT wysyła znaki końca wiersza.
    Żeby wysłać bajt spróbuj CHR() mniej więcej tak:
    PRINT CHR(Msb); CHR(Lsb)
    

    Teraz wysłane zostaną dwa bajty - starszy i młodszy a za nimi znaki końca wiersza.
    Teraz odbierając musisz przesunąć starszy bajt o 8 bitów w lewo i dodać młodszy. Musisz też olać znaki nowego wiersza.
REKLAMA