Atmega Bascom odczyt rejestru po RS485 Modbus RTU

Pytania, kody i porady dotyczące nie tylko Bascom.
Zbyszek
Posty: 96
Rejestracja: 30 lis 2017, 17:12

Re: Atmega Bascom odczyt rejestru po RS485 Modbus RTU

Post autor: Zbyszek » 09 cze 2026, 22:48

Siedzę jeszcze w robocie i myślę czy da się tym konwerterem sprawdzić o czym gada licznik z falownikiem ? to bym sobie to rano sprawdził
Zbyszek
Posty: 96
Rejestracja: 30 lis 2017, 17:12

Re: Atmega Bascom odczyt rejestru po RS485 Modbus RTU

Post autor: Zbyszek » 10 cze 2026, 10:29

Wygląda to tak. Żeby sprawdzić kablel który mam od licznika do warsztatu ( bo falownik jest w budynku gospodarczym ) dołożyłem dodatkową skrętkę z warsztatu do licznika i kabel który szedł mi do Atmegi wykorzystałem jako przedłużacz pomiędzy licznikiem a falownikiem. Po połączeniu na aplikacji wskazanie licznika się pokazało, więc kabel dobry. Ściągnąłem Modbus Poll do nasłuchiwania i podłączyłem równolegle tą przelotkę USB-RS485 i zaczęło się pokazywać to co w pliku w załączniku. Jak odepnę kabel od falownika to wiadomo same zera i wtedy włączyłem ten program HTerm , wysyłam ramkę ale nic nie odbieram. Nie ma komunikacjii z licznikiem. Podobna sytuacja jest jak podepnę rejestrator P43 do USB-RS485. Na dedykowanym oprogramowaniu chodzi mam podgląd na przetwornik ( czyli przelotka USB-RS485 dobra ) ale jak wysyłam ramkę przez HTerm to odbieram dokładnie to samo co wysłałem, a w przypadku licznika nie odbieram nic. Nie mam już pomysłu co jest nie tak. Bawiłem się ustawieniami programu ale nic to nie dało.
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Awatar użytkownika
niveasoft
Posty: 1313
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Atmega Bascom odczyt rejestru po RS485 Modbus RTU

Post autor: niveasoft » 10 cze 2026, 13:29

Nie rozumiem tych Twoich opisów. Dla mnie wyrażasz się nieprecyzyjnie. Napisz prosze albo narysuj w paincie topologię tych połączeń. Tak żeby było wiadomo gdzie licznik gdzie falownik gdzie pecet albo atmega. Który jest po drodze itd...

Log wygląda na dość prosty. Zwykłe zapytanie pod adres 1, odczyt rejestrów(&H03) od adresu 1 i prosimy o dziesięć rejestrów (&H0A) i na końcu CRC
...a adres 1 odpisuje że bedzie podawał rejestry (&H03) i że będzie ich 20 (&H14) bo sa dwubajtowe i podaje te rejestry i CRC.... Nie ma na co patrzeć.

Ciekawi mnie kto tu robi TX. Ten program którego używasz czy jak?
Co to za apka o której piszesz?

No naprawdę nie wróżę tu z kuli.
Zbyszek
Posty: 96
Rejestracja: 30 lis 2017, 17:12

Re: Atmega Bascom odczyt rejestru po RS485 Modbus RTU

Post autor: Zbyszek » 14 cze 2026, 14:58

… Znowu weekend w pracy. Trochę postów napisałem … potem usunąłem żeby nie zaśmiecać forum, ale może teraz będzie jaśniej. Sprawdziłem jeszcze raz połączenia i są OK. Kabel od licznika idzie przez mój warsztat do falownika, w warsztacie mam złączkę. Zainstalowałem i ustawiłem program HTerm tak jak sugerowałeś, wpisałem ramkę którą mi podałeś 01 03 20 12 00 02 FF CE i wcisnąłem Enter, ale licznik mi nie odpowiedział. Tu straciłem kupę ( 2 dni ) czasu na szukanie ( głównie po sieci ) sposobu na połączenie się z licznikiem, i wtedy wpadłem na pomysł żeby podsłuchać rozmowę falownika z licznikiem. Podłączyłem licznik do falownika i wpiąłem się do niego równolegle konwerterem USB>>>RS485. Znalazłem w sieci program do podsłuchu linii - Modus Poll i to co mi się wyświetliło na ekranie zapisałem do pliku jako *.log i wstawiłem w poprzednim poście. Szukałem tam m.in. tej twojej ramki … ale nie znalazłem. Dalej przeszukiwanie sieci i znalazłem program Simply Modbus Master ( screen w załączniku ). Podajesz adres slave, funkcję, adres który chcesz odczytać ( podajesz go jako HEX skonwertowany na DEC ) i typ rejestru oraz liczbę rejestrów do odczytania. Program sam w okienku tworzy ci ramkę do wysłania … i wciskasz Send. Pod spodem w okienku otrzymujesz w Hex’ie co licznik odpowiedział i w kolejnym okienku wynik jako liczba dziesiętna ( czyli to co jest na wyświetlaczu licznika ). Do rejestru 2012 Simply Modbus Master utworzył ramkę 01 03 20 12 00 02 6F CE. I tu był błąd zamiast 6F podałeś mi FF. Podłączyłem Atmegę do licznika i równolegle do konwertera USB>>>RS485. Teraz po resecie Atmegi okazało się że wysłała właśnie taką ramkę, ale teraz dlaczego nie odbiera i … kolejny czas. W lewy górnym rogu programu HTerm jest takie okienko do zaznaczenia opisane jako „Show newline characters” jeżeli się tam zaznaczy ptaszka to na końcu ramki którą wysłała Atmega pokazują się dodatkowe znaki 0D 0A. Atmega w rzeczywistości wysyła ramkę tą co trzeba i na jej końcu dodaje od siebie dodatkowe znaki - 01 03 20 12 00 02 6F CE 0D 0A. Wyczytałem że najprostszym sposobem aby się tych znaków pozbyć trzeba na końcu polecenia Print#1… dać średnik ( Print #1 , Makemodbus(1 , 3 , &H2012 , 4); ) czego AI tego nie wiedziało. OK. , wysyła co trzeba ale odczytuje 7 znaków zamiast spodziewanych 9.
Połączenie równoległe Licznik – Atmega - konwerter USB>>>RS485. W oknie Rx programu HTerm pojawia się ramka 01 03 20 12 00 02 6F CE 01 03 04 C6 BC D0 00 5A 9F a na wyświetlaczu Atmegi 01 03 04 C6 D0 5A 9F. To co pojawiło się w oknie Rx programu HTerm to pierwsze 8 znaków które wysłała Atmega a kolejne 9 to odpowiedź licznika czyli 01 03 04 C6 BC D0 00 5A 9F. Czyli Atmega gubi znaki 5 i 7 ( zawsze właśnie te )
HTerm - 01 03 04 C6 BC D0 00 5A 9F
Atmega - 01 03 04 C6 __ D0 __ 5A 9F
Z Simply Modus Master wiemy teraz jaka ma być odpowiedź i mamy wynik czyli wiadomo jak to obliczyć. Wartość to 32-bit IEEE754 float. Czyli jak w screenie HTerm odpowiedź 01 03 04 C6 BC D0 00 5A 9F. Nas interesuje C6 BC D0 00 co wklejamy ( bez spacji ) na stronę https://www.h-schmidt.net/FloatConverter/IEEE754.html w linii Hexadecimal Representation i otrzymujemy wynik jak w screenie -24168, mnożymy przez 0,1 albo dzielimy przez 10 i mamy wynik taki jak na wyświetlaczu licznika DTSU666 w Watach. Dlaczego Atmega gubi znaki przy odczycie ? Tak samo jak podepnę samą Atmegę do laptopa i z HTerm wyślę do Atmegi 01 03 04 C6 BC D0 00 5A 9F to odbierze tylko 01 03 04 C6 D0 5A 9F, czyli bez 5 i 7 znaku ... :?:
Taka ciekawostka - jak z HTerm wyślę do Atmegi 01 03 04 C6 BC to na wyświetlaczu się to wyświetli ( czyli 01 03 04 C6 BC ) ale jeżeli wyślę 01 03 04 C6 BC D0 to na wyświetlaczu mam tylko 01 03 04 C6 D0 - już bez BC. Czyli w trakcie odbierania pomija 5 i 7 znak ... i nie tylko bo jeżeli mu wyślę 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 to na wyświetlaczu pojawi się tylko 01 02 03 04 06 08 11 13 15
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Awatar użytkownika
niveasoft
Posty: 1313
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Atmega Bascom odczyt rejestru po RS485 Modbus RTU

Post autor: niveasoft » 15 cze 2026, 19:08

Duszno ostatnio z wolnym czasem :D

Ten Twój odbiór jest bardzo uproszczony i może program nie nadąża odbierać znaków i jeszcze je drukowaćna LCD.
Takim najprostszym sposobem może być odbiór na przerwaniach. Zobacz czy to wystaczy jak dopiszesz te die linijki:
Config Serialin0 = Buffered , Size 30 i Enable Interrupts.
  1. Config Com1 = 9600 , Parity = None , Stopbits = 1 , Databits = 8
  2. Config Serialin0 = Buffered , Size = 30
  3. Open "COM1:" For Binary As #1
  4. Enable Interrupts
To powinno odbierać znaki do bufora a Ischarwaiting() będzie wskazywał że jest już coś nowego do odebrania nawet jak w miedzyczasie będziesz bazgrał po LCD.
Jak nie pomoże to już trudno i trzeba to będzie napisać profesjonalniej.
Zbyszek
Posty: 96
Rejestracja: 30 lis 2017, 17:12

Re: Atmega Bascom odczyt rejestru po RS485 Modbus RTU

Post autor: Zbyszek » 16 cze 2026, 8:29

Pomogło, teraz wyświetla wszystkie odebrane znaki. Został jeszcze problem w złożeniu 4 bajtów w Single. Spróbuję się tym pobawić bo wynik jest cały czas 0.00. Jak sobie nie poradzę dam znać. :D ( chyba że masz jakiegoś gotowca :D )
Generalnie problem leży w tym

Dim Tempsingle As Single

Poke Varptr(tempsingle) , B1
Poke Varptr(tempsingle) + 1 , B2
Poke Varptr(tempsingle) + 2 , B3
Poke Varptr(tempsingle) + 3 , B4

Value = Tempsingle

Locate 2 , 1
Lcd Fusing(value , "0.00")
Awatar użytkownika
niveasoft
Posty: 1313
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Atmega Bascom odczyt rejestru po RS485 Modbus RTU

Post autor: niveasoft » 16 cze 2026, 9:49

Łap. Ten program można nawet testować w symulatorze Bascom gdy stała #const Sim = 1 (tak jak teraz więc potem sobie zmień na 0)

Program odlicza sekundę po czym wysyła żądanie odczytu do licznika.
Gdy zacznie odbierać bajty od licznika to ustawia timeout i co każdy następny bajt go przedłuża.
Gdy licznik skończy nadawać to ten timeout zejdzie do zera i Atmega uzna że licznik skończył nadawać.
Teraz wiedząc że w trzecim bajcie powinna być ilośc bajtów które powiiniśmy otrzymać sprawdza czy też mamy tyle bajtów. Dodaje do tego trzy bajty na header (01 03 04) i dwa bajty na CRC. czyli teoretycznie 3 + 4 + 2 = 9
Jesli mamy tyle bajtów ile potrzeba to sprawdzamy CRC. Obliczamy je z 7 bajtów a nie z 9. Porównujemy czy CRC się zgadza z tym które mamy na końcu wiadomości od licznika.
Jak się CRC zgadza to ładujemy tę wartośc float do naszej zmiennej. Potem się pozbywam danych po przecinku bo nie wiem czy się do czegoś przydadzą no i masz wynik taki jak ze strony.
  1. $regfile = "m328pdef.dat"
  2. $crystal = 16000000
  3. $hwstack = 64
  4. $swstack = 32
  5. $framesize = 128
  6. $baud = 9600
  7.  
  8. $lib "modbus.lbx"
  9.  
  10. Config Lcd = 16x2
  11. Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.3 , Db6 = Portc.2 , Db7 = Portc.1 , E = Portc.5 , Rs = Portc.0
  12. Cursor Off
  13. Cls
  14.  
  15. Config Portd.4 = Output : Reset Portd.4 : Rs485dir Alias Portd.4
  16. Config Print0 = Portd.4 , Mode = Set
  17.  
  18. Config Com1 = 9600 , Parity = None , Stopbits = 1 , Databits = 8
  19. Config Serialin0 = Buffered , Size = 30
  20. Open "COM1:" For Binary As #1
  21.  
  22. '*************************************************
  23. '*        TIMER2 CONFIG FOR TIME BASE            *
  24. '*************************************************
  25.   Config Timer2 = Timer , Prescale = 1024 , Clear_timer = 1
  26.   Compare2a = 155                                           '10ms @16MHz/1024
  27.  
  28.  
  29. Enable Interrupts
  30.  
  31. Const Timeout_val = 10
  32.  
  33. Const Bufflen = 30
  34.  
  35. Dim Rxbuff(bufflen) As Byte , Rxidx As Byte
  36.  
  37. Dim Rxtimeout As Byte , Gotmsg As Byte
  38.  
  39. Dim Miliseconds As Byte , Helpb As Byte
  40.  
  41. Dim Mycrc As Word , Crcbuff(2) As Byte At Mycrc Overlay
  42.  
  43. Dim Mysingle As Single , Singlebuff(4) As Byte At Mysingle Overlay
  44.  
  45. Dim Mylong As Long , Mystring As String * 16
  46.  
  47. Const Sim = 1 : Dim Simulation As Byte
  48. #if Sim
  49.  $sim
  50.  
  51.  Rxbuff(1) = &H01
  52.  Rxbuff(2) = &H03
  53.  Rxbuff(3) = &H04
  54.  Rxbuff(4) = &HC6
  55.  Rxbuff(5) = &HBC
  56.  Rxbuff(6) = &HD0
  57.  Rxbuff(7) = &H00
  58.  Rxbuff(8) = &H5A
  59.  Rxbuff(9) = &H9F
  60.  
  61.   Rxidx = 9
  62.   Rxtimeout = 1
  63.   Simulation = 1
  64. #endif
  65.  
  66.  
  67. Do
  68.  
  69.  
  70.  If Ischarwaiting(#1) > 0 Then
  71.  
  72.    Rxtimeout = Timeout_val                                  'ustaw timeout bo otrzymujemy znaki
  73.     If Rxidx < Bufflen Then Incr Rxidx
  74.       Rxbuff(rxidx) = Inkey(#1)
  75.  
  76.  End If
  77.  
  78.  
  79.  If Tifr2.ocf2a = 1 Or Simulation > 0 Then                  '10ms
  80.       Tifr2.ocf2a = 1
  81.  
  82.    If Miliseconds < 99 Then
  83.     Incr Miliseconds
  84.    Else
  85.     Miliseconds = 0                                         '1s
  86.  
  87.       Print #1 , Makemodbus(1 , 3 , &H2012 , 4);            'raz na sekunde
  88.  
  89.    End If
  90.  
  91.    If Rxtimeout > 0 Then                                    'otrzymywalismy znaki
  92.     Decr Rxtimeout
  93.  
  94.     If Rxtimeout = 0 Then                                   'przestalismy otrzymywac znaki
  95.      Simulation = 0
  96.       Cls
  97.  
  98.      'spodziewamy sie na przyklad 01 03 04 C6 BC D0 00 5A 9F
  99.      'powinno być 3byte header + tyle co w trzecim + 2byte CRC
  100.       Helpb = Rxbuff(3) + 5                                 'data + 3byte header + 2byte CRC
  101.  
  102.       If Helpb = Rxidx Then                                 'liczba odebranych sie zgadza
  103.         Lcd "IDX OK ,"
  104.  
  105.  
  106.  
  107.        'sprawdz CRC
  108.        Helpb = Rxidx - 2                                    'odebrany bufor minus CRC
  109.        Mycrc = Crcmb(rxbuff(1) , Helpb)
  110.  
  111.        If Crcbuff(1) = Rxbuff(rxidx - 1) And Crcbuff(2) = Rxbuff(rxidx) Then
  112.          Lcd " CRC OK "
  113.  
  114.  
  115.         Singlebuff(4) = Rxbuff(4)                           'zaladuj float do single
  116.         Singlebuff(3) = Rxbuff(5)
  117.         Singlebuff(2) = Rxbuff(6)
  118.         Singlebuff(1) = Rxbuff(5)                          '[EDIT] Uwaga. Blad copy-paste. Tu powino pisać Rxbuff(7)
  119.  
  120.          Mylong = Mysingle                                  'pozbywamy sie przecinka float/single (rzutowanie/cast)
  121.          Mystring = Str(mylong)
  122.          Mystring = Format(mystring , "          ")
  123.  
  124.          Locate 2 , 1 : Lcd Mystring
  125.  
  126.  
  127.        Else
  128.          'CRC sie nie zgadza
  129.           Lcd " CRC ERR"
  130.        End If
  131.  
  132.       Else
  133.        'liczba odebranych sie nie zgadza
  134.         Lcd "IDX ERR,"
  135.       End If
  136.  
  137.       Rxidx = 0
  138.     End If
  139.    End If
  140.  
  141.  End If
  142.  
  143.  
  144.  
  145.  
  146. Loop
  147. End
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Zbyszek
Posty: 96
Rejestracja: 30 lis 2017, 17:12

Re: Atmega Bascom odczyt rejestru po RS485 Modbus RTU

Post autor: Zbyszek » 16 cze 2026, 12:52

Bardzo dziękuję
Awatar użytkownika
niveasoft
Posty: 1313
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Atmega Bascom odczyt rejestru po RS485 Modbus RTU

Post autor: niveasoft » 18 cze 2026, 16:02

Daj znać czy gada :)
Zbyszek
Posty: 96
Rejestracja: 30 lis 2017, 17:12

Re: Atmega Bascom odczyt rejestru po RS485 Modbus RTU

Post autor: Zbyszek » 19 cze 2026, 7:22

Wszystko działa jak należy, jeszcze raz dziękuję.
ODPOWIEDZ