Arduino:Примеры/ConsoleShell

Материал из Онлайн справочника
Версия от 05:44, 14 декабря 2016; Myagkij (обсуждение | вклад) (Замена текста — «<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">» на «<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">»)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)
Перейти к навигацииПерейти к поиску

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


Использование CmdMessenger в качестве оболочки[1]

Этот пример показывает, как использовать CmdMessenger в качестве оболочки, а также то, как «общаться» с этой оболочкой через монитор порта в IDE Arduino.

Код

// *** Использование CmdMessenger в качестве оболочки ***

// Этот пример показывает, как использовать CmdMessenger в качестве
// оболочки и коммуницировать с нею при помощи консоли в мониторе 
// порта.

// Этот пример отличается от других:
// - у него нет «программы-напарника» на PC: 
// - он только получает команды; вместо отправки команд он использует Serial.print
//
// Ниже демонстрируется, как взаимодействовать с этим скетчем:
// 
//   Доступные команды:
//   0;                  - Показать список команд
//   1,<состояние>;      - Задать статус светодиода. 0 = выкл, 1 = вкл
//   2,<яркость>;        - Задать яркость светодиода. 0 - 1000
//   3;                  - Показать состояние светодиода
//  
//  Если ввести команду «3», то результат будет:
//  
//  Led status (т.е. состояние светодиода): on (т.е. «вкл»)
//  Led brightness (т.е. яркость светодиода): 500
//  
//  Если ввести команду «2», а затем «1000», то результат будет:
//  
//  Led status: on
//  Led brightness: 1000
//  
//  Если ввести команду «1», а затем «0», то результат будет:
//  
//  Led status: off (т.е. «выкл»)
//  Led brightness: 1000


#include <CmdMessenger.h>  // библиотека CmdMessenger

// переменные для ШИМ-интервала:
unsigned long intervalOn        = 0;
unsigned long prevBlinkTime     = 0;
const unsigned long PWMinterval = 1000;

// переменные для мигающего светодиода: 
bool ledState                   = 1;                 // состояние светодиода («вкл» или «выкл»)
int  ledBrightness              = prevBlinkTime /2 ; // 50 % от яркости
const int kBlinkLed             = 13;                // контакт для встроенного светодиода

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

// Это список распознаваемых команд. Чтобы получить команду, к этому 
// событию нужно привязать функцию внешнего вызова.
enum
{
  kCommandList         , // команда, запрашивающая список доступных команд
  kSetLed              , // команда, запрашивающая, чтобы светодиод выставили в определенное состояние  
  kSetLedBrightness    , // команда, запрашивающая, чтобы светодиод горел с определенной яркостью  
  kStatus              , // команда, запрашивающая статус светодиода
};

// функции внешнего вызова, определяющие, при получении каких команд нам нужно начинать действовать:
void attachCommandCallbacks()
{
  // подключаем функции внешнего вызова:
  cmdMessenger.attach(OnUnknownCommand);
  cmdMessenger.attach(kCommandList, OnCommandList);
  cmdMessenger.attach(kSetLed, OnSetLed);
  cmdMessenger.attach(kSetLedBrightness, OnSetLedBrightness);
  cmdMessenger.attach(kStatus, OnStatus);
}

// эта функция вызывается, когда к присланной команде не привязано никакой функции:
void OnUnknownCommand()
{
  Serial.println("This command is unknown!");  //  "Эта команда неизвестна!"
  ShowCommands();
}

// функция внешнего вызова, показывающая список команд:
void OnCommandList()
{
  ShowCommands();
}

// функция внешнего вызова, включающая/выключающая светодиод:
void OnSetLed()
{
  // считываем аргумент для состояния светодиода; здесь ожидается 
  // либо «0», либо «1», интерпретируем их как «false» или «true»: 
  ledState = cmdMessenger.readBoolArg(); 
  ShowLedState();  
}

// функция внешнего вызова, меняющая яркость светодиода:
void OnSetLedBrightness()
{
  // считываем аргумент для яркости светодиода; здесь ожидается 
  // значение в диапазоне от «0» до 255»:
  ledBrightness = cmdMessenger.readInt16Arg();  
  // задаем яркость светодиода:
  SetBrightness();  
  // показываем состояние светодиода
  ShowLedState();  
}

// функция внешнего вызова, показывающая статус светодиода:
void OnStatus()
{
  // отсылаем обратно статус, описывающий состояние светодиода:
  ShowLedState();
}

// показываем доступные команды:
void ShowCommands() 
{
  Serial.println("Available commands");  //  "Доступные команды"
  Serial.println(" 0;                  - This command list");  //  "0; - Показать список команд"
  Serial.println(" 1,<led state>;      - Set led. 0 = off, 1 = on");  //  "1,<состояние>; - Задать статус светодиода. 0 = выкл, 1 = вкл"
  Serial.print  (" 2,<led brightness>; - Set led brighness. 0 - ");  //  "2,<яркость>; - Задать яркость светодиода. 0 - 1000"
  Serial.println(PWMinterval); 
  Serial.println(" 3;                  - Show led state");  //  "3; - Показать состояние светодиода"
}

// показываем состояние и яркость светодиода:
void ShowLedState() 
{
  Serial.print("Led status: ");  //  "Статус светодиода: "
  Serial.println(ledState?"on":"off");
  Serial.print("Led brightness: ");  //  "Яркость светодиода: "
  Serial.println(ledBrightness);
}

// задаем состояние светодиода:
void SetLedState()
{
  if (ledState)  {
    // если светодиод включен, задаем яркость при помощи аналоговой записи:
    analogWrite(kBlinkLed, ledBrightness);
  } else {
    // если светодиод выключен, выключаем ШИМ при помощи цифровой записи:
    digitalWrite(kBlinkLed, LOW);
  }
}

// рассчитываем яркость светодиода:
void SetBrightness() 
{
  // делаем так, чтобы значение в intervalOn было либо «0», либо соответствующим PWMinterval:
  intervalOn  =  max(min(ledBrightness,PWMinterval),0);
}

// яркость светодиода будет зависеть от широтно-импульсной модуляции; 
// до достижения значения intervalOn светодиод будет включен,
// до достижения значения PWMinterval светодиод будет выключен:
bool blinkLed() {
  if (  micros() - prevBlinkTime > PWMinterval ) {
    // включаем светодиод в конце интервала (если состояние светодиода – «вкл»):
    prevBlinkTime = micros();
    digitalWrite(kBlinkLed, ledState?HIGH:LOW);    
  } else if (  micros() - prevBlinkTime > intervalOn ) {
    // выключаем светодиод в середине интервала: 
    digitalWrite(kBlinkLed, LOW);
  } 
}

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

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

  // задаем контакт для мигающего светодиода:
  pinMode(kBlinkLed, OUTPUT);
  
  // показываем список команд:
  ShowCommands();
}

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

См.также

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