- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Программируем Arduino. Основы работы со скетчами - Монк Саймон
Шрифт:
Интервал:
Закладка:
void sampleWindowFull()
{
for (int i = 0; i < 128; i++)
{
int val = (analogRead(analogPin) — 512) * GAIN;
data[i] = val / 4;
im[i] = 0;
}
}
Функция updateData вычисляет амплитуду в каждом частотном интервале. Сила сигнала вычисляется как длина гипотенузы прямоугольного треугольника, двумя другими сторонами которого являются действительная и мнимая части сигнала (практическое применение теоремы Пифагора!):
void updateData()
{
for (int i = 0; i < 64; i++)
{
data[i] = sqrt(data[i] * data[i] + im[i] * im[i]);
}
}
Результаты выводятся в монитор последовательного порта в одну строку через запятую. Первое значение игнорируется, потому что содержит постоянную составляющую сигнала и обычно не представляет интереса.
Массив data можно было бы использовать, например, для управления высотой столбиков диаграммы на жидкокристаллическом дисплее. Подключить источник сигнала (например, аудиовыход MP3-плеера) можно с помощью той же схемы, обеспечивающей колебание сигнала относительно средней точки 2,5 В, что была показана ранее, на рис. 13.4.
Пример измерения частоты
В этом, втором примере плата Arduino Uno используется для вывода оценки частоты сигнала в монитор последовательного порта (sketch_13_07_FFT_Freq). Большая часть кода в этом скетче повторяет код из предыдущего примера. Главное отличие в том, что после обработки массива data определяется индекс элемента с наибольшим значением и используется для оценки частоты. Затем функция loop выводит это значение в монитор последовательного порта.
В заключение
Цифровая обработка сигналов — сложная тема, ей посвящено множество отдельных книг. Из-за ее сложности я коснулся только наиболее полезных приемов, которые можно попробовать применить при использовании платы Arduino.
В следующей главе мы обратимся к проблеме, возникающей при желании одновременно решать несколько задач в Arduino. С этой проблемой часто сталкиваются те, кто имеет опыт программирования в больших системах, где несколько потоков выполнения, действующих одновременно, считаются нормой.
14. Многозадачность с единственным процессом
Программисты, пришедшие в мир Arduino из мира больших систем, часто отмечают отсутствие поддержки многозадачности в Arduino как существенное упущение. В этой главе я попробую исправить его и покажу, как преодолеть ограничения однопоточной модели встроенных систем.
Переход из мира программирования больших систем
Плата Arduino привлекла множество энтузиастов (в том числе и меня), которые работают в индустрии программного обеспечения не один год, имеют опыт работы в составе коллективов из десятков человек, объединяющих усилия для создания больших программных продуктов, и привыкли решать все возникающие проблемы. Для нас возможность без продолжительного проектирования написать несколько строк кода и практически немедленно получить какое-нибудь интересное проявление в физическом мире является отличным противоядием от привычек, прививаемых в мире большого программного обеспечения.
Однако накопленный опыт часто заставляет нас искать в Arduino то, чем мы привыкли пользоваться в повседневной работе. При переходе из мира больших систем в миниатюрный мир Arduino первое, что сразу бросается в глаза, — это простота разработки программ для Arduino. Приступать к созданию большой системы без использования приемов разработки через тестирование, системы управления версиями и процедуры гибкой разработки было бы слишком опрометчиво. В то же время большой проект для Arduino может состоять всего из 200 строк кода, написанных одним человеком. Если этот человек — опытный программист, он просто будет хранить все тонкости в памяти, не нуждаясь в привлечении инструментов, обычных в большой разработке.
Поэтому прекращайте беспокоиться об управлении версиями, шаблонах проектирования, создании модульных тестов и поддержке рефакторинга в среде разработки и просто почувствуйте радость от простоты Arduino.
Почему вам не нужны потоки выполнения
Если вам так много лет, что вы застали времена, когда большое распространение имели домашние компьютеры, программируемые на Бейсике, вы должны помнить, что компьютеры «в каждый момент времени делают что-то одно». Если игре, написанной на Бейсике, требовалось одновременно перемещать несколько спрайтов, вам приходилось прибегать к уловке с общим циклом, в котором каждый спрайт перемещался на небольшое расстояние.
Этот образ мышления отлично подходит для программирования Arduino. Вместо создания множества потоков выполнения, каждый из которых отвечает за перемещение единственного спрайта, достаточно единственного потока, перемещающего спрайты по очереди небольшими шагами, не блокируя ничто другое.
Компьютеры, кроме тех, что имеют многоядерные процессоры, действительно в каждый момент времени могут делать что-то одно. Операционная система переключает внимание процессора между процессами, действующими в компьютере. В Arduino, где нет операционной системы и потребность в решении нескольких задач одновременно возникает довольно редко, многозадачность можно реализовать самостоятельно.
Функции setup и loop
В каждом скетче требуется реализовать две функции, setup и loop, и такой подход выбран не случайно. Фактически функция loop вызывается снова и снова, и именно по этой причине ее работа не должна блокироваться. Код в функции loop должен действовать виртуозно, чтобы она выполнялась моментально и тут же запускалась вновь.
Оценка, затем действие
Большинство проектов для Arduino предназначено для управления чем-то. Поэтому функция loop часто:
• проверяет нажатие кнопки или превышение данных с некоторого датчика порогового значения;
• выполняет соответствующее действие.
Простым примером может служить реализация мигания светодиода в результате нажатия кнопки.
Следующий пример иллюстрирует это. Однако, как будет показано далее, иногда необходимость ждать, пока выполняется код, управляющий миганием светодиода, бывает совершенно неприемлемой:
// sketch_14_01_flashing_1
const int ledPin = 13;
const int switchPin = 5;
const int period = 1000;
boolean flashing = false;
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(switchPin, INPUT_PULLUP);
}
void loop()
{
if (digitalRead(switchPin) == LOW)
{
flashing = ! flashing;
}
if (flashing)
{
digitalWrite(ledPin, HIGH);
delay(period);
digitalWrite(ledPin, LOW);
delay(period);
}
}
Проблема данной реализации в том, что она проверяет нажатие кнопки только после того, как завершится цикл включения/выключения светодиода. Если кнопка будет нажата во время этого цикла, факт нажатия зафиксирован не будет. Это может быть не важно для нормальной работы скетча, но если важно фиксировать каждое нажатие кнопки, следует полностью исключить любые задержки в функции loop. Фактически после перехода в режим мигания Arduino будет тратить основное время на задержки и только малую часть времени — на проверку состояния кнопки.
Пример в следующем разделе решает эту проблему.
Пауза без приостановки
Предыдущий скетч можно переписать без использования функции delay:
// sketch_14_02_flashing_2
const int ledPin = 13;
const int switchPin = 5;
const int period = 1000;
boolean flashing = false;
long lastChangeTime = 0;
int ledState = LOW;
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(switchPin, INPUT_PULLUP);