♬ ☘ Moja muzyka do kodowania ♬ ♬ ♬ ☘
♫ ♩ ♪ Vanden Plas ☘ The Ghost Xperiment ♪ ♩ ♫
https://youtu.be/23BzcW8-zAY
Zabawka dalej to kolejny temat majstrowany głównie w celu niezwariowania od siedzenia w domu, wychodzenie na ogród przestało wystarczać. No i dni temu kilka taka mnie tęsknota naszła z nagła za zostawionymi na stoliku w pracy advantechowymi kostkami ADAM, miałam rozgrzebany mega fajny temat komunikacji MODBUS a tu brzdęk, wygnali precz na teleizolację, a klamoty osierocone zostały. No to myśl taka, że może coś na kolanie sobie wydłubię w tych klimatach i z części, które mam po pudełkach. I tak się wykluł pomysł na systemik akwizycji danych, edycja intencyjnie biedna i ekonomiczna - czyli tytułowe bieDAQ. Póki co zwalczyłam odczyt analogowy i działa mi kadłubek komunikacji MODBUS w trybie ASCII, do tego szkice w LabVIEW, niezbyt doskonałe ale także pracują. Dalej może będzie cyfrowe IO jako osobny moduł i będę miała te swoje "ADAMY z Biedry". A jak już nadejdzie kryzys postapokaliptyczny - to będą jak znalazł.
bieDAQ.ai4 - wejścia analogowe
Pisze *.ai4 ponieważ teoretycznie obsługiwany są cztery kanały pomiarowe, tyle po prostu posiada kostka PIC16F876. Btw, dostałam strzał od jednego ludka z Elki - czemu takim starociem się zajmuje? No właśnie dla sportu, przecież do kosza nie wyrzucę. Wprawdzie na horyzoncie widać już zasobową ścianę, głównie w postaci braku pamięci RAM, ale ogólnie to w układ sporo się mieści, nawet pisząc w C. Wracając to tematu - schemat poniżej - podobny był już tu pewnie kilka razy. Dla porządku kilka słów.
Procesor PIC w typowej konfiguracji z zewnętrznym kwarcem, przetwornik A/C PIC-a pracuje z zewnętrznym źródłem napięcia odniesienia na bazie kostki MCP1541. Kolejne kanały pomiarowe zasilają oczywiście termometry MCP9700 oraz LM35. Czwarty kanał póki co się obija. Komunikacja systemowe to MAX485 także w dość typowej konfiguracji. Pierwsze testy były na znanym już konwerterze TTL/RS485 z Chinowa, ale w ramach potaniania zastąpiłam go MAX-em. Komunikacja z człowiekiem zapewnia wyświetlacz LCD, taki zwykły jakich wszędzie pełno. Z powodu zabraknięcia pinów w kontrolerze zastosowanie znalazł układzik CD4094 pracujący jako slave SPI. Wyprowadzeń na ewentualne CS-y jeszcze tam kilka mam, więc to SPI ratuje mi skórę przy tak ubogich peryferiach. No i jeszcze LED-y, które ostały się na płytce z czasów 'PIC na wodę...', służą aktualnie do sygnalizacji aktywności modułu, no i dzięki nim zawsze coś więcej się dzieje na stole. Kolejne etapy ewolucji zabawki mamy na kolażu poniżej.
Wyświetlacz prezentuje surowe dane z przetwornika A/C w formie szesnastkowej, do obserwacji jak układzik się miewa to zupełnie wystarcza. Na płytce stykowej można zauważyć też elementy do spy-485 czyli podglądu magistrali, na schemacie już nie rysowałam, ponieważ to tymczasowy dodatek.
Oprogramowanie na PIC - w załączniku, to w sumie mieszanka moich urojeń w C oraz google, szczególnie odnośnie konfiguracji ADC, łatwo to poznać po niespójności odwołań do rejestrów procesora, raz ba wprost, raz przez pola bitowe.
Gdzieś tam w tym kodzie mym nieszczęsnym zaczaił się błąd i program potrafi się nieoczekiwanie zawiesić. Stąd szybko przeprosiłam się w watchdog-iem, gdyby coś nie pykło - układzik się zresetuje automatycznie.
Programik w LabVIEW także ewoluował - w załączniki kolejne etapy dziergania. Tu przy okazji wyszło jajko kwadratowe z klockami do obsługi Modbus, które przygotowali koleżkowie z National Instruments (znajdziemy je w narzędziu ot zarządzania pakietami VIPM, proszę doinstalować, gdyby ktoś chciał się tym pobawić). Rzeczone jajko polega na tym, że po przestawieniu kostki otwierającej sesję Modbus w tryb ASCII (tekstowy, pamiętamy, że RTU jest binarny) komunikacja odbywa się na siedmiu bitach danych, najstarszy ósmy bit robi za parzystość, bit stopu jest jeden. I w sumie nieważne co ustawimy w klocku, none,even czy odd - i tak w komunikacji jest even. Przynajmniej w tej wersji, która dla LV2014 jest w repozytoriach NI. Po stronie samego LabVIEW nic z tym nie zrobimy, ale z softem na PIC to nie ukrywam - namęczyłam się nieco, wycinanie najstarszego bitu przy odbiorze to pikuś, ale wyliczanie i wstawianie przy nadawaniu....heh, no właśnie na tę okazję powstało spy-485 ponieważ zdarzało się kląć mocniej niż zwykle.
Może kilka zdań o programiku w LV, w wersji która nie tylko odczytuje dane analogowe (funkcja 4) ale i informacje o klamocie (43/13). Kluczowe elementy ponumerowane, zatem mamy tak:
1 - VISA resource name - ekranowa kontrolka pozwalająca wskazać port szeregowy, do którego dołączyliśmy konwerter USB/RS485
2 - Create Modbus Instance - otwarcie sesji z urządzeniami Modbus, konfigurujemy parametry transmisji, wskazujemy ID urządzenia podrzędnego do dalszych operacji zapisu/odczytu. Oczywiście jest osobny klocek to zmiany tej wartości.
3 - Set Timeouts - ustawienie dopuszczalnych czasów oczekiwania na reakcję urządzeń podrzędnych
4 - Read Device Identification - kostka wywołująca funkcję 43 - identyfikacja urządzenia. Wykorzystuje tryb podstawowy (basic) stąd zwrotka zawiera tablicę trzech wartości - producent, produkt, wersja, opakowane w klaster ObjectID+Value [4]. Po pozyskaniu elementów tablicy i dodaniu do każdego CRLF-a można je na przykład wypisać na tekstowym indykatorze Info Text[9] metodą Invoke Node [5] AppendString. Oczywiście na starcie aplikacji warto jego zawartość wyczyścić wpisując pusty napis. Wracamy do Modbus-a.
7 - Read Input Registers - kostka wołające funkcję 4 - odczyt wskazanych rejestrów (w zamyśle analogowych), podajemy ile rejestrów chcemy odczytać oraz od którego zacząć odczyt. Te wartości są specyficzne dla danego urządzenia, każde może mieć przecież inne zasoby.
8 - Shutdown - zamknięcie połączenia z szyną i zwolnienie zasobów, np uchwytów do portu szeregowego.
Jak widać czarów tu nie ma, klocki są łatwe do ogarnięcia i robią to, co należy.
Garstka linków, gdyby komuś MODBUS przypasował, warto to poznać, to standard stary i wygrzany, a na rynku jest ogrom modułów, przystawek, liczników etc/itd obsługujących ten protokół, włączając w to różne (i myślę, że ciekawe) podróbki Advantecha, które zalegają ALI.
http://www.modbus.org/docs/Modbus_Appli ... _V1_1b.pdf
http://www.modbus.org/docs/Modbus_over_ ... _V1_02.pdf
https://www.modbustools.com/modbus.html
https://www.virtual-serial-port.org/art ... cii-guide/
http://www.simplymodbus.ca/FAQ.htm
https://www.fernhillsoftware.com/help/d ... tocol.html
Na koniec oczywiście filmik jak zabawka się sprawuje. Widać też moment zawieszki bieDAQ i sprzętowy reset, czego konsekwencją jest (póki co nieobsłużony) timeout po stronie LabVIEW. Aplikacje obie nie są aktualnie tak idiotoodporne jakbym chciała, stąd te drobne, tymczasowe niedogodności.
https://youtu.be/t4wTBgjARrc
#slowanawiatr
[PIC16F876][LabVIEW] bieDAQ - system zbierania danych z MODBUS/485 (w ciągłej budowie po taniości)
[PIC16F876][LabVIEW] bieDAQ - system zbierania danych z MODBUS/485 (w ciągłej budowie po taniości)
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
______________________________________________ ____ ___ __ _ _ _ _
Kończysz tworzyć dopiero, gdy umierasz. (Marina Abramović)
Kończysz tworzyć dopiero, gdy umierasz. (Marina Abramović)
Re: [PIC16F876][LabVIEW] bieDAQ - system zbierania danych z MODBUS/485 (w ciągłej budowie po taniości)
♬ ☘ Moja muzyka do kodowania ♬ ♬ ♬ ☘
♫ ♩ ♪ The Birthday Massacre ☘ The Sky Will Turn ♪ ♩ ♫
https://youtu.be/KLobWcKG8mo
analogowe bieDAQ.ai4 - ciąg dalszy
Na początek mała zmiana w wystawce - pojawił się całkiem spory wyświetlacz LCD 4x20. Wyświetlacze te przywlokłam kiedyś w bazarku Wolumen, no to jeden doczekał się właśnie występu w mediach. Oprogramowanie ruszyło na nim bez żadnych modyfikacji, w sumie to nie jest dziwne. Oczywiście aktywny obszar ograniczony był do 2x16, ekranik zaprojektowałam pod mały wyświetlacz.
Noo, ale skoro tyle miejsca mam, to może by wyświetlać dane pomiarowe jakoś tak bardziej po ludzku, w formie dziesiętnej i pokazując czego dotyczą. No i ten pomysł zapewnił mi całą masę atrakcji na większą cześć soboty, heh.
Po pierwsze - trzeba obrobić matematycznie dane z przetwornika A/C. W przypadku sensora MCP9700 należy od wynikowego napięcia odjąć 0.5V, oczywiście napięcie to surowa wartość z A/C pomnożona przez 4 mV (Uref 4.094 / 10bit ). Pamiętając, że MCP operuje współczynnikiem 10mV/C - musimy na koniec zarządzić kropką dziesiętną czyli przeskalować wynik z mV na stopnie C dla człowieka.
Dla LM35 (to pozostałe dwa czujniki) jest podobnie, tylko bez odejmowania tego przesunięcia 500 mV. No i tu powstała kwestia natury projektowej - teraz mam czujniki temperatury, a jak będę chciała mierzyć prąd? napięcie? cokolwiek inne? Warto byłoby wykombinować tak, aby podstawowe operacje na wartości z A/C były parametryzowane, a wynik obliczeń opatrzony symbolem wartości fizycznej stosownym do sytuacji.
No i stanęło na tym, że wartość na wyświetlacz jest formatowana przy pomocy matematyki wyższej w postaci funkcji liniowej:
Współczynnik A zapewnia mi konwersję wartości z A/C do napięcia w mV, ponieważ A wynika z wartości napięcia referencyjnego i rozdzielczości przetwornika.
B to przesunięcie na osi rzędnych, w górę lub dół (jak dla MCP9700), pozwala zniwelować (lub narzucić) offset napięciowy jaki pojawia się w fizycznym układzie.
K (a właściwie 1/K) to skala służąca do ustalenia miejsca kropki dziesiętnej.
jednostka - to dwa znaki ASCII, dwie literki pozwalające nazwać liczbę widoczną na wyświetlaczu, ewentualnie mogą tam być dwie spacje.
No super, że tak sobie uroiłam na kartce, to teraz implementacja...no i tu trochę dłubania było. Przede wszystkim powstało zagadnienie gdzie trzymać te współczynniki? No oczywiście w EEPROM, który ma w sobie mały PIC, super. Funkcyjki do zapisu i odczytu EEPROM czyli ee_read() ee_write() zaadoptowane z google do moich lokalnych potrzeb. Są wykorzystywane przez bardziej biznesowe funkcje load/saveCoefficientXXX(), które obsługują zapis/odczyt wartości w imię wskazanego kanału. Formatowanie wartości na ekanik to była jazda sama w sobie, ponieważ dołożenie wygodnego w sumie sprintf() wysadziło mi błąd o braku pamięci kodu i zdechł pies. No, już na okazję CA82 przerabiałam to zagadnienie i ponownie procedurki konwersji floata na napis od gawła pozwoliły wybrnąć z impasu. Pliki real2string.* podłączone na żywioł do projektu skompilowały się bez miałczenia i całość zaczęła żyć, wprawdzie nieco po swojemu, ale jednak.
Kolejny suchar to jak te wartości zadawać i odczytywać zdalnie, via MODBUS. No i tu sprytnie pomyślano o takiej funkcjonalności - protokół definiuje polecenia:
06 Write Single Register - ustalający 16 bitową wartość wskazanego rejestru urządzenia;
03 Read Holding Registers - odczytujący powyższe na podstawie startowego adresu rejestru i ilości sztuk, które chcemy pozyskać
Jest też 16 Write Multiple registers - ale to sobie zostawiłam na później.
Powyższe składniku protokołu udało się zakląć w funkcje executeReadHoldingRegisters() oraz executePresetSingleRegister().
Jak łatwo zgadnąć do obsługi tych komend w LabVIEW mamy stosowne klocki na paletce z MODBUS, pierwszy eksperyment to było polecenie zapisania wybranego parametru w urządzeniu, następnie odczytanie kompletu i sprawdzenie czy jeszcze się zgadza, bo wcale nie musiało... panel i diagram poniżej:
Przykład prezentuje modyfikację opisu jednostek - to dwa znaczki ASCII, które musimy przesłać w ramce polecenia. Zgodnie z podpisami pod kostkami - sztuka polega na przetworzeniu napisu na tablicę bajtów, potem klaster, następnie złożenie dwóch wartości 8-bit w jedno słowo kostką Join Numbers. Adres (a właściwie jego wartość bazowa) rejestru do modyfikacji/weryfikacji zadawany jest z ekranu, to wartości 0x0000,0x0100, 0x0200 lub 0x0300. Offset względem adresu bazowego - 3 - to wskazanie na parametr 'unit' z jednostką. Sam zapis wartości jest trywialny, wywołujemy kostkę Write Single Holding Register i tyle.
Odczyt-weryfikacja także nie jest trudny - mamy komplementarny klocek Read Holding Registers, którego filozofia jest podobna do wspominanej wcześniej 04/Read Input Registers. Podajemy adres bazowy zestawu rejestrów i ile sztuk chcemy pozyskać i uruchamiamy klocek. W odpowiedzi dostaniemy tablicę 16-bitowych wartości liczbowych, oczywiście ich interpretacja jest już całkowicie po naszej stronie, Modbus w to nie wnika ani nic nie narzuca. Przykładowa obróbka tablicy słów polega na pozyskaniu elementarnych wartości kostką Index Array, z wartościami numerycznymi nie ma kłopotu. Nieszczęsne `unit`-y czyli element numer 3 wymagają nieco zachodu: wykonujemy na nim operację Split Number, to taki odpowiednik zawołania HI(x), LO(x) - dostajemy dwa bajty luzem. Na podstawie tych dwóch bajtów budujemy tabelę, następnie klockiem Byte Array to String konwertujemy ją na napis, w tej postaci jest gotowy do prezentacji na kontrolce ekranowej.
No i to w skrócie wielkim cała filozofia obsługi parametrów i sterowania prezentacją na LCD tego mojego dziwadła. Z rzeczy do zrobienia to doimplementowanie operacji 16 Write Multiple registers, tak aby dało się wykonywać zmianę całego pakietu parametrów za jednym zamachem, wybiórcze operacje jak pokazałam powyżej są fajne w demach, ale tak w praktyce to chyba będą nieco upierdliwe. Oczywiście po stronie samego bieDAQ też można coś powymyślać w tej materii - na przykład rezygnację z prezentacji któregoś z kanałów gdy nie ustalono mu unit-a lub pokazywać go jakoś specjalnie gdy ma 'magiczną' wartość. I wszystko byłby pięknie, gdyby nie:
No właśnie - aktualnie projekt ma włączoną optymalizację na rozmiar kodu a i tak zaczyna być ciasno. Tak więc pewnie nieco czasu się zejdzie aby posprzątać ten bajzel w kodzie, pozbyć się redundantnych konstrukcji, może bardziej to wszystko zmodularyzować, zobaczymy.
Filmik na koniec z obu wymienionych labvików na żywo.
https://youtu.be/MgPXS520baU
#slowanawiatr
♫ ♩ ♪ The Birthday Massacre ☘ The Sky Will Turn ♪ ♩ ♫
https://youtu.be/KLobWcKG8mo
analogowe bieDAQ.ai4 - ciąg dalszy
Na początek mała zmiana w wystawce - pojawił się całkiem spory wyświetlacz LCD 4x20. Wyświetlacze te przywlokłam kiedyś w bazarku Wolumen, no to jeden doczekał się właśnie występu w mediach. Oprogramowanie ruszyło na nim bez żadnych modyfikacji, w sumie to nie jest dziwne. Oczywiście aktywny obszar ograniczony był do 2x16, ekranik zaprojektowałam pod mały wyświetlacz.
Noo, ale skoro tyle miejsca mam, to może by wyświetlać dane pomiarowe jakoś tak bardziej po ludzku, w formie dziesiętnej i pokazując czego dotyczą. No i ten pomysł zapewnił mi całą masę atrakcji na większą cześć soboty, heh.
Po pierwsze - trzeba obrobić matematycznie dane z przetwornika A/C. W przypadku sensora MCP9700 należy od wynikowego napięcia odjąć 0.5V, oczywiście napięcie to surowa wartość z A/C pomnożona przez 4 mV (Uref 4.094 / 10bit ). Pamiętając, że MCP operuje współczynnikiem 10mV/C - musimy na koniec zarządzić kropką dziesiętną czyli przeskalować wynik z mV na stopnie C dla człowieka.
Dla LM35 (to pozostałe dwa czujniki) jest podobnie, tylko bez odejmowania tego przesunięcia 500 mV. No i tu powstała kwestia natury projektowej - teraz mam czujniki temperatury, a jak będę chciała mierzyć prąd? napięcie? cokolwiek inne? Warto byłoby wykombinować tak, aby podstawowe operacje na wartości z A/C były parametryzowane, a wynik obliczeń opatrzony symbolem wartości fizycznej stosownym do sytuacji.
No i stanęło na tym, że wartość na wyświetlacz jest formatowana przy pomocy matematyki wyższej w postaci funkcji liniowej:
Kod: Zaznacz cały
y = ( A * adc + B ) / K [jednostka]
Współczynnik A zapewnia mi konwersję wartości z A/C do napięcia w mV, ponieważ A wynika z wartości napięcia referencyjnego i rozdzielczości przetwornika.
B to przesunięcie na osi rzędnych, w górę lub dół (jak dla MCP9700), pozwala zniwelować (lub narzucić) offset napięciowy jaki pojawia się w fizycznym układzie.
K (a właściwie 1/K) to skala służąca do ustalenia miejsca kropki dziesiętnej.
jednostka - to dwa znaki ASCII, dwie literki pozwalające nazwać liczbę widoczną na wyświetlaczu, ewentualnie mogą tam być dwie spacje.
No super, że tak sobie uroiłam na kartce, to teraz implementacja...no i tu trochę dłubania było. Przede wszystkim powstało zagadnienie gdzie trzymać te współczynniki? No oczywiście w EEPROM, który ma w sobie mały PIC, super. Funkcyjki do zapisu i odczytu EEPROM czyli ee_read() ee_write() zaadoptowane z google do moich lokalnych potrzeb. Są wykorzystywane przez bardziej biznesowe funkcje load/saveCoefficientXXX(), które obsługują zapis/odczyt wartości w imię wskazanego kanału. Formatowanie wartości na ekanik to była jazda sama w sobie, ponieważ dołożenie wygodnego w sumie sprintf() wysadziło mi błąd o braku pamięci kodu i zdechł pies. No, już na okazję CA82 przerabiałam to zagadnienie i ponownie procedurki konwersji floata na napis od gawła pozwoliły wybrnąć z impasu. Pliki real2string.* podłączone na żywioł do projektu skompilowały się bez miałczenia i całość zaczęła żyć, wprawdzie nieco po swojemu, ale jednak.
Kolejny suchar to jak te wartości zadawać i odczytywać zdalnie, via MODBUS. No i tu sprytnie pomyślano o takiej funkcjonalności - protokół definiuje polecenia:
06 Write Single Register - ustalający 16 bitową wartość wskazanego rejestru urządzenia;
03 Read Holding Registers - odczytujący powyższe na podstawie startowego adresu rejestru i ilości sztuk, które chcemy pozyskać
Jest też 16 Write Multiple registers - ale to sobie zostawiłam na później.
Powyższe składniku protokołu udało się zakląć w funkcje executeReadHoldingRegisters() oraz executePresetSingleRegister().
Jak łatwo zgadnąć do obsługi tych komend w LabVIEW mamy stosowne klocki na paletce z MODBUS, pierwszy eksperyment to było polecenie zapisania wybranego parametru w urządzeniu, następnie odczytanie kompletu i sprawdzenie czy jeszcze się zgadza, bo wcale nie musiało... panel i diagram poniżej:
Przykład prezentuje modyfikację opisu jednostek - to dwa znaczki ASCII, które musimy przesłać w ramce polecenia. Zgodnie z podpisami pod kostkami - sztuka polega na przetworzeniu napisu na tablicę bajtów, potem klaster, następnie złożenie dwóch wartości 8-bit w jedno słowo kostką Join Numbers. Adres (a właściwie jego wartość bazowa) rejestru do modyfikacji/weryfikacji zadawany jest z ekranu, to wartości 0x0000,0x0100, 0x0200 lub 0x0300. Offset względem adresu bazowego - 3 - to wskazanie na parametr 'unit' z jednostką. Sam zapis wartości jest trywialny, wywołujemy kostkę Write Single Holding Register i tyle.
Odczyt-weryfikacja także nie jest trudny - mamy komplementarny klocek Read Holding Registers, którego filozofia jest podobna do wspominanej wcześniej 04/Read Input Registers. Podajemy adres bazowy zestawu rejestrów i ile sztuk chcemy pozyskać i uruchamiamy klocek. W odpowiedzi dostaniemy tablicę 16-bitowych wartości liczbowych, oczywiście ich interpretacja jest już całkowicie po naszej stronie, Modbus w to nie wnika ani nic nie narzuca. Przykładowa obróbka tablicy słów polega na pozyskaniu elementarnych wartości kostką Index Array, z wartościami numerycznymi nie ma kłopotu. Nieszczęsne `unit`-y czyli element numer 3 wymagają nieco zachodu: wykonujemy na nim operację Split Number, to taki odpowiednik zawołania HI(x), LO(x) - dostajemy dwa bajty luzem. Na podstawie tych dwóch bajtów budujemy tabelę, następnie klockiem Byte Array to String konwertujemy ją na napis, w tej postaci jest gotowy do prezentacji na kontrolce ekranowej.
No i to w skrócie wielkim cała filozofia obsługi parametrów i sterowania prezentacją na LCD tego mojego dziwadła. Z rzeczy do zrobienia to doimplementowanie operacji 16 Write Multiple registers, tak aby dało się wykonywać zmianę całego pakietu parametrów za jednym zamachem, wybiórcze operacje jak pokazałam powyżej są fajne w demach, ale tak w praktyce to chyba będą nieco upierdliwe. Oczywiście po stronie samego bieDAQ też można coś powymyślać w tej materii - na przykład rezygnację z prezentacji któregoś z kanałów gdy nie ustalono mu unit-a lub pokazywać go jakoś specjalnie gdy ma 'magiczną' wartość. I wszystko byłby pięknie, gdyby nie:
No właśnie - aktualnie projekt ma włączoną optymalizację na rozmiar kodu a i tak zaczyna być ciasno. Tak więc pewnie nieco czasu się zejdzie aby posprzątać ten bajzel w kodzie, pozbyć się redundantnych konstrukcji, może bardziej to wszystko zmodularyzować, zobaczymy.
Filmik na koniec z obu wymienionych labvików na żywo.
https://youtu.be/MgPXS520baU
#slowanawiatr
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
______________________________________________ ____ ___ __ _ _ _ _
Kończysz tworzyć dopiero, gdy umierasz. (Marina Abramović)
Kończysz tworzyć dopiero, gdy umierasz. (Marina Abramović)
Re: [PIC16F876][LabVIEW] bieDAQ - system zbierania danych z MODBUS/485 (w ciągłej budowie po taniości)
tasza pisze:Formatowanie wartości na ekanik to była jazda sama w sobie, ponieważ dołożenie wygodnego w sumie sprintf() wysadziło mi błąd o braku pamięci kodu i zdechł pies. No, już na okazję CA82 przerabiałam to zagadnienie i ponownie procedurki konwersji floata na napis od gawła pozwoliły wybrnąć z impasu. Pliki real2string.* podłączone na żywioł do projektu skompilowały się bez miałczenia i całość zaczęła żyć, wprawdzie nieco po swojemu, ale jednak.
Dzięki, to fajna sprawa pomagać wychodzić z impasu
Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse
Re: [PIC16F876][LabVIEW] bieDAQ - system zbierania danych z MODBUS/485 (w ciągłej budowie po taniości)
No, to doimplementowana w końcu funkcja executeWriteHoldingRegisters() czyli Modbus operacja 16, można teraz jednym machnięciem zapisać cały bukiet ustawień dla wybranego kanału ... ale ja nie o tym dziś.
Podganianie części bieDAKa w LabVIEW oznaczało też sporo drobnych, ale jednak koniecznych poprawek z oprogramowaniu dla PIC-a. No i tu powstało zagadnienie - czy do zrobienia byle drobiazgu w C naprawdę muszę od razu wyprowadzać z garażu kombajn pod tytułem MPLABX? Popatrzmy co tam w projekcie przygotowanym dla IDE jest - a oprócz całej masy plików konfiguracyjnych jest też zwykły makefile, ale super. Targety all i clean działają, to dość miło, znaczy się mogę z palca przebudować projekt, a poprawki robić na szybko w dowolnym edytorze. Gorzej z programowaniem przez PICKIT, wizja klikania po IPE niezbyt mi się uśmiechała. No i stanęło na tym, że te wszystkie swoje klamoty zebrałam na boku, nieco uporządkowałam pliki i dorobiłam do nich może i koślawy ale skuteczny, własny makefile:
I teraz tak - opcje wywołania xc8-cc są identyczne jak dla projektu z MPLAB-X, po prostu podejrzałam co on tam wypisywał na konsoli i to samo wstawiłam u siebie. Rzeczone opcje są jak widać dodawane do listy per sztuka, to umożliwi mi zastosowanie w razie potrzeby podejścia - jak czegoś nie rozumiem, to znaczy, że jest niepotrzebne i chlast!
Porozkładanie kodu po plikach w szczególności uplasowanie ich w osobnym folderze `common` wymagało drobnej sztuczki z VPATH, opisane tu:
https://www.gnu.org/software/make/manua ... earch.html
W moim przypadku zapewnia to bezproblemową kompilację plików *.c do dedykowanego na binaria foldera, linker też bez problemu składa aplikację w całość
Z autorskich dodatków - raportowanie ile wolnego w CODE/DATA mi zostało. Super, że linker robi śliczną tabelkę z której wynika, że jest masakra i 99.8% zajęte, ale chyba warto byłoby wiedzieć to tak w bajtach, bez odejmowania w pamięci... No i proszę, robi się przy okazji linkowania pliczek memoryfile.xml z którego encji `/project/executable/memory[@name='program']/free` oraz /project/executable/memory[@name='data']/free` programikiem xmlstarlet można pozyskac te jakże przydatne wartości.
Teraz programowanie kostki. IDE ma programowanie pod ikonką `play`, ale widać, że uruchamia jakieś czarodziejskie skrypty. Chwila z Googlem i już wiadomo, że to ma sporo wspólnego z ipecmd.sh, który w środku uruchamia ipecmd.jar. No i to jest droga to programowania PIC-a z linii poleceń, whooooa! Niestety, specyfika mojej maszyny (niektórzy nazywają to śmietnikiem) polega na posiadaniu aktualnie trzech JDK luzem, 1.8 w wersji 32/64 bit oraz 11. No i lipa nieco, odpalenie ipecmd.jar wymagało żonglerki i zmienną JAVA_HOME i zawartością PATH-a.
Rozwiązanie jest równie proste i skuteczne, co siermiężne - wykorzystanie na wprost tego JRE, które przywlokła ze sobą instalacja MPLABX-a i stąd w makefile mamy dwie deklaracje IPE_JAVA oraz IPE_JAR - to będzie działało w każdych warunkach.
Następna ciekawostka odnośnie programowania to wskazanie sprzętu. Niestety, samolocik cudny Mrija z Chinowa przywiózł tylko artykuły higieniczne, a o zamówionym kolejnym PICKIT3 zapomniał. Nie zmienia to faktu, że pomału oswajam się z myślą o konieczności obsługi dwóch programatorów na raz, powstaje zagadnienie jak je rozróżniać. No i tu koleżkowie z Microchip sprytnie pomyśleli - jeżeli mamy jeden programator wskazujemy do w parametrach wywołania przez podanie typu -TPPK3.
A jak mamy ich więcej - wywołujemy imiennie, po numerze seryjnym: -TSBUR193268621. No i pozostaje mieć tylko nadzieje, że klonowane w Chinowie PICKIT-y mają różne numery seryjne...
W załączniku aktualne źródła, już niezależne od okienkowego IDE, filmik z kompilacji i programowania poniżej. Proszę zwrócić uwagę na tymczasowe pliki MPLABXLog.* pojawiające się w folderze projektu, tak śmieci ipecmd.jar.
https://youtu.be/eiSsJd2OMd0
ps.
Bieżąca wersja ma nieco poprawione formatowanie na ekraniku, dołożone liczniki odebranych ramek (Fxxxx) oraz zrealizowanych transakcji (Txxxx), ze względu na ograniczenia pamięci skrócona kolejka na próbki z przetwornika, póki co cztery uśredniane są cztery sztuki. Na LCD jest jeszcze nieco miejsca, może wymyślę jak to zutylizować.
ps do ps.
Aha, żeby nie było, że ja tu anarchię jakąś - MPLAB-X jest naprawdę fajnym i dobrze zrobionym IDE, dla mnie tym sympatyczniejszym, że opartym o NetBeans (jako Rich-Client Platform, RCP), a z NB do Java korzystam ... chyba od zawsze. Ale jak wspominałam - przy niewielkich projektach warto rozważyć bardziej konsolową i nieco zwinniejszą alternatywę, a co jest warta - przekonać się samodzielnie.
Podganianie części bieDAKa w LabVIEW oznaczało też sporo drobnych, ale jednak koniecznych poprawek z oprogramowaniu dla PIC-a. No i tu powstało zagadnienie - czy do zrobienia byle drobiazgu w C naprawdę muszę od razu wyprowadzać z garażu kombajn pod tytułem MPLABX? Popatrzmy co tam w projekcie przygotowanym dla IDE jest - a oprócz całej masy plików konfiguracyjnych jest też zwykły makefile, ale super. Targety all i clean działają, to dość miło, znaczy się mogę z palca przebudować projekt, a poprawki robić na szybko w dowolnym edytorze. Gorzej z programowaniem przez PICKIT, wizja klikania po IPE niezbyt mi się uśmiechała. No i stanęło na tym, że te wszystkie swoje klamoty zebrałam na boku, nieco uporządkowałam pliki i dorobiłam do nich może i koślawy ale skuteczny, własny makefile:
makefile pisze:Kod: Zaznacz cały
APPNAME = biedaq-ai4
PIC = 16F876
C_FILES := biedaq-ai4.c
C_FILES := ${C_FILES} real2string.c
C_FILES := ${C_FILES} eeprom.c
C_FILES := ${C_FILES} utils.c
# albo -TPPK3 albo -TSserial_no
PROGSER = BUR193268621
INC = -I../common
VPATH = ../common
HEXFILE = ${APPNAME}.hex
TARGET = ${APPNAME}.elf
TEMPDIR = build
# ----- dziwadła, które należy dostosować ------
XC8CC = /opt/microchip/xc8/v2.10/bin/xc8-cc
IPE_JAR = /home/otoja/mplabx/v5.30/mplab_platform/mplab_ipe/ipecmd.jar
IPE_JAVA= /home/otoja/mplabx/v5.30/sys/java/jre1.8.0_181/bin/java
# -- flagi xc8-cc, kompilacja
CC_FLAGS:= -mcpu=${PIC}
CC_FLAGS:= ${CC_FLAGS} -fno-short-double
CC_FLAGS:= ${CC_FLAGS} -fno-short-float
CC_FLAGS:= ${CC_FLAGS} -O2
CC_FLAGS:= ${CC_FLAGS} -fasmfile
CC_FLAGS:= ${CC_FLAGS} -maddrqual=ignore
CC_FLAGS:= ${CC_FLAGS} -xassembler-with-cpp
CC_FLAGS:= ${CC_FLAGS} -mwarn=-3
CC_FLAGS:= ${CC_FLAGS} -Wa,-a
CC_FLAGS:= ${CC_FLAGS} -msummary=-psect,-class,+mem,-hex,-file
CC_FLAGS:= ${CC_FLAGS} -ginhx032
CC_FLAGS:= ${CC_FLAGS} -Wl,--data-init
CC_FLAGS:= ${CC_FLAGS} -mno-keep-startup
CC_FLAGS:= ${CC_FLAGS} -mno-osccal
CC_FLAGS:= ${CC_FLAGS} -mno-resetbits
CC_FLAGS:= ${CC_FLAGS} -mno-save-resetbits
CC_FLAGS:= ${CC_FLAGS} -mno-download
CC_FLAGS:= ${CC_FLAGS} -mno-stackcall
CC_FLAGS:= ${CC_FLAGS} -std=c99
CC_FLAGS:= ${CC_FLAGS} -gdwarf-3
CC_FLAGS:= ${CC_FLAGS} -mstack=compiled:auto:auto
MEMFILE = -Wl,--memorysummary,${TEMPDIR}/memoryfile.xml
OBJ_FILES= $(C_FILES:%.c=${TEMPDIR}/%.p1)
all: ${TEMPDIR}/$(TARGET)
#linkowisko
${TEMPDIR}/$(TARGET): $(OBJ_FILES)
$(XC8CC) $(CC_FLAGS) ${MEMFILE} -o ${TEMPDIR}/${TARGET} $^
@echo "Wolne DATA: \c"
@xmlstarlet sel -t -v "/project/executable/memory[@name='data']/free" ${TEMPDIR}/memoryfile.xml
@echo "\nWolne CODE: \c"
@xmlstarlet sel -t -v "/project/executable/memory[@name='program']/free" ${TEMPDIR}/memoryfile.xml
@echo "\n\nFin.\n"
#c-ompilacja
${TEMPDIR}/%.p1: %.c
mkdir -p ${TEMPDIR}
$(XC8CC) -c $(CC_FLAGS) ${INC} -o $@ $^
clean:
rm -f ${TEMPDIR}/*.*
load:
${IPE_JAVA} -jar ${IPE_JAR} -TS${PROGSER} -P${PIC} -M -F${TEMPDIR}/${HEXFILE} -OL
rm MPLABXLog*
rm log.*
I teraz tak - opcje wywołania xc8-cc są identyczne jak dla projektu z MPLAB-X, po prostu podejrzałam co on tam wypisywał na konsoli i to samo wstawiłam u siebie. Rzeczone opcje są jak widać dodawane do listy per sztuka, to umożliwi mi zastosowanie w razie potrzeby podejścia - jak czegoś nie rozumiem, to znaczy, że jest niepotrzebne i chlast!
Porozkładanie kodu po plikach w szczególności uplasowanie ich w osobnym folderze `common` wymagało drobnej sztuczki z VPATH, opisane tu:
https://www.gnu.org/software/make/manua ... earch.html
W moim przypadku zapewnia to bezproblemową kompilację plików *.c do dedykowanego na binaria foldera, linker też bez problemu składa aplikację w całość
Z autorskich dodatków - raportowanie ile wolnego w CODE/DATA mi zostało. Super, że linker robi śliczną tabelkę z której wynika, że jest masakra i 99.8% zajęte, ale chyba warto byłoby wiedzieć to tak w bajtach, bez odejmowania w pamięci... No i proszę, robi się przy okazji linkowania pliczek memoryfile.xml z którego encji `/project/executable/memory[@name='program']/free` oraz /project/executable/memory[@name='data']/free` programikiem xmlstarlet można pozyskac te jakże przydatne wartości.
Teraz programowanie kostki. IDE ma programowanie pod ikonką `play`, ale widać, że uruchamia jakieś czarodziejskie skrypty. Chwila z Googlem i już wiadomo, że to ma sporo wspólnego z ipecmd.sh, który w środku uruchamia ipecmd.jar. No i to jest droga to programowania PIC-a z linii poleceń, whooooa! Niestety, specyfika mojej maszyny (niektórzy nazywają to śmietnikiem) polega na posiadaniu aktualnie trzech JDK luzem, 1.8 w wersji 32/64 bit oraz 11. No i lipa nieco, odpalenie ipecmd.jar wymagało żonglerki i zmienną JAVA_HOME i zawartością PATH-a.
Rozwiązanie jest równie proste i skuteczne, co siermiężne - wykorzystanie na wprost tego JRE, które przywlokła ze sobą instalacja MPLABX-a i stąd w makefile mamy dwie deklaracje IPE_JAVA oraz IPE_JAR - to będzie działało w każdych warunkach.
Następna ciekawostka odnośnie programowania to wskazanie sprzętu. Niestety, samolocik cudny Mrija z Chinowa przywiózł tylko artykuły higieniczne, a o zamówionym kolejnym PICKIT3 zapomniał. Nie zmienia to faktu, że pomału oswajam się z myślą o konieczności obsługi dwóch programatorów na raz, powstaje zagadnienie jak je rozróżniać. No i tu koleżkowie z Microchip sprytnie pomyśleli - jeżeli mamy jeden programator wskazujemy do w parametrach wywołania przez podanie typu -TPPK3.
A jak mamy ich więcej - wywołujemy imiennie, po numerze seryjnym: -TSBUR193268621. No i pozostaje mieć tylko nadzieje, że klonowane w Chinowie PICKIT-y mają różne numery seryjne...
W załączniku aktualne źródła, już niezależne od okienkowego IDE, filmik z kompilacji i programowania poniżej. Proszę zwrócić uwagę na tymczasowe pliki MPLABXLog.* pojawiające się w folderze projektu, tak śmieci ipecmd.jar.
https://youtu.be/eiSsJd2OMd0
ps.
Bieżąca wersja ma nieco poprawione formatowanie na ekraniku, dołożone liczniki odebranych ramek (Fxxxx) oraz zrealizowanych transakcji (Txxxx), ze względu na ograniczenia pamięci skrócona kolejka na próbki z przetwornika, póki co cztery uśredniane są cztery sztuki. Na LCD jest jeszcze nieco miejsca, może wymyślę jak to zutylizować.
ps do ps.
Aha, żeby nie było, że ja tu anarchię jakąś - MPLAB-X jest naprawdę fajnym i dobrze zrobionym IDE, dla mnie tym sympatyczniejszym, że opartym o NetBeans (jako Rich-Client Platform, RCP), a z NB do Java korzystam ... chyba od zawsze. Ale jak wspominałam - przy niewielkich projektach warto rozważyć bardziej konsolową i nieco zwinniejszą alternatywę, a co jest warta - przekonać się samodzielnie.
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
______________________________________________ ____ ___ __ _ _ _ _
Kończysz tworzyć dopiero, gdy umierasz. (Marina Abramović)
Kończysz tworzyć dopiero, gdy umierasz. (Marina Abramović)
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 1 gość