|
Hardware: Ввод-вывод и сенсоры
|
Hardware: Ввод-вывод и сенсоры
В этом разделе описываются классы, предназначенные для ввода вывода и использования стандартных сенсоров NXT.
В NXT есть кнопки для ввода информации, жидко-кристаллический индикатор (ЖКИ, LCD)
и маленький динамик для вывода звука. В leJOS NXJ
есть необходимые компоненты для работы со всеми этими аппаратными блоками.
ЖКИ(LCD)
Класс LCD не имеет экземпляров(есть всего лишь один ЖКИ в нашем устройстве NXT), поэтому все методы - статические.
ЖКИ может использоваться в текстовом или графическом режимах.
Методы класса LCD предназначенные для работы с текстом
В качестве текстового дисплея ЖК-индикатор NXT может отображать 16 символов в ширину и 8 символов в высоту. Позиция задаётся через указание координат (x, y) следующим образом:
x может изменяться от 0 до 15, и y от 0 до 7.
Методы для записи в ЖКИ в текстовом режиме следующие:-
void drawString(String str, int x, int y) Этот метод выводит строку текста на ЖКИ начиная с позиции (x, y).
void drawInt(int i, int x, int y)
Этот метод печатает целое число начиная с позиции (x,y). Число будет выровнено по левому краю и будет занимать столько символов, сколько необходимо для его вывода (т.е. никаких нулей или пробелов спереди числа не будет).
void drawInt(int i, int places, int x, int y)
Этот вариант метода drawInt выравнивает число по правому краю перед тем, как вывести и при этом число занимает заданное количество знакомест.
Это означает, что этот метод всегда печатает фиксированное число символов (вне зависимости от реальной длины числа), поэтому, если, например, в цикле этот метод вызывается несколько раз, то каждый раз он полностью стирает предыдущий вывод и печатает число заново.
void clear() Очищает ЖКИ.
Пример:
import lejos.nxt.LCD;
public class LCDTest {
public static void main(String[] args) throws Exception {
LCD.drawString("Free RAM:", 0, 0);
LCD.drawInt((int) System.getRuntime().freeMemory(), 6, 9, 0);
Thread.sleep(2000);
}
}
Обратите внимание: можно также печатать текст на ЖКИ с помощью метода System.out.println(String str). Он прокручивает выведенный на дисплее текст на одну строчку вверх и печатает в самой нижней строке экрана.
Также имейте в виду, что по умолчанию ЖКИ обновляется автоматически. Если вы хотите вручную контролировать момент, когда произойдёт обновление информации на ЖКИ, вы можете настроить такое поведение вызовом LCD.setAutoRefresh(0) и затем сами вызывать каждый раз метод LCD.refresh() когда вам нужно обновить содержимое дисплея.
Наверх страницы
Методы класса LCD для вывода графики
В качестве графического дисплея ЖКИ NXT имеет 100 пикселей (точек) в ширину и 64 пикселя в высоту.
Он адресуется через указание координат (x, y) пикселя аналогично текстовым методам:
x меняется от 0 до 99, y - от 0 до 63.
Чтоб отобразить графику на ЖКИ, вы можете использовать класс Graphics из пакета javax.microedition.lcdui.
Смотрите API класса Graphics (на английском).
С помощью этого класса вы можете рисовать линии, прямоугольники, дуги и выводить строчки с возможностью указывать место вывода с точностью до пикселя.
Пример:
import javax.microedition.lcdui.Graphics;
public class GraphicsSample {
public static void main(String [] options) throws Exception {
Graphics g = new Graphics();
g.drawLine(5,5,60,60);
g.drawRect(62, 10, 25, 35);
Thread.sleep(2000);
}
}
Наверх страницы
Кнопки
У класса Button есть четыре эксемпляра (объекта), к которым можно получить доступ через статические поля:
- Button.ENTER
- Button.ESCAPE
- Button.LEFT
- Button.RIGHT
Чтоб проверить, нажата ли кнопка, используйте метод:
Пример:
import lejos.nxt.Button;
import lejos.nxt.LCD;
public class ButtonPresses {
public static void main(String[] args) throws Exception {
while (true) {
LCD.clear();
if (Button.ENTER.isDown()) LCD.drawString("ENTER", 0, 0);
if (Button.ESCAPE.isDown()) LCD.drawString("ESCAPE", 0, 0);
if (Button.LEFT.isDown()) LCD.drawString("LEFT", 0, 0);
if (Button.RIGHT.isDown()) LCD.drawString("RIGHT", 0, 0);
}
}
}
Чтоб дождаться, когда какая-либо конкретная кнопка будет нажата или отпущена, используйте метод:
Пример:
import lejos.nxt.Button;
import lejos.nxt.LCD;
public class ButtonTest
{
public static void main (String[] args)
throws Exception
{
Button.ENTER.waitForPressAndRelease();
LCD.drawString("Finished", 3, 4);
Thread.sleep(2000);
}
}
Чтобы дождаться нажатия любой кнопки, используйте:
button
ENTER LEFT
RIGHT ESCAPE
Code
1
2
4 8
Чтоб указать слушателя для обработки событий какой-либо конкретной кнопки используйте метод:
void addButtonListener (ButtonListener aListener) Смотрите раздел “Слушатели и события” если вам не понятно, как использовать механизм событий.
Чтоб прочитать текущее состояние всех кнопок, используйте метод:
Наверх страницы
Класс Sound (Звук)
Этот класс управляет единственным динамиком, поэтому у него нет экземпляров (объектов) и все его методы статические.
Чтоб проиграть единичный тон, используйте
Пример:
import lejos.nxt.Sound;
public class PlayTones {
private static final short[] note = {2349,115, 0,5, 1760,165, 0,35};
public static void main(String [] args) throws Exception {
for(int i=0;i <note.length; i+=2) {
short w = note[i+1];
int n = note[i];
if (n != 0) {
Sound.playTone(n, w*10);
}
Thread.sleep(w*10);
}
}
}
Есть два способа проиграть системный звук, первый:
void systemSound (boolean aQueued, int aCode)
Параметр aQueued игнорируется в NXT, он нужен только для обратной совместимости с RXC.
Смыслы кодов такие:
code = 0 Короткий гудок
code = 1 Двойной гудок
code = 2 Descending arpeggio (убывающий арпеджио (наверно это музыкальный термин такой))
code = 3 Ascending arpeggio (возрастающий арпеджио)
code = 4 Длинный, низкий тон
Отдельные методы для проигрывания конкретных системных звуков (если вы не помните кодов):
Так же есть метод для того, чтоб воспроизвести отсутствие звука (период задаётся в милисекундах):
В leJOS NXJ также есть методы, которые могут проигрывать 8-битные WAV-файлы:
Возвращаемое значение - это время проигрывания файла в милисекундах или значение< 0 в случае ошибки.
Чтоб проиграть музыкальную ноту, используйте метод:
void playNote(int[] inst,int freq, int len)
Массив inst содержит значения параметров ноты: нарастания(attack),
спада(decay), затягивания(sustain) и отпускания(release) - эти параметры характеризуют разные музыкальные инструменты. Статические константы для некоторых предопределённых инструментов называются: FLUTE,
PIANO и XYLOPHONE. Вы можете экспериментировать с определением своих собственных значений.
Наверх страницы
класс Battery
Есть два статических метода для того, чтоб узнать напряжение на батарее:
Пример:
import lejos.nxt.Battery;
import lejos.nxt.LCD;
public class BatteryTest {
public static void main(String[] args) throws Exception {
LCD.drawString("Battery: " + Battery.getVoltage(), 0, 0);
Thread.sleep(2000);
}
}
Наверх страницы
Сенсоры
В комплекте конструктора Lego Mindstorms вместе с "кирпичом" NXT идут четыре типа сенсоров: сенсоры касания, сенсор звука, сенсор света и ультразвуковой сенсор. В leJOS NXJ есть классы, позволяющие эффективно использовать все эти типы сенсоров и многие другие, поставляемыми отдельно от конструктора. Дальше по тексту сами устройства будут называться датчиками, а абстракции, связанные с ними (классы) - сенсорами
Датчик должен быть подключен к порту и объект sensor должен знать, к какому порту подключен его датчик. Чтоб указать порт, передайте информацию о номере порта в конструктор сенсора при его создании. Возможные варианты: SensorPort.S1, S2, S3 или
S4.
Датчик касания
Чтоб использовать сенсор касания, создайте его экземпляр, используя конструктор:
Чтоб узнать, находится ли сенсор в состоянии срабатывания, используйте метод isPressed():
Пример:
import lejos.nxt.LCD;
import lejos.nxt.SensorPort;
import lejos.nxt.TouchSensor;
public class TouchTest {
public static void main(String[] args) throws Exception {
TouchSensor touch = new TouchSensor(SensorPort.S1);
while (!touch.isPressed()) {
// try again
}
LCD.drawString("Finished", 3, 4);
}
}
Наверх страницы
Сенсор освещённости
Чтоб использовать сенсор света, создайте его экземпляр, используя конструктор:
Пример:
import lejos.nxt.LCD;
import lejos.nxt.LightSensor;
import lejos.nxt.SensorPort;
public class LightTest {
public static void main(String[] args) throws Exception {
LightSensor light = new LightSensor(SensorPort.S1);
while (true) {
LCD.drawInt(light.getLightValue(), 4, 0, 0);
LCD.drawInt(light.getNormalizedLightValue(), 4, 0, 1);
LCD.drawInt(SensorPort.S1.readRawValue(), 4, 0, 2);
LCD.drawInt(SensorPort.S1.readValue(), 4, 0, 3);
}
}
}
Наверх страницы
Датчик звука
Звуковой сенсор поддерживает два режима: DB и DBA. Эти режимы
имеют разную АЧХ (амплитудно-частотную характеристику), поэтому, если вы хотите сделать какое-нибудь предположение о частоте слышимого звука, может иметь смысл задействовать оба режима (переключаясь между ними).
У этого класса есть два конструктора:
SoundSensor(SensorPort port) создаёт звуковой сенсор, работающий в режиме DB.
SoundSensor(SensorPort port, dba) создаёт звуковой сенсор, работающий в режиме DBA если второй параметр равен true.
Можно переключаться между режимами:
Пример использования только режима DB:
Этот пример графически показывает, как меняется звук в течение двухсекундного периода.
import lejos.nxt.*;
public class SoundScope {
public static void main(String[] args) throws Exception {
SoundSensor sound = new SoundSensor(SensorPort.S1);
while (!Button.ESCAPE.isDown()) {
LCD.clear();
for (int i = 0; i < 100; i++) {
LCD.setPixel(1, i, 60 - (sound.readValue() / 2));
Thread.sleep(20);
}
}
}
}
Наверх страницы
Датчик ультразвука
Чтоб создать экземпляр, используйте этот конструктор:
Сенсор может работать в двух режимах: непрерывном (обычно работает в этом режиме) и в режиме пинга. В непрерывном режиме сенсор посылает пинги (зондирующие сигналы) так часто, как это возможно, и самый последний результат измерения можно прочитать используя метод:
Пример:
import lejos.nxt.*;
public class SonicTest {
public static void main(String[] args) throws Exception {
UltrasonicSensor sonic = new UltrasonicSensor(SensorPort.S1);
while (!Button.ESCAPE.isDown()) {
LCD.clear();
LCD.drawString(sonic.getVendorID(), 0, 0);
LCD.drawString(sonic.getProductID(), 0, 1);
LCD.drawString(sonic.getVersion(), 0, 2);
LCD.drawInt(sonic.getDistance(), 0, 3);
}
}
}
В режиме "пинга" зондирующий сигнал посылается только при вызове метода:
void ping() Этот метод переводит сенсор в режим "пинга" (посылки зондирующего импульса), посылает единичный импульс и затем пытается поймать до 8 эхо-сигналов. Это может быть сделано путём вызова
int readDistances(int [] distances)
Вы передаёте массив целых чисел, в котором после возврата из метода будут результаты измерения.
Необходима задержка около 20 милисекунд между вызовоми ping и getDistances. Эта задержка не включена ни в один из указанных методов.
Вызов метода getDistances до того, как истечёт 20 мс может привести к ошибке либо данные не будут возвращены. Метод getDistance также может быть использован вместе с методом ping без использования данных массива, метод getDistance возвращает в качестве результата функции информацию о первом отражении.
Вызов метода ping() отключает непрерывный режим зондирования, в котором система находится по умолчанию. Чтоб переключиться обратно в режим непрерывного зондирования, вызовите метод
int continuous()
Программа: множественные отражения
Напишите программу, которая показывает расстояния от нескольких отражений в колонку.
Программа должна сделать четыре вызова ping(), и показать четыре колонки с результатами, затем дождаться нажатия кнопки и выйти, если была нажата кнопка ESCAPE.
Решение
Наверх страницы
|