Tajemnice wejść analogowych Arduino Leonardo i Yun

W Arduino Leonardo i Arduino Yun zastosowano inny kontroler niż w tradycyjnych płytkach. Jest nim ATmega32u4. Ma on kilka zalet w porównaniu z poprzednikami – sprzętowe USB, więcej wyjść PWM i więcej wejść analogowych.

Wejścia analogowe oprócz tradycyjnych cech opisanych w poprzednim wpisie mają też nowe możliwości.

long readADC(byte ref, byte input)
{
  ADMUX = (input & 31) | ((ref & 3) << 6);
  bitWrite(ADCSRB, 5, ((input & 32) >> 6));
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  long result = ADCL;
  result |= ADCH<<8;
  
  return result;
}

void setup() 
{
  while (!Serial);
  Serial.begin(9600);
}

void loop() 
{
  Serial.println(readADC(3, 39));
  delay(1000);
}

Użyta w programie funkcja readADC pozwala je odkryć.

word value = readADC(ref, input);

  • value – wartość odczytana z wejścia analogowego (0 – 1023)
  • ref – numer źródła napięcia referencyjnego
  • input – numer wejścia analogowego.

Argument “ref” może przyjąć następujące wartości:

  • 0 – napięcie referencyjne to napięcie zasilania
  • 1 – napięcie referencyjne pochodzi z pinu AREF
  • 3 – napięcie referencyjne pochodzi z dokładnego źródła 2,56 V

Jeśli czytałeś poprzedni wpis to zadanie i możliwości napięcia referencyjnego są ci znane.

Dużo ciekawiej jest z drugim argumentem “input”. Zacznę od standardowych możliwości.

Wprowadzając tam jedną z tych wartości odczytujesz standardowe wejścia analogowe:

  • 0    A5
  • 1    A4
  • 4    A3
  • 5    A2
  • 6    A1
  • 7    A0
  • 32    D4/A6
  • 33    D12/A7
  • 34    D6/A8
  • 35    D8/A9
  • 36    D9/A10
  • 37    D10/A11

Do tej pory nuuuda. Wszystko prawie jak bibliotekach Arduino, tylko bardziej zagmatwane ;-). Jednak mamy do dyspozycji więcej liczb w tym argumencie, które kryją dodatkowe możliwości.

Następna grupa to:

  • 30    1.1 V
  • 31    0 V
  • 39    Temperatura

Wartość 30 argumentu podaje na wejście przetwornika dokładne napięcie 1,1 V. Pozwala to skalibrować wynik podawany przez wejście i napięcie odniesienia. Tak jak w poprzednim wpisie.

Wartość 31 podaje na wejście analogowe 0 V. To taka wartość testowa, czy przetwornik zwróci wynik 0.

Wartośc 39 odczytuje temperaturę panującą w środku kontrolera. Pomiar nie jest zbyt precyzyjny. Ma dokładność +/-10 stopni Celsjusza. Służy głównie do tego by kalibrować wewnętrzne elementy wrażliwe na temperaturę (jak generator RC). Trudno nim zmierzyć temperaturę w pokoju, bo przecież kontroler też się nagrzewa podczas pracy.

Kolejne wartości dotyczą wejść symetrycznych.

Standardowo wejścia analogowe Arduino mierzą napięcie między pinami GND i wybranym wejściem analogowym.

W wejściach symetrycznych dostajesz do dyspozycji 2 wejścia analogowe. Jedno z biegunem dodatnim “+”, a drugie z biegunem ujemnym “-”. Napięcie jest mierzone między tymi biegunami.

Wejścia symetryczne ułatwiają wiele obwodów w których nie chcesz do pomiarów używać GND. Jak np. w pomiarze prądu za pomocą rezystora o małej wartości, albo przy czujnikach wagi w układzie mostka.

Wartości wejść symetrycznych to:

  • 16    +A5    -A4
  • 20    +A3    -A4
  • 21    +A2    -A4
  • 22    +A1    -A4
  • 23    +A0    -A4

Czyli biegun dodatni takiego wejścia jest w wybranym pinie A0, A1, A2, A3, A5, a biegun ujemny jest w pinie A4.

Wejścia symetryczne mają jeszcze jedną opcję. Pozwalają przepuścić wejście przez wzmacniacz i wzmocnić sygnał od 10 do 200 razy.

Kombinacja wejść symetrycznych i siła wzmocnienia przypisana jest do następujących wartości:

  • 9    +A4    -A5    x10
  • 11    +A4    -A5    x200
  • 38    +A4    -A5    x40
  • 40    +A3    -A5    x10
  • 41    +A2    -A5    x10
  • 42    +A1    -A5    x10
  • 43    +A0    -A5    x10
  • 44    +A3    -A4    x10
  • 45    +A2    -A4    x10
  • 46    +A1    -A4    x10
  • 47    +A0    -A4    x10
  • 48    +A3    -A5    x40
  • 49    +A2    -A4    x40
  • 50    +A1    -A5    x40
  • 51    +A0    -A5    x40
  • 52    +A3    -A4    x40
  • 53    +A2    -A4    x40
  • 54    +A1    -A4    x40
  • 55    +A0    -A4    x40
  • 56    +A3    -A5    x200
  • 57    +A2    -A5    x200
  • 58    +A1    -A5    x200
  • 59    +A0    -A5    x200
  • 60    +A3    -A4    x200
  • 61    +A2    -A4    x200
  • 62    +A1    -A4    x200
  • 63    +A0    -A4    x200

Wzmocnienie 200 razy przy napięciu odniesienia 2,56 V pozwoli zmierzyć napięcia nawet do 12,5 mikrowolta.

sprae

Dokładniejsze wejścia analogowe w Arduino Yun i Leonardo

Każde Arduino ma wejścia analogowe w sekcji ANALOG IN (od A0 do A5). Pozwalają one dokładnie mierzyć napięcie.
Arduino Yun i Leonardo mają więcej wejść analogowych. Są one ukryte w pinach sekcji DIGITAL.

  • Pin cyfrowy 4 to wejście analogowe A6
  • Pin cyfrowy 6 to wejście analogowe A8
  • Pin cyfrowy 8 to wejście analogowe A9
  • Pin cyfrowy 9 to wejście analogowe A10
  • Pin cyfrowy 10 to wejście analogowe A11
  • Pin cyfrowy 12 to wejście analogowe A7

Napięcie na wejściach analogowych mierzysz za pomocą funkcji “analogRead”

word value = analogRead(numer_wejścia);

Gdzie:

  • value – zmienna przechowująca wynik pomiaru od 0 do 1023. Gdzie 0 to 0 V, a 1023 to domyślnie 5 V.
  • numer_wejścia – numer wejścia analogowego zależnie od pinu w Yun to wartości do 0 dla pinu A0 do 11 dla pinu A11.

Dokładność pomiaru wejść analogowych zależy od napięcia odniesienia.

Napięcie odniesienia to wzorcowe napięcie, przy którym przetwornik wejścia analogowego wskazuje wartość maksymalną (1023).

Napięcie odniesienia ustawiasz za pomocą funkcji “analogReference”.

analogReference(reference);

reference – rodzaj napięcia odniesienia.
Rodzaj wybieramy za pomocą stałych, gdzie:

  • DEFAULT – napięciem odniesienia jest napięcie zasilania około 5 V
  • INTERNAL – napięciem odniesienia jest dokładne napięcie 2,56 V
  • EXTERNAL – napięciem odniesienia jest napięcie podłączone do pinu AREF

W zależności od tego jaki zakres wyjść ma czujnik podłączony do wejścia analogowego, wartość napięcia odniesienia powinna być większa lub równa z jego zakresem.

Najbardziej dokładny jest rodzaj INTERNAL, ale nadaje się od tylko do urządzeń z wyjściem od 0 do 2,5 V (np pojedyncze ogniwa baterii).

Najmniej dokładny jest rodzaj DEFAULT, bo napięcie zasilania nie ma idealnie 5 V. Zmienia się pod wpływem różnych warunków np. obciążenia, albo zakłóceń.

Można poprawić dokładność pomiaru z referencją DEFAULT. W tym celu przerobiłem mały programik, który zwróci dokładne napięcie odniesienia.

long readVcc()
{
  ADMUX = _BV(REFS0) | _BV(MUX1) | _BV(MUX2) | _BV(MUX3) | _BV(MUX4);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  long result = ADCL;
  result |= ADCH<<8;
  result = 1126400L / result; // Back-calculate AVcc in mV
  return result;
}

void setup() 
{
  while (!Serial);
  Serial.begin(9600);
}

void loop() 
{
  Serial.println(readVcc());
  delay(1000);
}

Funkcja “readVcc” zwraca dokładną wartość napięcia zasilania w mili voltach. Właśnie dla takiego napięcia przetwornik będzie zwracał wartość 1023.

Ciekawe, że Arduino Yun zwróciło mi wartość zasilania 4200 mV.

sprae