Strona 1 z 3

Łączenie bajtów do jednej zmiennej

: 28 lut 2019, 20:07
autor: Henryk
Witam :D
Nie miał chłop problemu , to go sobie wymyślił ;) ćwiczę przesyłanie danych przez HC-05 i urodził się problem .
Odczyt jednego znaku Ascii nie jest problemem , to ich połączenie w jeden ciąg lub odebranie n,znaków daje mi nieźle w koś .
Jak już wiadomo w transmisji danych i ich obróbce jestem cieniutki , ale cięgle próbuję czegoś się nauczyć :)
Poniżej moje dzisiejsze wypociny .
Co zamierzałem osiągnąć ? odebrać trzy znaki Ascii (liczby) , połączyć w jedną zmienną string i zwrócić z tej zmiennej wartość do zmiennej Word .
  1. $regfile = "m8def.dat"
  2. $crystal = 8000000
  3. $hwstack = 32
  4. $swstack = 16
  5. $framesize = 32
  6. $baud = 9600
  7. Config Serialin = Buffered , Size = 10
  8. Config Lcd = 20 * 4
  9. Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
  10.  
  11.  
  12. Dim Suma As String * 3 , A As String * 1 , B As String * 1 , C As String * 1
  13. Dim Serial_flag As Byte
  14. Dim Serial_rx(3) As Byte
  15. Dim Liczba As Word
  16. Cursor Off
  17. Cls
  18. Enable Interrupts
  19. Do
  20.  
  21.  Serial_flag = Ischarwaiting()
  22.  
  23.     If Serial_flag = 1 Then
  24.      Inputbin Serial_rx(1) , 3
  25.     A = Chr(serial_rx(1) , 1)
  26.     B = Chr(serial_rx(2) , 1)
  27.     C = Chr(serial_rx(3) , 1)
  28.     Locate 1 , 1 : Lcd "znak1 " ; A ; "  "
  29.     Locate 2 , 1 : Lcd "znak2 " ; B ; "  "
  30.     Locate 3 , 1 : Lcd "znak3 " ; C ; "  "
  31.  
  32.     Suma = Space(3)
  33.     Insertchar Suma , 1 , A
  34.     Insertchar Suma , 2 , B
  35.     Insertchar Suma , 3 , C
  36.     Liczba = Val(suma)
  37.     Waitms 100
  38.  
  39.     Locate 4 , 1 : Lcd "Txt " ; Suma ; "Dec->" ; Liczba ; " "
  40.     End If
  41.     Waitms 100
  42.     Loop
  43.  
  44.  End
Nie mam za bardzo pojęcia jak uprościć ten proces łączenia danych .

Re: Łączenie bajtów do jednej zmiennej

: 28 lut 2019, 20:41
autor: Pikczu
jeśli dobrze rozumiem chcesz zrobić tak:

0011 0001, 0011 0010,0011 0011 - dane binarne
Teraz z tego string "123" i wsadzić do word ?
Proste ale mało sensowne:
  1. Dim A As Byte , S As String * 10
  2. dim B as word
  3. A = 123
  4.  
  5. S = Str(a)
  6.  
  7. Print S                                                     ' 123
  8. 'teraz z ze stringa trzeba zrobić normalna zmienną
  9. b= val(s)
Edit
twoje stringi są za małe :o :lol:
Pamiętaj z e string ma jeszcze terminacje z 00 na końcu każdy string jak deklarujesz musi być (+) plus 1.

Re: Łączenie bajtów do jednej zmiennej

: 28 lut 2019, 20:52
autor: Henryk
Witaj Pikczu :D
Ogólnie chodzi o obróbkę danych odebranych np. wysyłam z terminala liczbę 12345 jako ascii i chcę tą wartość umieścić w zmiennej Dword .
Wiem , że to co wypociłem wygląda dziwacznie :lol: wykorzystałem twój fragment programu bo działa , moje kombinacje zawodziły ;)

Re: Łączenie bajtów do jednej zmiennej

: 28 lut 2019, 21:38
autor: Henryk
Doczytałem się w tej diabelskiej pomocy Bascoma :D
  1. $regfile = "m8def.dat"
  2. $crystal = 8000000
  3. $hwstack = 32
  4. $swstack = 16
  5. $framesize = 32
  6. $baud = 9600
  7. Config Serialin = Buffered , Size = 10
  8. Config Lcd = 20 * 4
  9. Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
  10.  
  11.  
  12. Dim Suma As String * 6
  13. Dim Serial_flag As Byte
  14. Dim Liczba As Dword
  15. Cursor Off
  16. Cls
  17. Enable Interrupts
  18. Do
  19.  
  20.  Serial_flag = Ischarwaiting()
  21.     If Serial_flag = 1 Then
  22.      Inputbin Suma , 6
  23.       Liczba = Val(suma)
  24.         Waitms 100
  25.        Locate 1 , 1 : Lcd "Txt " ; Suma ; " "
  26.      Locate 2 , 1 : Lcd "Dec->" ; Liczba ; " "
  27.    End If
  28.     Waitms 100
  29.     Loop
  30.  
  31.  End
Ale to nie znaczy ,że już wiem wszystko ;)

Re: Łączenie bajtów do jednej zmiennej

: 28 lut 2019, 21:57
autor: Pikczu
Widzę że już rozkminiłeś, coś tam skleciłem z twojego pierwszego kodu.
Aha nie rób inputbin to jest dobre do tablic ty wysyłasz same znaki.
Jakimś cudem config lcd wywala mi cały czas ostrzeżenie :roll:
  1. $sim
  2. $regfile = "m8def.dat"
  3. $crystal = 4000000
  4. $hwstack = 40
  5. $swstack=16
  6. $framesize = 32
  7. Config Serialin = Buffered , Size = 20
  8. Config Lcd = 20 * 4
  9. Config Submode = New
  10. $projecttime = 3
  11. $version 0 , 0 , 3
  12.  
  13. Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
  14.  
  15.  
  16.  
  17. Dim Suma As String * 5 , A As String * 2 , B As String * 2 , C As String * 2
  18. Dim Serial_flag As Byte
  19. Dim Serial_rx(3) As Byte
  20. Dim Liczba As Word
  21. Dim Znak_ As Byte
  22. Dim Uart_komenda As String * 20                             'musi byc wystarczjaco dlugie
  23. Dim Ile_elementow_1 As Byte
  24. Dim Getcommands(10) As String * 10                          'tablica na pociete komendy
  25. Cursor Off
  26. Cls
  27. Enable Interrupts
  28.  
  29. Sub Uartrx_:
  30.   Cls
  31.    Ile_elementow_1 = Split(uart_komenda , Getcommands(1) , " ")       'This choping coomand after space
  32.    Debug Chr(13)
  33.  
  34.    Debug "uart_command= " ; Uart_komenda
  35.    Debug "Getcommands(1)= " ; Getcommands(1)
  36.    Debug "Getcommands(2)= " ; Getcommands(2)
  37.    Debug "Getcommands(3)= " ; Getcommands(3)
  38.  
  39.    Print                                                    'to dla wyświetlania poprawnych odstepow
  40.    Locate 1 , 1 : Lcd "znak1 " ; Getcommands(1) ; "  "
  41.    Locate 2 , 1 : Lcd "znak2 " ; Getcommands(2) ; "  "
  42.    Locate 3 , 1 : Lcd "znak3 " ; Getcommands(3) ; "  "
  43.    Getcommands(1) = ""                                      'czysczenie bufora
  44.    Getcommands(2) = ""                                      'czysczenie bufora
  45.    Getcommands(3) = ""
  46.     Liczba = Val(uart_komenda)                              'czysczenie bufora
  47.    Locate 4 , 1 : Lcd "Txt " ; Suma ; "Dec->" ; Liczba ; " "
  48. End Sub
  49.  
  50.  
  51.  
  52.  
  53.  
  54. Do
  55.  
  56.    If Ischarwaiting() > 0 Then
  57.       Znak_ = Waitkey()                                     'pobierz znka z bufora
  58.       If Znak_ = 13 Or Len(uart_komenda) > 6 Then           ' jelsi ENTER lub wiecej niz 6 znaków to call uartrx
  59.          Call Uartrx_                                       '
  60.          Uart_komenda = ""
  61.       Else
  62.          Uart_komenda = Uart_komenda + Chr(znak_)           'kluczowe budowanie bufora
  63.          Print Chr(znak_) ;                             'to jest echo zeby było widac co przychodzi
  64.       End If
  65.    End If
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73. Loop
  74.  
  75. End

Re: Łączenie bajtów do jednej zmiennej

: 01 mar 2019, 18:58
autor: Henryk
Witam :D
Pikczu ale mi namieszałeś w głowie tą przeróbką :D dziękuje za ten przykład , przy okazji poczytałem jak działa split.

Wspomniałeś , że zmienne string są za małe ( string*1 ) , czegoś nie rozumie.
Zerknij na ten kod , opis w komentarzach .
  1. Dim Suma As String * 10     ' jeśli mam string*10 to do dwóch ostatnich pozycji tej zmiennej są przepisywane dwie pierwsze .
  2. ' przykład : wysyłam z terminala osiem znaków  ABCDEFGH , to po odebraniu zmienna ma postać ABCDEFGHAB ,
  3. ' a każde kolejne przesłanie tego samego ciągu znaków przesuwa je o kolejne dwie pozycje w prawo .
  4. ' jeśli string * 8 odbieram cały ciąg poprawnie .
  5. Dim Serial_flag As Byte
  6. Cursor Off
  7. Cls
  8. Enable Interrupts
  9. Do
  10.  
  11.  Serial_flag = Ischarwaiting()
  12.     If Serial_flag = 1 Then
  13.       Inputbin Suma , 8
  14.          Waitms 100
  15.        Locate 1 , 1 : Lcd "Txt " ; Suma ; "    "
  16.          End If
  17.        Waitms 100
  18.     Loop
  19.  
  20.  End
Może mieć na to wpływ bufor ?

Re: Łączenie bajtów do jednej zmiennej

: 01 mar 2019, 20:26
autor: Pikczu
Na początek, zmień printbin na inkey lub waitkey, wywal waitms 100 , dodaj bufor.
Ja za ten czas przetestuje twój kod.

Re: Łączenie bajtów do jednej zmiennej

: 01 mar 2019, 20:43
autor: Henryk
Pikczu pisze:
01 mar 2019, 20:26
Na początek, zmień printbin na inkey lub waitkey, wywal waitms 100 , dodaj bufor.
Ja za ten czas przetestuje twój kod.
Bufor mam w kodzie ( Size = 10 ) , tylko nie wklejałem całości .
Ta opcja z printbin bardzo mi odpowiada ;)
Kod w całości z wywalonym waitms , w tej postaci odbieram ciąg ABCDEFGH za każdym razem poprawnie .
  1. $regfile = "m8def.dat"
  2. $crystal = 8000000
  3. $hwstack = 32
  4. $swstack = 16
  5. $framesize = 32
  6. $baud = 9600
  7. Config Serialin = Buffered , Size = 10
  8. Config Lcd = 20 * 4
  9. Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
  10.  
  11.  
  12. Dim Suma As String * 8
  13. Dim Serial_flag As Byte
  14. Cursor Off
  15. Cls
  16. Enable Interrupts
  17. Do
  18.  
  19.  Serial_flag = Ischarwaiting()
  20.     If Serial_flag = 1 Then
  21.       Inputbin Suma , 8
  22.           Locate 1 , 1 : Lcd "Txt " ; Suma ; "    "
  23.            print " odebrano dane "
  24.          End If
  25.         Loop
  26.  
  27.  End
Edit :
Dopisałem do kodu potwierdzenie odbioru ;) print "odebrano dane " , ślicznie odpowiada układ .
IMG_20190301_210248.jpg

Re: Łączenie bajtów do jednej zmiennej

: 01 mar 2019, 21:23
autor: Pikczu
No widzisz :)
input bin jest raczej przewidziany do odbioru tablic nie pojedynczych znaków.
do budowania tekstu lub całych zdań używa się inkey() i składa się literki do kupy mniej więcej tak:
Suma = Suma + Chr(znak)
  1. $sim
  2. $regfile = "m8def.dat"
  3. $crystal = 8000000
  4. $hwstack = 32
  5. $swstack = 16
  6. $framesize = 32
  7. $baud = 9600
  8. Config Serialin = Buffered , Size = 20
  9. Config Lcd = 20 * 4
  10. Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
  11. Debug On
  12.  
  13.  
  14. Dim Tablica(10) As Byte
  15. Dim Suma As String * 10 At Tablica(1) Overlay               'to jets nakladka na tablice czyli kazda litera bedzie zapisana do osbnego bajtu
  16.     '***************************************************************************
  17.     ' jesli mam string*10 to do dwóch ostatnich pozycji tej zmiennej sa przepisywane dwie pierwsze .
  18.     ' przyklad : wysylam z terminala osiem znaków  ABCDEFGH , to po odebraniu zmienna ma postac ABCDEFGHAB ,
  19.     ' a kazde kolejne przeslanie tego samego ciagu znaków przesuwa je o kolejne dwie pozycje w prawo .
  20.     ' jesli string * 8 odbieram caly ciag poprawnie .
  21.  
  22.  
  23. Dim Flaga As Byte
  24. Dim Serial_flag As Byte
  25. Dim Znak As Byte
  26. Const Przyklad = 2                                          'Henryk zmien to na 2 i kompiluj zeby spawdzic przykldad 2
  27.  
  28. Cursor Off
  29. Cls
  30. Enable Interrupts
  31.  
  32. Flaga = 1
  33.  
  34.  
  35.  
  36. #if Przyklad = 1
  37.    Debug "pierwszy test"
  38.    Do
  39.       If Ischarwaiting() = 1 Then
  40.          Inputbin Tablica(1) , 8
  41.              'Waitms 100
  42.            'Locate 1 , 1 : Lcd "Txt " ; Suma ; "    "
  43.          Debug "komorka 1 =" ; Tablica(1) , 1
  44.          Debug "komorka 2 =" ; Tablica(2) , 1
  45.          Debug "komorka 3 =" ; Tablica(3) , 1
  46.          Debug "komorka 4 =" ; Tablica(4) , 1
  47.          Debug "komorka 5 =" ; Tablica(5) , 1
  48.          Debug "komorka 6 =" ; Tablica(6) , 1
  49.          Debug "komorka 7 =" ; Tablica(7) , 1
  50.          Debug "komorka 8 =" ; Tablica(8) , 1
  51.          Debug "komorka 9 =" ; Tablica(9) , 1
  52.          Debug "komorka 10 =" ; Tablica(10) , 1
  53.          Flaga = 1
  54.       End If
  55.            'Waitms 100
  56.       If Flaga = 1 Then                                        ' zeby nie migac wysiwetlaczem tylko wyswietlac po przyjsciu nowych danych
  57.  
  58.          Locate 1 , 1 : Lcd "Txt " ; Suma ; "    "
  59.          Flaga = 0
  60.       End If
  61. #else
  62.  
  63.  
  64.  
  65.    Debug "drugi test"
  66.    Do
  67.       If Ischarwaiting() > 0 Then
  68.          Znak = Inkey()                                        'pobierz znak z bufora
  69.          If Znak = 13 Or Len(suma ) > 10 Then               ' jelsi ENTER lub wiecej niz 10 znaków to call uartrx
  70.             Locate 1 , 1 : Lcd "Txt " ; Suma ; "    "            '
  71.  
  72.  
  73.             Suma = ""                                          'kasuj odebrane dane
  74.          Else
  75.             Suma = Suma + Chr(znak)                         'kluczowe budowanie bufora
  76.             Print Chr(znak) ;                                  'to jest echo zeby było widac co przychodzi
  77.          End If
  78.  
  79.  
  80.  
  81.       Debug "komorka 1 =" ; Tablica(1) , 1
  82.       Debug "komorka 2 =" ; Tablica(2) , 1
  83.       Debug "komorka 3 =" ; Tablica(3) , 1
  84.       Debug "komorka 4 =" ; Tablica(4) , 1
  85.       Debug "komorka 5 =" ; Tablica(5) , 1
  86.       Debug "komorka 6 =" ; Tablica(6) , 1
  87.       Debug "komorka 7 =" ; Tablica(7) , 1
  88.       Debug "komorka 8 =" ; Tablica(8) , 1
  89.       Debug "komorka 9 =" ; Tablica(9) , 1
  90.       Debug "komorka 10 =" ; Tablica(10) , 1
  91.       Flaga = 1
  92.    End If
  93.            'Waitms 100
  94.    If Flaga = 1 Then                                        ' zeby nie migac wysiwetlaczem tylko wyswietlac po przyjsciu nowych danych
  95.  
  96.       Locate 1 , 1 : Lcd "Txt " ; Suma ; "    "
  97.       Flaga = 0
  98.    End If
  99. #endif
  100.  
  101. Loop
  102.  
  103. End
U mnie na symulatorze printbin niezbyt działa.
Nadpisuje pozostałe komórki tym samym znakiem.
Natomiast test nr 2 działa dużo lepiej.

**************************************************edit*****************************
Co do stringów jak chcesz zapisać jedna literę to deklarujesz jak na dwie dim litera as string *2 bo do stringa jest dokładane 00 na końcu.

Re: Łączenie bajtów do jednej zmiennej

: 01 mar 2019, 21:45
autor: Henryk
Działa pięknie , "1" wyświetla tekst w całości , "2" znak po znaku :D dziękuje za przykład .

Mam pytanie : jak zbudować zabezpieczenie kiedy któryś z bajtów nie dojdzie , lub przesłano ich więcej ?
Przed chwilą zrobiłem doświadczenie i wysłałem zamiast 8 ...9 bajtów i dzieją się cuda na wyświetlaczu .
Czy jest możliwość zliczenia przychodzących bajtów do bufora i po weryfikacji dopiero odbierać :?: