Arduino:Примеры/EsploraTable

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Вывод данных от акселерометра Esplora на электронную таблицу[1]

Этот пример упрощает сбор данных от акселерометра Esplora. То есть этот скетч делает так, что Esplora собирает данные от своего акселерометра, а затем периодически передает их на компьютер, где печатает в электронной таблице.

Среди элементов Esplora, задействованных в этом примере, помимо акселерометра значатся кнопка «Вниз», RGB-светодиод и линейный потенциометр. Первая отвечает за начало/завершение процесса регистрации данных, второй – за информирование о том или ином состоянии этого процесса, а третий – для того, чтобы пользователь мог задать интервал в считывании данных от акселерометра.

Необходимое оборудование

  • Плата Arduino Esplora;

Цепь

Для этого примера нужна лишь Arduino Esplora.

Расположение на Esplora акселерометра, слайдера, RGB-светодиода и кнопки «Вниз», а также то, какие роли они выполняют в этом скетче

Код

В этом скетче Esplora будет выступать в качестве клавиатуры. То есть, нажимая на кнопку «Вниз», вы будете отсылать данные на компьютер, к которому подключена Esplora.

Символы, отсылаемые на компьютер, будут отформатированы, чтобы подходить к столбцам и строкам электронной таблицы. Каждая строка будет содержать информацию о времени, а также данные от трех осей акселерометра.

Чтобы начать процесс, нажмите кнопку «Вниз». С этого момента Esplora начнет выступать для компьютера в роли клавиатуры. Изменение позиции линейного потенциометра изменяет интервал между считываниями данных с акселерометра.

Если RGB-светодиод загорится синим, это значит, что Esplora готова, но данные не отправляет. Нажмите на кнопку «Вниз», и RGB-светодиод замигает зеленым. Во время передачи данных с Esplora на электронную таблицу RGB-светодиод будет гореть красным.

Если снова нажать на кнопку, то Esplora перестанет отправлять данные.

/*
Вывод данных от акселерометра Esplora на электронную таблицу

Делает так, что компьютер начинает видеть Esplora как клавиатуру,
которая печатает данные от датчика в таблицу, ряд за рядом. 

После запуска скетч не делает ничего. 
Он ждет, пока вы откроете электронную таблицу (например, в Google Drive),
чтобы он мог вписать туда свои данные.
Затем вам нужно нажать на Esplora кнопку «Вниз», после чего он начнет печатать заголовки для таблицы, а также первую строку с данными. 
Далее он ждет немного, печатает еще одну строку и т.д.

Временной интервал между печатанием строк определяется слайдером линейного потенциометра.
Если сдвинуть его до конца влево, то скетч будет ждать 10 секунд;
если до конца вправо, то 5 минут. 
То есть, если поставить слайдер где-то посередине, то скетч будет ждать где-то около 2,5 минут. 

Если снова нажать на кнопку «Вниз», это остановит печать данных на электронную таблицу.

Цвет RGB-светодиода сообщает, чем скетч занимается в данный момент:
синий – простой; скетч ждет, когда вы нажмете на кнопку, чтобы начать регистрацию данных,
зеленый – активация; печать скоро начнется,
красный – печать данных на PC.

Создан 22 ноября 2012 Энрико Гуэли (Enrico Gueli, enrico.gueli@gmail.com),
модифицирован 24 ноября 2012 Томом Иго (Tom Igoe).
*/

#include <Esplora.h>

/*
Эта переменная будет говорить о том, идет ли в данный момент регистрация данных или нет.
*/

boolean active = false;

/*
Эта переменная хранит информацию о времени в будущем,
когда скетчу нужно будет сосчитать данные с акселерометра в очередной раз.
Скетч постоянно сверяет ее значение со значением от функции millis().
*/

unsigned long nextSampleAt = 0;

/*
В этой переменной будет храниться значение от функции millis(),
возвращаемое при активации очередного этапа регистрации данных.
Она нужна, чтобы ввести правильное значение в столбце «Time» ("Время") электронной таблицы.
*/

unsigned long startedAt = 0;

/*
Когда переменной active присваивается значение true, 
то же значение получает и эта переменная.
Это нужно затем, чтобы код, выполняющий задачи сразу после активации,
начал работать чуть позже, чем код, который говорит «запускаем активацию».
*/

boolean justActivated = false;

/*
В этой переменной хранится информация о последнем состоянии кнопки «Вниз».
Если код видит, что предыдущее и текущее состояние кнопки
друг от друга отличаются, это значит, 
что на кнопку либо нажали, либо отпустили ее. 
*/

boolean lastStartBtn = HIGH;

/*
Код инициализации. 
Виртуальная USB-клавиатура должна быть инициализирована.
Инициализация класса Serial требуется в отладочных целях.
*/

void setup() {
  Keyboard.begin();
  Serial.begin(9600);
}

/*
Этот код будет работать непрерывно.
*/

void loop() {
  
  /*
  Примечание: в данном случае не используется стандартная
  «ардуиновская» функция delay(),
  поскольку во время такой паузы сделать особо ничего нельзя.
  Наша собственная версия этой функции, наоборот,
  позволяет проверять, нажималась ли кнопка «Вниз» или нет. 
  */

  activeDelay(50);

  /*
  Функция checkSwitchPress() может придать переменной justActivated значение true.
  И здесь мы проверяем состояние этой переменной, 
чтобы запустить печать табличных заголовков и сделать начальную преднастройку.
  */

  if (justActivated == true) {
    justActivated = false; // делаем это всего раз
    printHeaders();
    // Делаем так, чтобы следующее считывание запустилось как можно быстрее:
    nextSampleAt = startedAt = millis();
  }

  if (active == true) {
    if (nextSampleAt < millis()) {
      // Приступаем к определению позиции слайдера линейного потенциометра:
      int slider = Esplora.readSlider();
      // Эта строчка кода подгоняет диапазон линейного потенциометра
      // к временному диапазону между 10 и 290 секундами:
      int sampleInterval = map(slider, 0, 1023, 10, 290);
      nextSampleAt = millis() + sampleInterval * 1000;

      logAndPrint();
    }

    // Делаем так, чтобы RGB-светодиод мигал зеленым цветом
    // с периодичностью 200 миллисекунд в секунду:
    unsigned int ms = millis() % 1000;
    if (ms < 200)
      Esplora.writeGreen(50);
    else
      Esplora.writeGreen(0);

    Esplora.writeBlue(0);
  }
  else
    // Во время простоя делаем так, чтобы RGB-светодиод горел синим цветом:  
    Esplora.writeBlue(20);

}

/*
Печатаем заголовки.
*/

void printHeaders() {
  Keyboard.print("Time");  //  "Время"
  Keyboard.write(KEY_TAB);
  activeDelay(300); // некоторые электронные таблицы довольно медлительны (например, от Google)
  // Печатаем заголовки для осей акселерометра:
  Keyboard.print("Accel X");  //  "Ось X"
  Keyboard.write(KEY_TAB);
  activeDelay(300);
  Keyboard.print("Accel Y");  //  "Ось Y"
  Keyboard.write(KEY_TAB);
  activeDelay(300);
  Keyboard.print("Accel Z");  //  "Ось Z"
  Keyboard.println();
  activeDelay(300);
}

void logAndPrint() {
  // Считываем данные со всех осей за один раз,
  // потому что между «нажатиями» на клавиши стоят паузы:
  unsigned long timeSecs = (millis() - startedAt) / 1000;
  int xAxis = Esplora.readAccelerometer(X_AXIS);
  int yAxis = Esplora.readAccelerometer(Y_AXIS);
  int zAxis = Esplora.readAccelerometer(Z_AXIS);

  Esplora.writeRed(100);

  Keyboard.print(timeSecs);
  Keyboard.write(KEY_TAB);
  activeDelay(300);
  Keyboard.print(xAxis);
  Keyboard.write(KEY_TAB);
  activeDelay(300);
  Keyboard.print(yAxis);
  Keyboard.write(KEY_TAB);
  activeDelay(300);
  Keyboard.print(zAxis);
  Keyboard.println();
  activeDelay(300);
  Keyboard.write(KEY_HOME);

  Esplora.writeRed(0);
}

/*
Эта функция аналогична delay(), но, в отличие от «близнеца», 
не останавливает программу, а позволяет ей что-то делать.
В частности, она вызывает функцию checkSwitchPress().
Примечание 1: пауза может длиться дольше указанного времени, но не меньше.
Примечание 2: могут быть проблемы с синхронизацией данных. 
Например, вызов функции activeDelay() может поменять значение некоторых переменных. 
*/

void activeDelay(unsigned long amount) {
  unsigned long at = millis() + amount;
  while (millis() < at) {
    checkSwitchPress();
  }
}

/*
Эта функция считывает состояние кнопки. Если она видит, что кнопка нажата, то меняет значение переменной active.
Если active получает значение true, то это же самое значение
присваивается и переменной justActivated, чтобы функция loop() все сделала как надо.
Необходимо, чтобы эта функция вызывалась как можно чаще и делала как можно меньше,
поскольку она может быть вызвана во время работы другой функции.
*/

void checkSwitchPress() {
  boolean startBtn = Esplora.readButton(SWITCH_DOWN);

  if (startBtn != lastStartBtn) {
    if (startBtn == HIGH) { // кнопка отпущена
      active = !active;
      if (active)
        justActivated = true;
    }

    lastStartBtn = startBtn;
  }
}

См.также

  1. Mouse and Keyboard
  2. Esplora.readSlider()
  3. Esplora.readButton()
  4. Esplora.readAccelerometer()
  5. Esplora.writeRed()
  6. Esplora.writeGreen()
  7. Esplora.writeBlue()

Внешние ссылки