?

Log in

No account? Create an account
Разбираю гуманитарные вопросы на винтики, функции, алгоритмы. Оживляю технологии
Совмещаю гуманитарный и технический пласты знаний в единое мировоззрение
Raspberry Pi: читаем аналоговые датчики с помощью MCP3008 (АЦП) 
30th-Oct-2016 04:10 am
Понадобилось железкой по имени Raspberry Pi считывать данные нескольких аналоговых датчиков. Для этого была в наличии микросхемка АЦП MICROCHIP mcp3008 (думаю, подключение mcp3004 выполняется похожим образом).
Поскольку первая найденная мной информация по работе с аналоговыми датчиками не позволяла разобраться "на коленке за 5 минут", а потребовала для неосведомленного человека нескольких часов жизни, делюсь изысканиями.

Первым делом о подключении. Подключается АЦП к SPI интерфейсу.
Схем подключения нашел несколько, заработала одна.

Схема расположения выводов на mcp3008:
Распиновка mcp3008

И подключение к SPI:
Подключение mcp3008 к SPI Raspberry

Обратите внимание на расположение АЦП (ориентация надписи). Бывают схемы с перепутанными сторонами. Приведена правильная схема.

Датчики, соответственно цепляются выводом данных на один из 8 входов (ch0 .. ch7) АЦП.

Перед использованием MCP3008, необходимо инициализировать SPI интерфейс.

Для считывания использовал perl5 и набор библиотек HiPi.
Код библиотечки-обвязки для чтения данных с ножек (висит на SPI dev 0):
package MCP;
use strict;

use HiPi::Device::SPI qw( :all );
use HiPi::Interface::MCP3008 qw( :mcp );

our @pins = (
	MCP3008_S0,
	MCP3008_S1,
	MCP3008_S2,
	MCP3008_S3,
	MCP3008_S4,
	MCP3008_S5,
	MCP3008_S6,
	MCP3008_S7
);

sub new
{
	my $class = shift;
	my %arg = @_;

	my $self = bless {
			mcp => HiPi::Interface::MCP3008->new(
				devicename   => '/dev/spidev0.0',
				speed        => SPI_SPEED_KHZ_500,
				bitsperword  => 8
			)
		}, $class;

	return $self;
} # sub new

sub get
{
	my $self = shift;
	my $pin = shift || 0;

	return $self->{mcp}->read( $pins[$pin] );
} # sub get

1;


И вызов из скрипта обхода датчиков, соответственно (для примера, читаю ножки ch0 и ch3):
#!/usr/bin/perl
use strict;
use warnings;

use MCP;

my $mcp = MCP->new();
my $sensor_0 = $mcp->get( 0 );
my $sensor_3 = $mcp->get( 3 );


Значения получил инверсированные, т.е. если датчик показывает по максимуму - значение близко к 0, если датчик показывает по минимуму, значение 1023.
Такое наблюдал на 2-х совершенно разнотипных датчиках. С фоторезистором все понятно, он и должен наращивать сопротивление под действием света, т.е. снижать напряжение на выходе. Со вторым все не так очевидно.

Удачи в автоматизации.

Добавлено: в начале сего (2017) года решил обновить систему и библиотеки. SPI интерфейс отвалился. На образ откатываться не хотел, решил повозиться.
При попытке воспользоваться альтернативным методом считывания со SPI на стадии подготовки получил ошибку установки пакета библиотек WiringPi::API
Нечто вроде
Can't load .../auto/WiringPi/API/API.so for module WiringPi::API: .../auto/WiringPi/API/API.so: undefined symbol: bmp180Setup

Оказалось, что автор C-библиотеки WiringPi, которую и используют перловые библиотеки, в новой версии менял названия методов. Разработчики надстроек на других языках получили кучу жалоб на неработоспособность и тоже обновились под изменения Gordon-a. А C-библиотеки в репозитории raspbian не обновлялись. По факту вышли новые библиотеки-обвязки + старая версия C-ной WiringPi.
Лечится ручной установкой свежей версии WiringPi с последующим перезапуском rPi.

This page was loaded Nov 20th 2017, 5:52 am GMT.