środa, 5 października 2016

[27] Arduino - Przetwornik R-2R

W związku z tym, że płytka Atmega328 nie posiada konwertera cyfrowo analogowego to chciałbym zaprezentować jeden z najprostszych sposobów na jego wykonanie.

Przetwornik R-2R

Zasada jego działania jest bardzo prosta. Do budowy wykorzystuje się rezystory o wartościach, jak sama nazwa wskazuje, równych R lub wartości podwojonej czyli 2R. Ilość wykonanych skoków pozwala na określenie jaką rozdzielczość będzie posiadał przetwornik. Na rysunku poniżej przetwornik 8 oraz 10 bitowy.

Rys. 1. Przetwornik 8 bitowy

Rys. 2. Przetwornik 10 bitowy

Jest to dosyć tania alternatywa dla przetworników scalonych w układach zewnętrznych. Wiadomo, że nie będzie to posiadało tak dobrej dokładności jak układ zewnętrzny, natomiast będzie od niego sporo tańsze. Dodatkowo każdy z "bitów" tego przetwornika odpowiada jednemu wyprowadzeniu mikrokontrolera. Co znacząco zmniejsza ilość pinów GPIO z układu. Zasada działania tego przetwornika opiera się na układaniu rezystorów w dzielniki napięć. Dodatkowo impedancja wyjściowa jest zawsze równa R.


Programowanie


Za każdym razem gdy chce się wygenerować odpowiednią wartość napięcia. Dzielenie rozpoczyna się od wartości 1/2 napięcia zasilającego czyli np 5V lub 3,3V. Dalej schodzi się odpowiednie 1/4, 1/8, 1/16, 1/32 itp. W celu otrzymania żądanej wartości napięcia można dokonać włączenia kilku linii, czyli np. połączyć 1/2 i 1/8 wartości napięcia.

Jak już wspomniałem wcześniej aktywacje danego elementu układu wykonuje się poprzez ustawienie stanu wysokiego na odpowiednim wyprowadzeniu. 

Dane wyprowadzenia w celu otrzymania przebiegu należy cyklicznie włączać i wyłączać.

Jeśli chodzi o Arduino to program może wyglądać następująco:

  1. #define PIN0 0
  2. #define PIN1 1
  3. #define PIN2 2
  4. #define PIN3 3
  5. #define PIN4 4
  6. #define PIN5 5
  7. #define PIN6 6
  8. #define PIN7 7
  9. void setup() {
  10.   pinMode(PIN0, OUTPUT);
  11.   pinMode(PIN1, OUTPUT);
  12.   pinMode(PIN2, OUTPUT);
  13.   pinMode(PIN3, OUTPUT);
  14.   pinMode(PIN3, OUTPUT);
  15.   pinMode(PIN4, OUTPUT);
  16.   pinMode(PIN5, OUTPUT);
  17.   pinMode(PIN6, OUTPUT);
  18.   pinMode(PIN7, OUTPUT);
  19. }
  20. void loop() {
  21.   int i = 0;
  22.   //Przebieg trójkątny
  23.   for(= 0; i<512; i++)
  24.     set_data(i);
  25.   for(i=510; i>0; i++)
  26.     set_data(i);
  27. }
  28. //Wartosci zostaja ustawione poprzez cykliczne
  29. //Wlaczanie i
  30. void set_data(byte x)
  31. {
  32.   digitalWrite(PIN0, x & (1<<7));
  33.   digitalWrite(PIN1, x & (1<<6));
  34.   digitalWrite(PIN2, x & (1<<5));
  35.   digitalWrite(PIN3, x & (1<<4));
  36.   digitalWrite(PIN4, x & (1<<3));
  37.   digitalWrite(PIN5, x & (1<<2));
  38.   digitalWrite(PIN6, x & (1<<1));
  39.   digitalWrite(PIN7, x & 1);
  40. }

Dane dla innych przebiegów można wykonać przez odpowiednie dobranie punktów pomiarowych i odpowiednie zdefiniowanie jej w tablicy. Tak jak zostało to wykonane w przykładach dla STM32. Ta sama zasada tworzenia układu towarzyszy każdemu z rodzaju mikrokontrolera.

Sygnał możne zostać odpowiednio zmodulowany poprzez dodawanie bądź odejmowanie ilości próbek. Można też odczekać pewną ilość czasu. Dane wyjściowe z buffora można oczywiście odpowiednio wzmocnić poprzez zastosowanie wzmacniacza operacyjnego.