wstęp
Projekt jest nawiązaniem do projektu opublikowanego przeze mnie wcześniej: Link, dlatego gorąco zachęcam do zapoznania się z nim. Tym razem skupiłem się na części software’owej i zastąpiłem płytę PC modułem mikrokontrolera. Z poprzedniego projektu wykorzystałem algorytmy i struktury danych (programowanie obiektowe) oraz obudowę i układy wejścia/wyjścia (bo je akurat miałem i nie chciało mi się robić lepszych). Nie będę tu omawiał kwestii sprzętowych, bo nie o to tutaj chodzi.
Podsumowując, celem projektu było stworzenie amatorskiego, uniwersalnego programowalnego sterownika, pozwalającego w warunkach laboratoryjnych na szybkie przetestowanie różnych algorytmów sterowania przy przebiegach szybkozmiennych. Zakładana częstotliwość przetwarzania musi wynosić co najmniej 10kHz, aby układ można było wykorzystać do sterowania np. silnikami bezszczotkowymi lub wtryskiem paliwa w silnikach spalinowych.
Podstawowe założenia projektu to:
1. Prosta i tania konstrukcja umożliwiająca wykonanie w warunkach amatorskich
2. Programowanie za pomocą schematu blokowego w środowisku Microsoft Windows
3. Obsługa modułu za pomocą jednej aplikacji – możliwość zapisania konfiguracji do modułu jako funkcja edytora programu
4. Wykorzystanie darmowych rozwiązań software’owych
5. Modułowa konstrukcja
6. Uniwersalność
7. Możliwość przetwarzania sygnałów analogowych (podstawowe funkcje DSP)
8. Możliwość rozbudowy o nowe funkcjonalności
9. Wysoka wydajność – jak najwyższa częstotliwość przetwarzania
Ze względu na wykorzystanie popularnego mikrokontrolera 8-bitowego, w porównaniu z projektem oryginalnym mocno zostanie ograniczona moc obliczeniowa, szczególnie w przypadku sygnałów zmiennoprzecinkowych. Dlatego stopień skomplikowania programu będzie miał kluczowe znaczenie dla częstotliwości przetwarzania.
Sprzęt
Jako moduł sterujący wybrałem Arduino Nano. Aby podłączyć moduł mikrokontrolera do płyty we/wy został wykonany obwód drukowany umożliwiający osadzenie modułu Arduino w taki sposób, aby jego złącze USB było dostępne z zewnątrz obudowy.
Płyta we/wy jest zasilona z wyjścia 5V modułu Arduino. Ten z kolei może być zasilony z portu USB lub z zewnętrznego źródła.
Kompletny sterownik (moduł we/wy + moduł mikrokontrolera)
Programowanie sterownika
Jednym z najważniejszych założeń projektu było szybkie i proste programowanie sterownika. Dla mnie najbardziej naturalnym jest wykorzystanie do tego celu środowiska graficznego, w którym program rysowany byłby w postaci schematu pokazującego połączone funktory logiczne. Daje to większe możliwości i łatwość programowania w porównaniu z tradycyjnymi językami programowania sterowników.
Wymagane funkcje edytora to:
1. Możliwość wyeksportowania grafu do pliku w celu przetworzenia go i wysłania do sterownika,
2. Możliwość definiowania własnych bloków grafu,
3. Możliwość programowania sterownika bezpośrednio z interfejsu edytora.
Biorąc powyższe pod uwagę, jako edytor graficzny wybrałem program Cadsoft Eagle w wersji 6.5, dostępny również w wersji shareware.
Szczególnie przydatne cechy program Eagle to:
1. schematy są zapisywane są w łatwo przetwarzalnej formie tekstowej XML (pliki SCH),
2. istnieje możliwość zdefiniowania własnych przycisków w menu głównym i podpięcia do nich dowolnych poleceń/skryptów,
3. symbole na schemacie mogą mieć przypisaną wartość, co umożliwi modyfikację parametrów funktorów.
Programowanie sterownika będzie polegało więc na:
1. wykorzystaniu specjalnie przygotowanej biblioteki programu Eagle (zawierającej symbole bloków logicznych) do narysowania schematu logicznego przepływy sygnału od wejść sterownika, poprzez bloki funkcyjne do wyjść sterownika,
2. zaprogramowaniu sterownika poprzez wybranie w oknie edytora odpowiednio przygotowanego przycisku, co spowoduje uruchomienie skryptu, który wywoła kolejno czynności:
- Przetworzenie pliku SCH na program w języku C++,
- Skompilowanie programu
- Zapisanie programu w pamięci kontrolera
Oprogramowanie sterujące
Architektura oprogramowania sterującego została zaczerpnięta z oprogramowania w wersji PC. Główne różnice to:
1. Bloki funkcyjne mogą posiadać wiele wyjść.
- klasy bloków mogą posiadać wiele metod zwracających wartości
- Została wprowadzona koncepcja sieci, czyli połączenia dwóch lub wielu elementów
- do każdej sieci może być podłączone tylko jedno wyjście jednego bloku oraz dowolna ilość wejść innych bloków
- wartość sieci liczona jest jako wartość zwracana przez metodę bloku symbolizującą odpowiednie wyjście bloku
- wejścia bloku to zestaw wskaźników na funkcje zwracającą wartość sieci
2. Brak synchronizacji wykonania programu z zegarem sprzętowym. Tym samym prędkość przetwarzania uzależniona jest od skomplikowania algorytmu.
3. Uproszczona struktura plików. Dla każdego bloku istnieje tylko jeden plik C z definicją klasy
4. Wprowadzono dwa typy bloków: logiczny oraz zmiennoprzecinkowy
5. Obiekty bloków oraz relacje między nimi tworzone są statycznie, a nie dynamicznie
6. W każdej iteracji obliczane są wartości tylko wykorzystywanych wyjść sterownika
7. Dla uproszczenia przyjęto, że blok posiada wszystkie wyjścia tego samego typu (binarne albo zmiennoprzecinkowe).
8. Wartości binarne są zapisywane jako typ signed char (zero odpowiada logicznej prawdzie, pozostałe wartości to logiczny fałsz), a wartości zmiennoprzecinkowe jako double.
Kod źródłowy oprogramowania sterującego składa się z trzech głównych części:
1. plik END.C zawierający silnik programu, składający się z funkcji odczytania stanu wejść, funkcji zapisania stany wyjść sterownika oraz głównej pętli programu
2. pliki zawierające definicje klas bloków
3. głównego pliku programu, który zawiera: deklaracje bloków, definicje sieci, funkcję obliczającą wartość wyjść sterownika (funkcja evaluate_outputs) oraz funkcją main.
Przykład programu wykorzystującego tą architekturę pokazuje plik t1.c
Kompletne źródła programu wraz z opisem - plc_avr.zip
Konwersja schematu do programu
Biblioteka elementów
Na potrzeby projektu powstała specjalna biblioteka programu Eagle. Plik PLC.LBR zawiera definicje elementów, których można użyć do zapisania algorytmu sterowania.
W chwili obecnej biblioteka zawiera symbole wejść i wyjść sterownika, bramek logicznych (AND, NOT, OR), wartości stałych, licznika, generatora PWM, dekodera impulsatora oraz wzmacniacza (bloku mnożącego)
Przykładowy schemat programu sterującego
Poniższy przykład pokazuje, jak można wykorzystać sterownik do sterowania jasnością żarówki lub prędkością obracania silnika prądu stałego.
Sterownik został podłączony do impulsatora obrotowego (wejścia nr 11 i 12) oraz małego silniczka modelarskiego na 12V (wyjścia nr 1 i 2).
Plik T1.ZIP zawiera zastosowany graf sterowania. Graf w postaci graficznej
Graf ten składa się z czterech głównych bloków (kolejno od lewej): dekoder impulsatora, licznik, wzmacniacz oraz generator PWM. Dodatkowo na schemacie znajduje się 6 bloków symbolizujących wartości stałe.
W efekcie zaprogramowania sterownika według tego schematu, prędkość obracania się silnika jest regulowana za pomocą impulsatora w zakresie od 2% do 100%.
Skrypt konwertujący
Skrypt konwertujący schemat programu Eagle (plik SCH) do postaci programu w języku C++ został napisany w języku PHP. Do poprawnej pracy tego skryptu wymagane jest więc zainstalowane środowisko PHP.
Skrypt ten pobiera jako parametr nazwę pliku wejściowego i generuje plik o takiej samej nazwie i rozszerzeniu C.
Dokładny opis działania skryptu znajduje się wewnątrz skryptu w postaci komentarzy.
Jako efekt działania skryptu powstaje plik o strukturze przedstawionej na przykładzie pliku t1.c
Kod źródłowy PHP - sch2c.php
Skrypt programujący
Skrypt programujący składa się de facto z dwóch skryptów:
1. skryptu programu Eagle (język ULP), który pobiera nazwę bieżącego pliku SCH i przekazuje ją do skryptu BATCH
2. skryptu BATCH, który wykonuje właściwe operacje
skrypt programuj.ulp ma następująca postać:
schematic(S) {
string com = "D:\\sch2c\\build.cmd " + S.name;
system (com);
}Aby go wywołać należy w oknie edytora schematów wpisać polecenie run programuj
Plik build.cmd wywołuje skrypt konwertujący oraz przenosi wynikowy plik C do folderu D:\sch2c. Następnie plik wynikowy jest kompilowany (avr-c++), linkowany (avr-gcc) i na tej podstawie generowany jest plik HEX (avr-objcopy).
Następnie plik HEX zapisywany jest w pamięci mikrokontrolera za pomocą programu AVRDUDE, przy czym założono, że moduł Arduino widoczny jest w systemie operacyjnym jako port COM10.
Programy avr-c++, avr-gcc, avr-objcopy, avrdude oraz wszelkie niezbędne biblioteki są zawarte w darmowym pakiecie WinAVR, którego zainstalowanie jest niezbędne do poprawnej pracy skryptu.
Przycisk programowania
Aby ułatwić proces programowania uruchomienie skryptu programuj.ULP można przypisać do przycisku w oknie edytora schematów.
Szczegółowy opis, jak ro zrobić na mojej stronie po adresem http://wniedziel.mooo.com/plc/avr. Na tej stronie znajduje się pełny opis projektu, wraz opisem struktur danych zapisanych w plikach SCH.
Co dalej?
W zasadzie projekt można rozwijać w nieskończoność. Poniżej moje pomysły na dalsze modyfikacje.
W kwestii sprzętowej:
1. Poprawienie moduł wyjściowy push-pull z uwzględnieniem diod zabezpieczających,
2. Dodanie diod świecących sygnalizujących stan wejść i wyjść,
3. Zmniejszenie liczby wejść i wyjść, co pozwoli na zamknięcie sterownika w kompaktowej obudowie,
4. sterowanie modułami we/wy bezpośrednio z portów mikrokontrolera (brak magistrali, dekoderów adresowych oraz zatrzasków) kosztem zmniejszenia liczby wejść i wyjść lub zastosowanie modułu mikrokontrolera z większą ilością portów, np. Arduino Mega,
5. wykorzystanie modułu sterującego z mikrokontrolerem Cortex, co pozwoli na wielokrotne zwiększenie mocy obliczeniowej. Moduły Nucleo-32 i Nucleo-64 posiadają rozstaw pinów zgodny z modułami Arduino, co pozwoli na łatwą wymianę modułów,
6. wykorzystanie układu FPGA jako modułu sterującego,
7. Wykonanie sterownika w wersji do montażu na szynę DIN.
Oprogramowanie:
8. Przepisanie skryptu php na PowerShell lub na program wykonywalny exe, co ułatwi korzystanie z niego,
9. Stworzenie programu instalatora, który automatycznie zainstaluje i skonfiguruje wszystkie elementy środowiska programistycznego.
Fajne? Ranking DIY