Arduino:Примеры/DataLogging

Материал из Онлайн справочника
Версия от 12:33, 8 июля 2023; EducationBot (обсуждение | вклад)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)
Перейти к навигацииПерейти к поиску

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


Запись логов[1]

Этот пример является расширенной версией примера «Получение и отправка команд с аргументами» и демонстрирует, как вести учет данных и отображать их на графике.

Код

// *** Запись логов ***

// Это расширенная версия примера «Получение и отправка команд 
// с аргументами». Теперь перед отправкой на PC аналоговых данных  
// и нескольких float-значений (а экспоненциальной форме) Arduino 
// ждет команду StartLogging.

#include <CmdMessenger.h>  // CmdMessenger

// привязываем экземпляр класса CmdMessenger к последовательному порту:
CmdMessenger cmdMessenger = CmdMessenger(Serial);

// контакты термопары:
const int AnalogPin1               = 0;
const int AnalogPin2               = 1;
bool acquireData                   = false;
const unsigned long sampleInterval = 100; // интервал 0,1 секунды; частота 10 Гц
unsigned long previousSampleMillis = 0;
long startAcqMillis                = 0;

// Это список распознаваемых команд, и эти команды могут быть 
// либо получены, либо отправлены. Чтобы получить команду, к этому 
// событию нужно привязать функцию внешнего вызова.
enum
{
  // Команды:
  kAcknowledge         , // команда, подтверждающая получение команды
  kError               , // команда, сообщающая об ошибках
  kStartLogging        , // команда, запрашивающая начать запись логов (как правило, с PC на Arduino)
  kPlotDataPoint       , // команда, запрашивающая отображение на графике точек данных (как правило, с Arduino на PC)
};

// команды, отсылаемые от PC и получаемые на Arduino; в скетче Arduino 
// нужно задать функцию внешнего вызова для каждой записи из списка ниже:
void attachCommandCallbacks()
{
  // подключаем функции внешнего вызова:
  cmdMessenger.attach(OnUnknownCommand);
  cmdMessenger.attach(kStartLogging, OnStartLogging);
}

// ------------------  ФУНКЦИИ ВНЕШНЕГО ВЫЗОВА -----------------------

// эта функция вызывается, когда к присланной команде не привязано никакой функции:
void OnUnknownCommand()
{
  cmdMessenger.sendCmd(kError,"Command without attached callback");  //  "Команда без функции внешнего вызова"
}

// функция внешнего вызова, сообщающая о готовности Arduino (т.е. о ее загрузке):
void OnArduinoReady()
{
  cmdMessenger.sendCmd(kAcknowledge,"Arduino ready");  //  "Arduino готова"
}

// функция внешнего вызова, рассчитывающая сумму двух присланных float-значений:
void OnStartLogging()
{
  // начинаем сбор информации:
  startAcqMillis = millis();
  acquireData    = true;
  cmdMessenger.sendCmd(kAcknowledge,"Start Logging");  //  "Начинаем запись логов"
}

// ------------------ ГЛАВНАЯ ЧАСТЬ СКЕТЧА ----------------------

// блок исходных операций:
void setup() 
{
  // прослушиваем последовательное соединение на предмет сообщений от PC: 
  Serial.begin(115200); 

  // добавляем каждой команде символ новой строки:
  cmdMessenger.printLfCr();   

  // подключаем функции внешнего вызова, заданные пользователем:
  attachCommandCallbacks();

  // отсылаем на PC сообщение, что Arduino загрузилась:
  cmdMessenger.sendCmd(kAcknowledge,"Arduino has started!");  //  "Arduino запущена!"
}

// возвращаем «true», если время превысило заданный интервал 
// (в миллисекундах); используется для периодических действий:
bool hasExpired(unsigned long &prevTime, unsigned long interval) {
  if (  millis() - prevTime > interval ) {
    prevTime = millis();
    return true;
  } else     
    return false;
}

// блок повторяющихся операций:
void loop() 
{
  // обрабатываем данные, пришедшие по последовательному соединению,
  // и выполняем функции внешнего вызова:
  cmdMessenger.feedinSerialData();
 
  // периодически делаем замеры:
  if (hasExpired(previousSampleMillis,sampleInterval)) 
  { 
    if (acquireData) {
      measure();
    }
  }
}

// простое считывание данных с аналоговых контактов: 
void measure() {
   
   float seconds = (float) (millis()-startAcqMillis) /1000.0 ;
   float Analog1 = analogRead(AnalogPin1);
   float Analog2 = analogRead(AnalogPin2);   
   
   cmdMessenger.sendCmdStart(kPlotDataPoint); 
   cmdMessenger.sendCmdArg(seconds,4);   
   cmdMessenger.sendCmdSciArg(Analog1);  
   cmdMessenger.sendCmdSciArg(Analog2);    
   cmdMessenger.sendCmdEnd();
}

См.также

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