Предисловие
Привет! Буквально недавно меня взяли в кружок по робототехнике. Конечно, я с радостью согласился, это же новый опыт и все такое… Тем более я всего лишь первокурсник. Мой преподаватель, объяснив мне общую концепцию, предложил заняться работой с Raspberry Pi. Нужно было разобраться, как с ним работать, установить на него JDK и написать программу, которая выводила бы на экран показания с 3-х осевого акселерометра. Взяв все необходимое, я отправился домой разбираться. Когда я все закончил (ушло на это примерно неделя), решил написать гайдик, адресованный таким же, как и я, дабы собрать все, что я нарыл, в одном месте. Ну, приятного чтения!
Первым делом
Первым делом нужно получить доступ к нашему устройству. Подключаться будем посредством протокола SSH. По умолчанию сервер SSH отключен, и чтобы включить его, подключаем Raspberry к монитору или телевизору, подсоединяем клавиатуру и мышку. Конечно, можно просто просканировать сетевое окружение, выявить наше устройство и подключиться по найденному IP, но все же рекомендую сделать по моему варианту. После загрузки запускам терминал и вводим команду sudo raspi-config. В открывшемся меню идем в advanced options->SSH и выбираем Enable. После этих манипуляций, должно появиться следующее окошко:
Отлично! Теперь мы сможем приконектиться к нашей “малинке” в любое время. Давайте сразу пропишем настройки сети. Файл, который нам нужен, находится в каталоге /etc/network/.Переходим туда с помощью команды cd /etc/network. Далее открываем нужный файл, введя sudo nano interfaces. Здесь в соответствующих строках прописываем свои данные, тем самым мы задаем статический IP адрес. Должно получиться примерно следующее:
После нажимаем CTRL+X, Y, Enter. Именно по этому адресу будем подключаться. Далее скачиваем клиет SSH — PuTTY. Запустив программу, вы увидите следующее окно:
Здесь в поле Host Name пишем тот самый ip, который мы прописали в interfaces. Здесь же можно сохранить настройки, прописав в поле Save Session имя и нажав на Save. Нажимаем Open. Как только PuTTY подключится к SSH серверу, откроется окно, и появится запрос учетных данных (по умолчанию, пользователь: pi, пароль: raspberry):
Не пугайтесь, что при вводе вы не видите пароль, в Linux подобных системах пароль просто не виден, хотя ввод происходит. Нажимаем Enter. Если все прошло удачно, вы увидите следующее окошко:
В этой консольке можно выполнять любые команды, и они будут выполнены на самом устройстве. Неправда ли удобно?
Установка JDK
Здесь все довольно просто. Обновляем список пакетов, введя в терминале sudo apt-get update.
Обновим и саму систему sudo apt-get upgrade.
На все это может понадобиться довольно много времени (у меня это обновление проходило примерно 30 минут), так что запаситесь чаем. Слава великой силе, что в списки пакетов был добавлен пакет JDK, и нам не пришлось танцевать с бубном. Для установки пакета просто вводим sudo apt-get install openjdk-7-jdk.
Для проверки работоспособности вводим java -version. Вы должны увидеть примерно следующее:
P.S. На некоторых машинах может возникнуть проблема, связанная с тем, что система не находит пакет JDK. Она возникает из-за несовместимости ядра Debian “wheezy” с java. Попробуйте переустановить ОС на Soft-float Debian “wheezy”, оптимизированную для работы с java. В любом случае на моей “малинке” все встало с первого раза. Вот моя версия:
I2c vs Raspberry PI
Итак, теперь начинается самое интересное! Для начала, давайте разберемся, что это вообще такое? Великая и могучая Википедия говорит:
I²C (рус. ай-ту-си/и-два-цэ/и-два-си) — последовательная шина данных для связи интегральных схем, использующая две двунаправленные линии связи (SDA и SCL). Используется для соединения низкоскоростных периферийных компонентов с материнской платой, встраиваемыми системами и мобильными телефонами. Название представляет собой аббревиатуру слов Inter-Integrated Circuit.
В своей работе, я использую вот это устройство LSM303DLM, в дальнейшем все примеры будут показаны именно на нем. Ниже я нарисовал схему подключения:
Она довольно простая, и я думаю, не требует разъяснений. Продолжим. Ах да, давайте сразу добавим пару строк в файл, отвечающий за автозагрузку модулей. Прописываем в командной строке sudo nano /etc/modules и дописываем туда:
i2c-bcm2708
i2c-dev
Теперь устанавливаем пакет i2c-tools. В терминале пишем: sudo apt-get install python-smbus и sudo apt-get install i2c-tools.
Редактируем черный список. Для этого пишем sudo nano /etc/modprobe.d/raspi-blacklist.conf. Добавляем строки:
blacklist spi-bcm2708
blacklist i2c-bcm2708
Все. Все самое необходимое для работы с I2C мы сделали, теперь давайте проверим, видим ли мы наше устройство. В утилиту i2c-tools входит команда i2cdetect, она нам и нужна. Но сперва проверим, что драйвера успешно установлены. Пишем в терминале i2cdetect –l. Если видим следующее:
То все нормально, можно двигаться дальше. Теперь пишем i2cdetect –y 1 (i2cdetect –y 0). Видим решетку адресов:
В моем случае, адрес акселерометра 0x18(можно узнать, например, в документации). Теперь поговорим о PI4J.
Уоу уоу уоу палехче…
Для работы с I2C средствами JAVA, нужно скачать и установить дополнительную библиотеку PI4J. Прочитать про нее можно здесь. Скачиваем, написав в терминале wget pi4j.googlecode.com/files/pi4j-0.0.5.deb. Устанавливаем, прописав: sudo dpkg -i pi4j-0.0.5.deb. Проверим установленные файлы:
Теперь для компиляции программы пишем:
javac -classpath .:classes:/opt/pi4j/lib/'*' (название)
Для запуска:
sudo java -classpath .:classes:/opt/pi4j/lib/'*' (название)
Из всех пакетов нам пригодится 3:
import com.pi4j.io.i2c.I2CBus;
import com.pi4j.io.i2c.I2CDevice;
import com.pi4j.io.i2c.I2CFactory;
Создаем ссылки на объекты классов I2CDevice и I2CBus.
import java.io.IOException;
import com.pi4j.io.i2c.I2CBus;
import com.pi4j.io.i2c.I2CDevice;
import com.pi4j.io.i2c.I2CFactory;
public class accelerometrOne {
static I2CDevice device;
static I2CBus bus;
static byte[] accel;
public static void main(String[] args) throws IOException {
System.out.println("Starting sensors reading:");
try {
bus = I2CFactory.getInstance(I2CBus.BUS_1);
System.out.println("Connected to bus OK!");
device = bus.getDevice(0x18);
System.out.println("Connected to device OK!");
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
Разберем код. Строчкой bus = I2CFactory.getInstance(I2CBus.BUS_1); мы подключаемся к нашей шине, а с помощью device = bus.getDevice(0x18); мы подключаемся к нашему устройству.
Теперь нужно произвести калибровку акселерометра. Лезем в документацию.
У кого совсем все плохо с английским. В моем вольном переводе: “После включения LSM303DLH необходимо произвести конфигурацию устройства по 2 регистрам CTRL_REG1_A(20h) и CTRL_REG2_A (23h). Для этого в первый регистр пишем 0x27 для нормальной работы с ODR 50гц.
Пишем 0*40 во второй регистр для того, чтобы сохранить полный диапазон измерений +- 2 гаусс в непрерывном обновлении базы данных и изменить порядок байтов от младшего к старшему на порядок, от старшего к младшему.”
Для записи данных в устройство воспользуемся методом write из класса I2CDevice. Допишем программу:
import java.io.IOException;
import com.pi4j.io.i2c.I2CBus;
import com.pi4j.io.i2c.I2CDevice;
import com.pi4j.io.i2c.I2CFactory;
public class accelerometrOne {
static I2CDevice device;
static I2CBus bus;
static byte[] accel;
public static void main(String[] args) throws IOException {
System.out.println("Starting sensors reading:");
try {
bus = I2CFactory.getInstance(I2CBus.BUS_1);
System.out.println("Connected to bus OK!");
device = bus.getDevice(0x18);
System.out.println("Connected to device OK!");
device.write(0x20, (byte) 0x27);
device.write(0x23, (byte) 0x40);
System.out.println("Configuring sensors OK!");
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
Отлично!!! Осталось считать данные с устройства. Снова лезем в документацию и узнаем, что данные выдаются по 2 байта на каждую ось:
Ну и все. Записываем полученные байты в массив и выводим данные на экран:
import java.io.IOException;
import com.pi4j.io.i2c.I2CBus;
import com.pi4j.io.i2c.I2CDevice;
import com.pi4j.io.i2c.I2CFactory;
public class accelerometrOne {
static I2CDevice device;
static I2CBus bus;
static byte[] accel;
public static void main(String[] args) throws IOException {
System.out.println("Starting sensors reading:");
try {
bus = I2CFactory.getInstance(I2CBus.BUS_1);
System.out.println("Connected to bus OK!");
device = bus.getDevice(0x18);
System.out.println("Connected to device OK!");
device.write(0x20, (byte) 0x27);
device.write(0x23, (byte) 0x40);
System.out.println("Configuring sensors OK!");
readingsensors();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
private static void readingsensors() throws IOException {
while (true) {
accel = new byte[6];
accel[0] = (byte) device.read(0x28);
accel[1] = (byte) device.read(0x29);
accel[2] = (byte) device.read(0x2a);
accel[3] = (byte) device.read(0x2b);
accel[4] = (byte) device.read(0x2c);
accel[5] = (byte) device.read(0x2d);
int accelx = asint(accel[0]) * 256 + asint(accel[1]);
int accely = asint(accel[2]) * 256 + asint(accel[3]);
int accelz = asint(accel[4]) * 256 + asint(accel[5]);
System.out.println("accelx: " + accelx + ", accely: " + accely
+ ", accelz: " + accelz);
}
}
private static int asint(byte b) {
int i = b;
if (i < 0) {
i = i + 256;
}
return i;
}
}
В итоге, после запуска мы увидим примерно следующее:
Автор: AlexStrat