LinkedIn YouTube Facebook
Szukaj

Wstecz
SoM / SBC

[PROJEKT] KAmodRPI 10b ADC/DAC – ekspander z przetwornikiem ADC dla komputerów Raspberry Pi – Przykład w C++

kamodrpi-adc-dac-modul-przetwornika-ac-i-ca-dla-komputerow-raspberry-pi2-raspberry-pi-i-raspberry-pi-mcp3021-mcp4716

Moduł KAmodRPI 10b ADC/DAC to ekspander rozszerzający możliwości komputera Raspberry PI o przetwarzanie sygnałów cyfrowych na postać analogową oraz dyskretyzację sygnału analogowego. Ekspander został oparty na dwóch niezależnych przetwornikach A/C i C/A. W module zastosowano 10 bitowy przetwornik ADC MCP3021 i 10-bitowy przetwornik DAC MCP4716 firmy Microchip. Moduł jest kompatybilny z komputerami Raspberry Pi 3, Raspberry Pi 2, Raspberry Pi+ i Raspberry Pi. Komunikacja z przetwornikami odbywa się za pośrednictwem magistrali I2C. Przetwornik analogowo-cyfrowy pozwala na konwersję z częstotliwością do 22,3 kHz. Zakres napięcia wejściowego to 0…+3,3V/0…+5V/0…+10V (w zależności od wybranego współczynnika podziału). Przetwornik zawiera wbudowany układ próbkująco-pamiętający (Sample & Hold). W tym przykładzie pokażę jak w prosty sposób można zrealizować pomiar napięcia wejściowego, z poziomu programu w C++, oraz z wykorzystaniem modułu KAmodRPI 10b ADC/DAC.

Program został napisany i skompilowany na komputerze Raspberry PI Model B z poziomu systemu Raspbian Jessie (wersja z: 27.05.2016).

Pierwszą czynnością po uruchomieniu systemu będzie utworzenie katalogu, gdzie będziemy przechowywali nasz program wraz z skompilowaną wersją. W moim przypadku jest to katalog „KAmodRPI_10b_ADC_DAC” w folderze domowym użytkownika.

Kolejnym krokiem jest utworzenie pliku *.cpp, z przykładowym programem, w nowo utworzonym katalogu. Kod programu przedstawiam poniżej.

#include <iostream>
#include <errno.h>
#include <wiringPiI2C.h>
#include <unistd.h>
#include <iomanip>
#include <stdint.h>
#include <stdio.h>

using namespace std;

int main()
{
	int fd;
	
	uint8_t tmp;
	uint16_t measureValueRAW = 0;
	
	double measureValue = 0.0;
	
	fd = wiringPiI2CSetup(0x4D);
	
	cout << "Init result: " << fd << endl;
	
	while(1)
	{
		measureValueRAW = wiringPiI2CReadReg16(fd, 0x4B);
		
		printf("%.4X >> RAW\n", measureValueRAW);
		
		tmp = measureValueRAW;
		
		measureValueRAW = (measureValueRAW >> 8) | (tmp << 8);
		
		measureValueRAW = (measureValueRAW >> 2);
		measureValueRAW &= 0x3FF;
		
		measureValue = (measureValueRAW / 1024.0) * 3.3;
		
		printf("%.2X >> %Lf \n", measureValueRAW, measureValue);
		
		usleep(1000000);
	}
	
	return 0;
}

W powyższym programie korzystamy z biblioteki wiringPiI2C.h. Umożliwia ona w prosty sposób realizować komunikację z układem za pośrednictwem interfejsu I2C.

W programie tworzymy cztery zmienne:

  • fd – zmienna przechowuje status konfiguracji i inicjalizacji połączenia z wykorzystaniem I2C;
  • tmp – zmienna tymczasowa do przechowywania 8 starszych bitów wyniku pomiaru;
  • measureValueRaw – zmienna przechowuje zawartość dwóch rejestrów składających się na całkowity pomiar
  • measureValue – zmienna przechowująca ostateczny obliczony wynik pomiaru

funkcja wiringPiI2CSetup() pozwala na konfigurację i ustanowienie połączenia pomiędzy procesorem a układem ADC z ekspandera. Adres układu zapisany w postaci szesnastkowej to 0x4D.

Główna pętla programu rozpoczyna się od odczytania dwóch rejestrów układu zawierających młodszy i starszy bajt wyniku pomiaru. Odczyt odbywa się po uprzednim wysłaniu do układu informacji o konieczności wykonania pomiaru napięcia na wejściu. W tym celu stosujemy funkcję wiringPiI2CReadReg16().

Kolejna linijka odpowiada za wyświetlenie odczytanej wartości w konsoli.

Do poprawnego przeliczenia surowej wartości konieczne jest zamienienie miejscami dwóch bajtów. Pobranie wartości za pomocą wyżej wymienionej funkcji powoduje to, że 8 starszych bitów to tak naprawdę 8 bitów mniej znaczących całego pomiaru. Zamiany dokonujemy z wykorzystaniem zmiennej pomocniczej tmp, do której przypisujemy starszy bajt zmiennej measureValueRAW. Kolejnym krokiem jest przesunięcie bitowe o 8 miejsc w prawo bitów zmiennej measureValueRAW oraz dopisanie do zmiennej na właściwym miejscu, zawartości zmiennej tmp.

Przetwornik ADC zastosowany w KAmodRPI 10b ADC/DAC ma rozdzielczość 10 bitów. Oznacza to że wynik pomiaru napięcia wejściowego zawarty jest jedynie w 10 bitach, a nie w pełnych 16. Wynik zawarty jest między 2 a 11 bitem zmiennej measureValueRAW. Aby poprawnie odczytać interesującą nas wartość należy zawartość zmiennej przesunąć bitowo o dwa miejsca w prawo, a następnie dokonać operacji koniunkcji bitowej lub bardziej znanej pod nazwą BIT-AND z maską 0x3FF. Pozwoli to na wyłuskanie ostatecznego wyniku.

Ostatnią czynnością jest przeliczenie otrzymanej wartości mierzonej wielkości na wartość napięcia. W tym celu dzielimy wartość zmiennej measureValueRAW na 1024 i wynik dzielenia mnożymy przez wartość napięcia odniesienia. W naszym przypadku jest to 3,3V.

Obliczoną wartość przechowujemy w ostatniej zmiennej measureValue oraz na koniec wyświetlamy ją na ekranie w konsoli.

Program kompilujemy za pomocą kompilatora g++, z poziomu terminala systemu operacyjnego. Kompilację przeprowadzamy wykonując polecenie:

g++ example_kamodrpi_10b_ADC_DAC.cpp -l wiringPi -o example_kamodrpi_10b_ADC_DAC

Polecenie wykonujemy będąc w katalogu, w którym znajduje się plik *.cpp z naszym programem.

Program uruchamiamy z poziomu terminala poleceniem:

sudo ./example_kamodrpi_10b_ADC_DAC

Wynik działania programu prezentuje poniższy zrzut ekranu gdzie widać jak zmieniała się wartość pomiaru wraz z regulacją napięcia na zasilaczu laboratoryjnym.

screed

Fot. 1. Efekt działania programu – wartość napięcia regulowana między 1.00 V, a 2.70 V

Ekspander wyposażony jest w zworki umożliwiające zmianę progu wartości napięcia mierzonego. Realizowane jest to przez użycie przy pomocy zworki jednego z dwóch dzielników napięcia. W celu skorzystania z tej funkcjonalności należy w programie uwzględnić odpowiedni mnożnik dla ostatecznego wyniku pomiaru.

Do pobrania

Autor: Jakub Kuryło